Skip to content

Commit fc03b7a

Browse files
jbower-fbfacebook-github-bot
authored andcommitted
Add JIT support for STORE_GLOBAL
Summary: whatcouldgowrong Reviewed By: alexmalyshev Differential Revision: D82694078 fbshipit-source-id: fbe27a1a72d13f369574d849e4f88947095af741
1 parent 6dff293 commit fc03b7a

6 files changed

Lines changed: 82 additions & 3 deletions

File tree

cinderx/Jit/hir/builder.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ bool isSupportedOpcode(int opcode) {
228228
case STORE_FAST_LOAD_FAST:
229229
case STORE_FAST_STORE_FAST:
230230
case STORE_FIELD:
231+
case STORE_GLOBAL:
231232
case STORE_LOCAL:
232233
case STORE_SLICE:
233234
case STORE_SUBSCR:
@@ -1558,6 +1559,10 @@ void HIRBuilder::translate(
15581559
emitLoadBuildClass(tc);
15591560
break;
15601561
}
1562+
case STORE_GLOBAL: {
1563+
emitStoreGlobal(tc, bc_instr);
1564+
break;
1565+
}
15611566
case CHECK_EG_MATCH:
15621567
case CHECK_EXC_MATCH:
15631568
case CLEANUP_THROW:
@@ -5005,6 +5010,25 @@ void HIRBuilder::emitLoadBuildClass(TranslationContext& tc) {
50055010
tc.frame.stack.push(result);
50065011
}
50075012

5013+
void HIRBuilder::emitStoreGlobal(
5014+
TranslationContext& tc,
5015+
const BytecodeInstruction& bc_instr) {
5016+
Register* globals = temps_.AllocateNonStack();
5017+
Register* key = temps_.AllocateNonStack();
5018+
5019+
tc.emit<LoadConst>(globals, Type::fromObject(tc.frame.globals));
5020+
// Starting at the preloader the JIT seems to assume globals will be a
5021+
// dictionary, however I'm not sure there's any guarantee of this.
5022+
Register* globals_dict = temps_.AllocateNonStack();
5023+
tc.emit<GuardType>(globals_dict, TDictExact, globals, tc.frame);
5024+
tc.emit<LoadConst>(
5025+
key,
5026+
Type::fromObject(PyTuple_GET_ITEM(code_->co_names, bc_instr.oparg())));
5027+
Register* value = tc.frame.stack.pop();
5028+
Register* result = temps_.AllocateNonStack();
5029+
tc.emit<SetDictItem>(result, globals_dict, key, value, tc.frame);
5030+
}
5031+
50085032
void HIRBuilder::insertEvalBreakerCheck(
50095033
CFG& cfg,
50105034
BasicBlock* check_block,

cinderx/Jit/hir/builder.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,10 @@ class HIRBuilder {
479479

480480
void emitLoadBuildClass(TranslationContext& tc);
481481

482+
void emitStoreGlobal(
483+
TranslationContext& tc,
484+
const BytecodeInstruction& bc_instr);
485+
482486
BorrowedRef<> constArg(const jit::BytecodeInstruction& bc_instr);
483487

484488
ExecutionBlock popBlock(CFG& cfg, TranslationContext& tc);

cinderx/Jit/pyjit.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -931,14 +931,20 @@ hir::Preloader* preload(BorrowedRef<> unit) {
931931
return nullptr;
932932
}
933933
BorrowedRef<PyFunctionObject>& outer_func = it->second;
934-
// Assuming the builtins will always be a dictionary goes way back in the
935-
// JIT's history. I'm not sure what guarantees this though. Tread carefully
936-
// but try not to blow things up if this happens in production code.
934+
// Assuming the builtins + globals will always be a dictionary goes way back
935+
// in the JIT's history. I'm not sure what guarantees this though. Tread
936+
// carefully but try not to blow things up if this happens in production
937+
// code.
937938
JIT_DCHECK(
938939
PyDict_CheckExact(outer_func->func_builtins),
939940
"Unexpected type for builtins ({}) on function {}",
940941
Py_TYPE(outer_func->func_builtins)->tp_name,
941942
funcFullname(outer_func));
943+
JIT_DCHECK(
944+
PyDict_CheckExact(outer_func->func_globals),
945+
"Unexpected type for globals ({}) on function {}",
946+
Py_TYPE(outer_func->func_globals)->tp_name,
947+
funcFullname(outer_func));
942948
preloader = hir::Preloader::makePreloader(
943949
code,
944950
outer_func->func_builtins,

cinderx/PythonLib/test_cinderx/test_python310_bytecodes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ class TestClass:
2424
self.assertEqual(result.__class__.__name__, "TestClass")
2525
self.assertBytecodeContains(x, "LOAD_BUILD_CLASS")
2626

27+
def test_STORE_GLOBAL(self):
28+
global test_STORE_GLOBAL_v
29+
30+
test_STORE_GLOBAL_v = 1
31+
32+
@cinder_support.fail_if_deopt
33+
@cinder_support.failUnlessJITCompiled
34+
def x():
35+
global test_STORE_GLOBAL_v
36+
test_STORE_GLOBAL_v = 42
37+
38+
x()
39+
self.assertEqual(test_STORE_GLOBAL_v, 42)
40+
self.assertBytecodeContains(x, "STORE_GLOBAL")
41+
2742

2843
if __name__ == "__main__":
2944
unittest.main()

cinderx/PythonLib/test_cinderx/test_python312_bytecodes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ class TestClass:
2424
self.assertEqual(result.__class__.__name__, "TestClass")
2525
self.assertBytecodeContains(x, "LOAD_BUILD_CLASS")
2626

27+
def test_STORE_GLOBAL(self):
28+
global test_STORE_GLOBAL_v
29+
30+
test_STORE_GLOBAL_v = 1
31+
32+
@cinder_support.fail_if_deopt
33+
@cinder_support.failUnlessJITCompiled
34+
def x():
35+
global test_STORE_GLOBAL_v
36+
test_STORE_GLOBAL_v = 42
37+
38+
x()
39+
self.assertEqual(test_STORE_GLOBAL_v, 42)
40+
self.assertBytecodeContains(x, "STORE_GLOBAL")
41+
2742

2843
if __name__ == "__main__":
2944
unittest.main()

cinderx/PythonLib/test_cinderx/test_python314_bytecodes.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,21 @@ class TestClass:
488488
self.assertEqual(result.__class__.__name__, "TestClass")
489489
self.assertBytecodeContains(x, "LOAD_BUILD_CLASS")
490490

491+
def test_STORE_GLOBAL(self):
492+
global test_STORE_GLOBAL_v
493+
494+
test_STORE_GLOBAL_v = 1
495+
496+
@cinder_support.fail_if_deopt
497+
@cinder_support.failUnlessJITCompiled
498+
def x():
499+
global test_STORE_GLOBAL_v
500+
test_STORE_GLOBAL_v = 42
501+
502+
x()
503+
self.assertEqual(test_STORE_GLOBAL_v, 42)
504+
self.assertBytecodeContains(x, "STORE_GLOBAL")
505+
491506

492507
if __name__ == "__main__":
493508
unittest.main()

0 commit comments

Comments
 (0)