| Index: runtime/vm/intermediate_language_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_ia32.cc (revision 8921)
|
| +++ runtime/vm/intermediate_language_ia32.cc (working copy)
|
| @@ -306,6 +306,7 @@
|
| ASSERT(comp->HasICData());
|
| const ICData& ic_data = *comp->ic_data();
|
| ASSERT(ic_data.NumberOfChecks() > 0);
|
| + ASSERT(ic_data.num_args_tested() == 1);
|
| Label* deopt = compiler->AddDeoptStub(comp->cid(),
|
| comp->token_index(),
|
| comp->try_index(),
|
| @@ -637,10 +638,47 @@
|
| }
|
|
|
|
|
| +static void EmitLoadIndexedPolymorphic(FlowGraphCompiler* compiler,
|
| + LoadIndexedComp* comp) {
|
| + Label* deopt = compiler->AddDeoptStub(comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index(),
|
| + kDeoptLoadIndexedPolymorphic);
|
| + if (comp->ic_data()->NumberOfChecks() == 0) {
|
| + __ jmp(deopt);
|
| + return;
|
| + }
|
| + ASSERT(comp->HasICData());
|
| + const ICData& ic_data = *comp->ic_data();
|
| + ASSERT(ic_data.num_args_tested() == 1);
|
| + // No indexed access on Smi.
|
| + ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
|
| + // Load receiver into EAX.
|
| + const intptr_t kNumArguments = 2;
|
| + __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
|
| + __ testl(EAX, Immediate(kSmiTagMask));
|
| + __ j(ZERO, deopt);
|
| + Label done;
|
| + __ LoadClassId(EDI, EAX);
|
| + compiler->EmitTestAndCall(ic_data,
|
| + EDI, // Class id register.
|
| + kNumArguments,
|
| + Array::Handle(), // No named arguments.
|
| + deopt, &done, // Labels.
|
| + comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index());
|
| + __ Bind(&done);
|
| +}
|
|
|
| +
|
| void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| if (receiver_type() == kIllegalObjectKind) {
|
| - compiler->EmitLoadIndexedGeneric(this);
|
| + if (HasICData()) {
|
| + EmitLoadIndexedPolymorphic(compiler, this);
|
| + } else {
|
| + compiler->EmitLoadIndexedGeneric(this);
|
| + }
|
| ASSERT(locs()->out().reg() == EAX);
|
| return;
|
| }
|
| @@ -719,7 +757,6 @@
|
| }
|
|
|
|
|
| -
|
| static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
|
| StoreIndexedComp* comp) {
|
| const String& function_name =
|
| @@ -737,14 +774,52 @@
|
| comp->try_index(),
|
| function_name,
|
| kNumArguments,
|
| - Array::ZoneHandle(), // No optional arguments.
|
| + Array::ZoneHandle(), // No named args.
|
| kNumArgsChecked);
|
| }
|
|
|
|
|
| +static void EmitStoreIndexedPolymorphic(FlowGraphCompiler* compiler,
|
| + StoreIndexedComp* comp) {
|
| + Label* deopt = compiler->AddDeoptStub(comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index(),
|
| + kDeoptStoreIndexedPolymorphic);
|
| + if (comp->ic_data()->NumberOfChecks() == 0) {
|
| + __ jmp(deopt);
|
| + return;
|
| + }
|
| + ASSERT(comp->HasICData());
|
| + const ICData& ic_data = *comp->ic_data();
|
| + ASSERT(ic_data.num_args_tested() == 1);
|
| + // No indexed access on Smi.
|
| + ASSERT(ic_data.GetReceiverClassIdAt(0) != kSmi);
|
| + // Load receiver into EAX.
|
| + const intptr_t kNumArguments = 3;
|
| + __ movl(EAX, Address(ESP, (kNumArguments - 1) * kWordSize));
|
| + __ testl(EAX, Immediate(kSmiTagMask));
|
| + __ j(ZERO, deopt);
|
| + Label done;
|
| + __ LoadClassId(EDI, EAX);
|
| + compiler->EmitTestAndCall(ic_data,
|
| + EDI, // Class id register.
|
| + kNumArguments,
|
| + Array::Handle(), // No named arguments.
|
| + deopt, &done, // Labels.
|
| + comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index());
|
| + __ Bind(&done);
|
| +}
|
| +
|
| +
|
| void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| if (receiver_type() == kIllegalObjectKind) {
|
| - EmitStoreIndexedGeneric(compiler, this);
|
| + if (HasICData()) {
|
| + EmitStoreIndexedPolymorphic(compiler, this);
|
| + } else {
|
| + EmitStoreIndexedGeneric(compiler, this);
|
| + }
|
| return;
|
| }
|
|
|
| @@ -1760,12 +1835,16 @@
|
|
|
| void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT(instance_call()->VerifyComputation());
|
| - ASSERT(HasICData());
|
| - ASSERT(ic_data()->num_args_tested() == 1);
|
| Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
|
| instance_call()->token_index(),
|
| instance_call()->try_index(),
|
| kDeoptPolymorphicInstanceCallTestFail);
|
| + if (!HasICData() || (ic_data()->NumberOfChecks() == 0)) {
|
| + __ jmp(deopt);
|
| + return;
|
| + }
|
| + ASSERT(HasICData());
|
| + ASSERT(ic_data()->num_args_tested() == 1);
|
| Label handle_smi;
|
| Label* is_smi_label =
|
| ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
|
| @@ -1777,21 +1856,14 @@
|
| __ j(ZERO, is_smi_label);
|
| Label done;
|
| __ LoadClassId(EDI, EAX);
|
| - for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); i++) {
|
| - Label next_test;
|
| - __ cmpl(EDI, Immediate(ic_data()->GetReceiverClassIdAt(i)));
|
| - __ j(NOT_EQUAL, &next_test);
|
| - const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(i));
|
| - compiler->GenerateStaticCall(instance_call()->cid(),
|
| - instance_call()->token_index(),
|
| - instance_call()->try_index(),
|
| - target,
|
| - instance_call()->ArgumentCount(),
|
| - instance_call()->argument_names());
|
| - __ jmp(&done);
|
| - __ Bind(&next_test);
|
| - }
|
| - __ jmp(deopt);
|
| + compiler->EmitTestAndCall(*ic_data(),
|
| + EDI, // Class id register.
|
| + instance_call()->ArgumentCount(),
|
| + instance_call()->argument_names(),
|
| + deopt, &done, // Labels.
|
| + instance_call()->cid(),
|
| + instance_call()->token_index(),
|
| + instance_call()->try_index());
|
| if (is_smi_label == &handle_smi) {
|
| __ Bind(&handle_smi);
|
| ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
|
|
|