Skip to content

Commit 94b47ff

Browse files
iliadshawesomekling
authored andcommitted
LibJS: Add GetByValue fast path for simple array access
1 parent f91c3e9 commit 94b47ff

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

Userland/Libraries/LibJS/JIT/Compiler.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,9 +1208,121 @@ void Compiler::compile_get_by_value(Bytecode::Op::GetByValue const& op)
12081208
{
12091209
load_vm_register(ARG1, op.base());
12101210
load_accumulator(ARG2);
1211+
1212+
Assembler::Label end {};
1213+
Assembler::Label slow_case {};
1214+
1215+
branch_if_object(ARG1, [&] {
1216+
branch_if_int32(ARG2, [&] {
1217+
// if (ARG2 < 0) goto slow_case;
1218+
m_assembler.mov(
1219+
Assembler::Operand::Register(GPR0),
1220+
Assembler::Operand::Register(ARG2));
1221+
m_assembler.sign_extend_32_to_64_bits(GPR0);
1222+
m_assembler.jump_if(
1223+
Assembler::Operand::Register(GPR0),
1224+
Assembler::Condition::SignedLessThan,
1225+
Assembler::Operand::Imm(0),
1226+
slow_case);
1227+
1228+
// GPR0 = extract_pointer(ARG1)
1229+
extract_object_pointer(GPR0, ARG1);
1230+
1231+
// if (object->may_interfere_with_indexed_property_access()) goto slow_case;
1232+
m_assembler.mov8(
1233+
Assembler::Operand::Register(GPR1),
1234+
Assembler::Operand::Mem64BaseAndOffset(GPR0, Object::may_interfere_with_indexed_property_access_offset()));
1235+
m_assembler.jump_if(
1236+
Assembler::Operand::Register(GPR1),
1237+
Assembler::Condition::NotEqualTo,
1238+
Assembler::Operand::Imm(0),
1239+
slow_case);
1240+
1241+
// GPR0 = object->indexed_properties().storage()
1242+
m_assembler.mov(
1243+
Assembler::Operand::Register(GPR0),
1244+
Assembler::Operand::Mem64BaseAndOffset(GPR0, Object::indexed_properties_offset() + IndexedProperties::storage_offset()));
1245+
1246+
// if (GPR0 == nullptr) goto slow_case;
1247+
m_assembler.jump_if(
1248+
Assembler::Operand::Register(GPR0),
1249+
Assembler::Condition::EqualTo,
1250+
Assembler::Operand::Imm(0),
1251+
slow_case);
1252+
1253+
// if (!GPR0->is_simple_storage()) goto slow_case;
1254+
m_assembler.mov8(
1255+
Assembler::Operand::Register(GPR1),
1256+
Assembler::Operand::Mem64BaseAndOffset(GPR0, IndexedPropertyStorage::is_simple_storage_offset()));
1257+
m_assembler.jump_if(
1258+
Assembler::Operand::Register(GPR1),
1259+
Assembler::Condition::EqualTo,
1260+
Assembler::Operand::Imm(0),
1261+
slow_case);
1262+
1263+
// GPR2 = extract_int32(ARG2)
1264+
m_assembler.mov32(
1265+
Assembler::Operand::Register(GPR2),
1266+
Assembler::Operand::Register(ARG2));
1267+
1268+
// if (GPR2 >= GPR0->array_like_size()) goto slow_case;
1269+
m_assembler.mov(
1270+
Assembler::Operand::Register(GPR1),
1271+
Assembler::Operand::Mem64BaseAndOffset(GPR0, SimpleIndexedPropertyStorage::array_size_offset()));
1272+
m_assembler.jump_if(
1273+
Assembler::Operand::Register(GPR2),
1274+
Assembler::Condition::SignedGreaterThanOrEqualTo,
1275+
Assembler::Operand::Register(GPR1),
1276+
slow_case);
1277+
1278+
// GPR0 = GPR0->elements().outline_buffer()
1279+
m_assembler.mov(
1280+
Assembler::Operand::Register(GPR0),
1281+
Assembler::Operand::Mem64BaseAndOffset(GPR0, SimpleIndexedPropertyStorage::elements_offset() + Vector<Value>::outline_buffer_offset()));
1282+
1283+
// GPR2 *= sizeof(Value)
1284+
m_assembler.mul32(
1285+
Assembler::Operand::Register(GPR2),
1286+
Assembler::Operand::Imm(sizeof(Value)),
1287+
slow_case);
1288+
1289+
// GPR0 = GPR0[GPR2]
1290+
m_assembler.add(
1291+
Assembler::Operand::Register(GPR0),
1292+
Assembler::Operand::Register(GPR2));
1293+
m_assembler.mov(
1294+
Assembler::Operand::Register(GPR0),
1295+
Assembler::Operand::Mem64BaseAndOffset(GPR0, 0));
1296+
1297+
// if (GPR0.is_empty()) goto slow_case;
1298+
m_assembler.mov(Assembler::Operand::Register(GPR1), Assembler::Operand::Register(GPR0));
1299+
m_assembler.shift_right(Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(TAG_SHIFT));
1300+
m_assembler.jump_if(
1301+
Assembler::Operand::Register(GPR1),
1302+
Assembler::Condition::EqualTo,
1303+
Assembler::Operand::Imm(EMPTY_TAG),
1304+
slow_case);
1305+
1306+
// if (GPR0.is_accessor()) goto slow_case;
1307+
m_assembler.mov(Assembler::Operand::Register(GPR1), Assembler::Operand::Register(GPR0));
1308+
m_assembler.shift_right(Assembler::Operand::Register(GPR1), Assembler::Operand::Imm(TAG_SHIFT));
1309+
m_assembler.jump_if(
1310+
Assembler::Operand::Register(GPR1),
1311+
Assembler::Condition::EqualTo,
1312+
Assembler::Operand::Imm(ACCESSOR_TAG),
1313+
slow_case);
1314+
1315+
// accumulator = GPR0;
1316+
store_accumulator(GPR0);
1317+
m_assembler.jump(end);
1318+
});
1319+
});
1320+
1321+
slow_case.link(m_assembler);
12111322
native_call((void*)cxx_get_by_value);
12121323
store_accumulator(RET);
12131324
check_exception();
1325+
end.link(m_assembler);
12141326
}
12151327

12161328
static Value cxx_get_global(VM& vm, DeprecatedFlyString const& identifier, Bytecode::GlobalVariableCache& cache)

0 commit comments

Comments
 (0)