| Index: runtime/vm/intermediate_language_ia32.cc
|
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
|
| index 91a6d5438f2af488e0e23113623991546c0a3c14..2678ce759f467f1a29d8598571df4d2dd506dcf9 100644
|
| --- a/runtime/vm/intermediate_language_ia32.cc
|
| +++ b/runtime/vm/intermediate_language_ia32.cc
|
| @@ -424,26 +424,38 @@ void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|
|
| LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 3;
|
| - return LocationSummary::Make(kNumInputs, Location::NoLocation());
|
| + if (receiver_type() == kGrowableObjectArray || receiver_type() == kArray) {
|
| + const intptr_t kNumTemps = 1;
|
| + LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
|
| + locs->set_in(0, Location::RequiresRegister());
|
| + locs->set_in(1, Location::RequiresRegister());
|
| + locs->set_in(2, Location::RequiresRegister());
|
| + locs->set_temp(0, Location::RequiresRegister());
|
| + locs->set_out(Location::NoLocation());
|
| + return locs;
|
| + } else {
|
| + ASSERT(receiver_type() == kIllegalObjectKind);
|
| + return MakeCallSummary();
|
| + }
|
| }
|
|
|
|
|
| -void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - Register receiver = locs()->in(0).reg();
|
| - Register index = locs()->in(1).reg();
|
| - Register value = locs()->in(2).reg();
|
|
|
| +static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
|
| + StoreIndexedComp* comp) {
|
| const String& function_name =
|
| String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
|
|
|
| - __ pushl(receiver);
|
| - __ pushl(index);
|
| - __ pushl(value);
|
| + compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
|
| + comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index());
|
| +
|
| const intptr_t kNumArguments = 3;
|
| const intptr_t kNumArgsChecked = 1; // Type-feedback.
|
| - compiler->GenerateInstanceCall(cid(),
|
| - token_index(),
|
| - try_index(),
|
| + compiler->GenerateInstanceCall(comp->cid(),
|
| + comp->token_index(),
|
| + comp->try_index(),
|
| function_name,
|
| kNumArguments,
|
| Array::ZoneHandle(), // No optional arguments.
|
| @@ -451,6 +463,65 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
|
|
| +void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| + if (receiver_type() == kIllegalObjectKind) {
|
| + EmitStoreIndexedGeneric(compiler, this);
|
| + return;
|
| + }
|
| +
|
| + Register receiver = locs()->in(0).reg();
|
| + Register index = locs()->in(1).reg();
|
| + Register value = locs()->in(2).reg();
|
| + Register temp = locs()->temp(0).reg();
|
| +
|
| + Label* deopt = compiler->AddDeoptStub(cid(),
|
| + token_index(),
|
| + try_index(),
|
| + kDeoptStoreIndexed,
|
| + receiver,
|
| + index,
|
| + value);
|
| +
|
| + __ testl(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
|
| + __ j(ZERO, deopt);
|
| + __ CompareClassId(receiver, receiver_type(), temp);
|
| + __ j(NOT_EQUAL, deopt);
|
| +
|
| + __ testl(index, Immediate(kSmiTagMask));
|
| + __ j(NOT_ZERO, deopt);
|
| +
|
| + switch (receiver_type()) {
|
| + case kArray:
|
| + case kImmutableArray:
|
| + __ cmpl(index, FieldAddress(receiver, Array::length_offset()));
|
| + __ j(ABOVE_EQUAL, deopt);
|
| + // Note that index is Smi, i.e, times 2.
|
| + ASSERT(kSmiTagShift == 1);
|
| + __ StoreIntoObject(receiver,
|
| + FieldAddress(receiver, index, TIMES_2, sizeof(RawArray)),
|
| + value);
|
| + break;
|
| +
|
| + case kGrowableObjectArray: {
|
| + __ cmpl(index,
|
| + FieldAddress(receiver, GrowableObjectArray::length_offset()));
|
| + __ j(ABOVE_EQUAL, deopt);
|
| + __ movl(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
|
| + // Note that index is Smi, i.e, times 2.
|
| + ASSERT(kSmiTagShift == 1);
|
| + __ StoreIntoObject(temp,
|
| + FieldAddress(temp, index, TIMES_2, sizeof(RawArray)),
|
| + value);
|
| + break;
|
| + }
|
| +
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 2;
|
| return LocationSummary::Make(kNumInputs, Location::NoLocation());
|
|
|