Chromium Code Reviews| Index: runtime/vm/flow_graph_compiler_arm.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_compiler_arm.cc (revision 45488) |
| +++ runtime/vm/flow_graph_compiler_arm.cc (working copy) |
| @@ -28,6 +28,7 @@ |
| DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic."); |
| DECLARE_FLAG(bool, enable_type_checks); |
| DECLARE_FLAG(bool, enable_simd_inline); |
| +DECLARE_FLAG(bool, use_megamorphic_stub); |
| FlowGraphCompiler::~FlowGraphCompiler() { |
| @@ -1289,45 +1290,50 @@ |
| const MegamorphicCache& cache = |
| MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor)); |
| __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize); |
| - __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| - |
| - // R0: class ID of the receiver (smi). |
| __ LoadObject(R1, cache); |
| - __ ldr(R2, FieldAddress(R1, MegamorphicCache::buckets_offset())); |
| - __ ldr(R1, FieldAddress(R1, MegamorphicCache::mask_offset())); |
| - // R2: cache buckets array. |
| - // R1: mask. |
| - __ mov(R3, Operand(R0)); |
| - Label loop, update, call_target_function; |
| - __ b(&loop); |
| + if (FLAG_use_megamorphic_stub) { |
|
Florian Schneider
2015/05/04 22:06:20
To avoid performance regression in optimized code,
srdjan
2015/05/05 07:15:29
There are no measureable (< 0.5% diffs) in optimiz
srdjan
2015/05/05 12:13:28
Measured dart2js optimized: with out-of-line megam
Florian Schneider
2015/05/05 16:34:43
If the difference is not noticable in optimized co
|
| + StubCode* stub_code = isolate()->stub_code(); |
| + __ BranchLink(&stub_code->MegamorphicLookupLabel()); |
| + } else { |
| + // R0: class ID of the receiver (smi). |
| + __ LoadTaggedClassIdMayBeSmi(R0, R0); |
| + __ ldr(R2, FieldAddress(R1, MegamorphicCache::buckets_offset())); |
| + __ ldr(R1, FieldAddress(R1, MegamorphicCache::mask_offset())); |
| + // R2: cache buckets array. |
| + // R1: mask. |
| + __ mov(R3, Operand(R0)); |
| - __ Bind(&update); |
| - __ add(R3, R3, Operand(Smi::RawValue(1))); |
| - __ Bind(&loop); |
| - __ and_(R3, R3, Operand(R1)); |
| - const intptr_t base = Array::data_offset(); |
| - // R3 is smi tagged, but table entries are two words, so LSL 2. |
| - __ add(IP, R2, Operand(R3, LSL, 2)); |
| - __ ldr(R4, FieldAddress(IP, base)); |
| + Label loop, update, call_target_function; |
| + __ b(&loop); |
| - ASSERT(kIllegalCid == 0); |
| - __ tst(R4, Operand(R4)); |
| - __ b(&call_target_function, EQ); |
| - __ cmp(R4, Operand(R0)); |
| - __ b(&update, NE); |
| + __ Bind(&update); |
| + __ add(R3, R3, Operand(Smi::RawValue(1))); |
| + __ Bind(&loop); |
| + __ and_(R3, R3, Operand(R1)); |
| + const intptr_t base = Array::data_offset(); |
| + // R3 is smi tagged, but table entries are two words, so LSL 2. |
| + __ add(IP, R2, Operand(R3, LSL, 2)); |
| + __ ldr(R4, FieldAddress(IP, base)); |
| - __ Bind(&call_target_function); |
| - // Call the target found in the cache. For a class id match, this is a |
| - // proper target for the given name and arguments descriptor. If the |
| - // illegal class id was found, the target is a cache miss handler that can |
| - // be invoked as a normal Dart function. |
| - __ add(IP, R2, Operand(R3, LSL, 2)); |
| - __ ldr(R0, FieldAddress(IP, base + kWordSize)); |
| - __ ldr(R1, FieldAddress(R0, Function::instructions_offset())); |
| + ASSERT(kIllegalCid == 0); |
| + __ tst(R4, Operand(R4)); |
| + __ b(&call_target_function, EQ); |
| + __ cmp(R4, Operand(R0)); |
| + __ b(&update, NE); |
| + |
| + __ Bind(&call_target_function); |
| + // Call the target found in the cache. For a class id match, this is a |
| + // proper target for the given name and arguments descriptor. If the |
| + // illegal class id was found, the target is a cache miss handler that can |
| + // be invoked as a normal Dart function. |
| + __ add(IP, R2, Operand(R3, LSL, 2)); |
| + __ ldr(R0, FieldAddress(IP, base + kWordSize)); |
| + __ ldr(R1, FieldAddress(R0, Function::instructions_offset())); |
| + __ AddImmediate(R1, Instructions::HeaderSize() - kHeapObjectTag); |
| + } |
|
Florian Schneider
2015/05/04 22:06:20
Maybe you can factor this lookup code into a commo
srdjan
2015/05/05 07:15:29
Will do.
|
| __ LoadObject(R5, ic_data); |
| __ LoadObject(R4, arguments_descriptor); |
| - __ AddImmediate(R1, Instructions::HeaderSize() - kHeapObjectTag); |
| __ blx(R1); |
| AddCurrentDescriptor(RawPcDescriptors::kOther, |
| Isolate::kNoDeoptId, token_pos); |