Skip to content

Commit df60f02

Browse files
committed
Rewrite LOAD_GLOBAL _Unbound to LOAD_IMMEDIATE in builtins module
This should save some caches and be faster. Ideally we would do this in all Skybison-controlled modules but I don't think we have a good signal for that yet. Partially addresses #395; we still cannot use it as marker in dictionaries because it's still in the globals dict.
1 parent 4cbb209 commit df60f02

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

‎runtime/bytecode.cpp‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ struct RewrittenOp {
9090
};
9191

9292
static RewrittenOp rewriteOperation(const Function& function, BytecodeOp op,
93-
bool use_load_fast_reverse_unchecked) {
93+
bool use_load_fast_reverse_unchecked,
94+
bool is_builtin_module) {
9495
auto cached_binop = [](Interpreter::BinaryOp bin_op) {
9596
return RewrittenOp{BINARY_OP_ANAMORPHIC, static_cast<int32_t>(bin_op),
9697
true};
@@ -178,6 +179,20 @@ static RewrittenOp rewriteOperation(const Function& function, BytecodeOp op,
178179
return cached_inplace(Interpreter::BinaryOp::XOR);
179180
case LOAD_ATTR:
180181
return RewrittenOp{LOAD_ATTR_ANAMORPHIC, op.arg, true};
182+
case LOAD_GLOBAL: {
183+
if (is_builtin_module) {
184+
RawTuple names = Tuple::cast(Code::cast(function.code()).names());
185+
RawStr name = Str::cast(names.at(op.arg));
186+
if (name.equalsCStr("_Unbound")) {
187+
DCHECK(Unbound::object() ==
188+
objectFromOparg(opargFromObject(Unbound::object())),
189+
"Expected to be able to fit _Unbound in a byte");
190+
return RewrittenOp{LOAD_IMMEDIATE, opargFromObject(Unbound::object()),
191+
false};
192+
}
193+
}
194+
break;
195+
}
181196
case LOAD_FAST: {
182197
CHECK(op.arg < Code::cast(function.code()).nlocals(),
183198
"unexpected local number");
@@ -305,7 +320,7 @@ void rewriteBytecode(Thread* thread, const Function& function) {
305320
use_load_fast_reverse_unchecked = false;
306321
continue;
307322
}
308-
RewrittenOp rewritten = rewriteOperation(function, op, false);
323+
RewrittenOp rewritten = rewriteOperation(function, op, false, false);
309324
if (rewritten.needs_inline_cache) {
310325
num_caches++;
311326
}
@@ -322,11 +337,15 @@ void rewriteBytecode(Thread* thread, const Function& function) {
322337
return;
323338
}
324339
word cache = num_global_caches;
340+
RawObject module = function.moduleObject();
341+
bool is_builtin_module =
342+
module.isModule() &&
343+
Module::cast(module).id() == thread->runtime()->builtinsModuleId();
325344
for (word i = 0; i < num_opcodes;) {
326345
BytecodeOp op = nextBytecodeOp(bytecode, &i);
327346
word previous_index = i - 1;
328-
RewrittenOp rewritten =
329-
rewriteOperation(function, op, use_load_fast_reverse_unchecked);
347+
RewrittenOp rewritten = rewriteOperation(
348+
function, op, use_load_fast_reverse_unchecked, is_builtin_module);
330349
if (rewritten.bc == UNUSED_BYTECODE_0) continue;
331350
if (rewritten.needs_inline_cache) {
332351
rewrittenBytecodeOpAtPut(bytecode, previous_index, rewritten.bc);

0 commit comments

Comments
 (0)