Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| =================================================================== |
| --- runtime/vm/intermediate_language_ia32.cc (revision 32653) |
| +++ runtime/vm/intermediate_language_ia32.cc (working copy) |
| @@ -2163,6 +2163,8 @@ |
| FlowGraphCompiler* compiler) { |
| Register instantiator_reg = locs()->in(0).reg(); |
| Register result_reg = locs()->out().reg(); |
| + ASSERT(instantiator_reg == EAX); |
| + ASSERT(instantiator_reg == result_reg); |
| // 'instantiator_reg' is the instantiator TypeArguments object (or null). |
| ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| @@ -2179,6 +2181,30 @@ |
| __ cmpl(instantiator_reg, raw_null); |
| __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| } |
| + // Lookup cache before calling runtime. |
| + // TODO(fschneider): Consider moving this into a shared stub to reduce |
| + // generated code size. |
|
regis
2014/02/13 19:07:50
OK, that was my previous question.
Actually, befor
Florian Schneider
2014/02/14 11:36:34
Sounds good.
|
| + __ LoadObject(EDI, type_arguments()); |
| + __ movl(EDI, FieldAddress(EDI, TypeArguments::instantiations_offset())); |
| + __ movl(EBX, FieldAddress(EDI, Array::length_offset())); |
| + __ leal(EDI, FieldAddress(EDI, Array::data_offset())); |
| + __ leal(EBX, Address(EDI, EBX, TIMES_2, 0)); // EBX is smi. |
| + Label loop, found, slow_case; |
| + __ Bind(&loop); |
| + __ cmpl(EDI, EBX); |
| + __ j(ABOVE_EQUAL, &slow_case); |
| + __ movl(EDX, Address(EDI, 0 * kWordSize)); // Cached instantiator. |
| + __ cmpl(EDX, EAX); |
| + __ j(EQUAL, &found, Assembler::kNearJump); |
| + __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| + __ j(EQUAL, &slow_case); |
| + __ addl(EDI, Immediate(2 * kWordSize)); |
| + __ jmp(&loop, Assembler::kNearJump); |
| + __ Bind(&found); |
| + __ movl(EAX, Address(EDI, 1 * kWordSize)); // Cached instantiated args. |
| + __ jmp(&type_arguments_instantiated); |
| + |
| + __ Bind(&slow_case); |
| // Instantiate non-null type arguments. |
| // A runtime call to instantiate the type arguments is required. |
| __ PushObject(Object::ZoneHandle()); // Make room for the result. |
| @@ -2192,93 +2218,9 @@ |
| __ Drop(2); // Drop instantiator and uninstantiated type arguments. |
| __ popl(result_reg); // Pop instantiated type arguments. |
| __ Bind(&type_arguments_instantiated); |
| - ASSERT(instantiator_reg == result_reg); |
| } |
| -LocationSummary* |
| -ExtractConstructorTypeArgumentsInstr::MakeLocationSummary(bool opt) const { |
| - const intptr_t kNumInputs = 1; |
| - const intptr_t kNumTemps = 0; |
| - LocationSummary* locs = |
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| - locs->set_in(0, Location::RequiresRegister()); |
| - locs->set_out(Location::SameAsFirstInput()); |
| - return locs; |
| -} |
| - |
| - |
| -void ExtractConstructorTypeArgumentsInstr::EmitNativeCode( |
| - FlowGraphCompiler* compiler) { |
| - Register instantiator_reg = locs()->in(0).reg(); |
| - Register result_reg = locs()->out().reg(); |
| - ASSERT(instantiator_reg == result_reg); |
| - |
| - // instantiator_reg is the instantiator type argument vector, |
| - // i.e. a TypeArguments object (or null). |
| - ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| - !type_arguments().CanShareInstantiatorTypeArguments( |
| - instantiator_class())); |
| - // If the instantiator is null and if the type argument vector |
| - // instantiated from null becomes a vector of dynamic, then use null as |
| - // the type arguments. |
| - ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); |
| - Label type_arguments_instantiated; |
| - const Immediate& raw_null = |
| - Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| - __ cmpl(instantiator_reg, raw_null); |
| - __ j(EQUAL, &type_arguments_instantiated, Assembler::kNearJump); |
| - // Instantiate non-null type arguments. |
| - // In the non-factory case, we rely on the allocation stub to |
| - // instantiate the type arguments. |
| - __ LoadObject(result_reg, type_arguments()); |
| - // result_reg: uninstantiated type arguments. |
| - |
| - __ Bind(&type_arguments_instantiated); |
| - // result_reg: uninstantiated or instantiated type arguments. |
| -} |
| - |
| - |
| -LocationSummary* |
| -ExtractConstructorInstantiatorInstr::MakeLocationSummary(bool opt) const { |
| - const intptr_t kNumInputs = 1; |
| - const intptr_t kNumTemps = 0; |
| - LocationSummary* locs = |
| - new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| - locs->set_in(0, Location::RequiresRegister()); |
| - locs->set_out(Location::SameAsFirstInput()); |
| - return locs; |
| -} |
| - |
| - |
| -void ExtractConstructorInstantiatorInstr::EmitNativeCode( |
| - FlowGraphCompiler* compiler) { |
| - Register instantiator_reg = locs()->in(0).reg(); |
| - ASSERT(locs()->out().reg() == instantiator_reg); |
| - |
| - // instantiator_reg is the instantiator TypeArguments object (or null). |
| - ASSERT(!type_arguments().IsUninstantiatedIdentity() && |
| - !type_arguments().CanShareInstantiatorTypeArguments( |
| - instantiator_class())); |
| - |
| - // If the instantiator is null and if the type argument vector |
| - // instantiated from null becomes a vector of dynamic, then use null as |
| - // the type arguments and do not pass the instantiator. |
| - ASSERT(type_arguments().IsRawInstantiatedRaw(type_arguments().Length())); |
| - const Immediate& raw_null = |
| - Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| - Label instantiator_not_null; |
| - __ cmpl(instantiator_reg, raw_null); |
| - __ j(NOT_EQUAL, &instantiator_not_null, Assembler::kNearJump); |
| - // Null was used in VisitExtractConstructorTypeArguments as the |
| - // instantiated type arguments, no proper instantiator needed. |
| - __ movl(instantiator_reg, |
| - Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| - __ Bind(&instantiator_not_null); |
| - // instantiator_reg: instantiator or kNoInstantiator. |
| -} |
| - |
| - |
| LocationSummary* AllocateContextInstr::MakeLocationSummary(bool opt) const { |
| const intptr_t kNumInputs = 0; |
| const intptr_t kNumTemps = 1; |