| Index: runtime/vm/intermediate_language_x64.cc
|
| diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
|
| index 269806c1ad7a7e86cfd2be741fe146c6a6cdb87f..86fc0f6baca9a96e655dee3a8f6786c455b65c7d 100644
|
| --- a/runtime/vm/intermediate_language_x64.cc
|
| +++ b/runtime/vm/intermediate_language_x64.cc
|
| @@ -473,10 +473,6 @@ void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| Register index = locs()->in(1).reg();
|
| Register result = locs()->out().reg();
|
|
|
| - const Class& receiver_class =
|
| - Class::ZoneHandle(Isolate::Current()->class_table()->At(
|
| - receiver_type()));
|
| -
|
| const DeoptReasonId deopt_reason = (receiver_type() == kGrowableObjectArray) ?
|
| kDeoptLoadIndexedGrowableArray : kDeoptLoadIndexedFixedArray;
|
|
|
| @@ -489,7 +485,7 @@ void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|
|
| __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
|
| __ j(ZERO, deopt);
|
| - __ CompareClassId(receiver, receiver_class.id());
|
| + __ CompareClassId(receiver, receiver_type());
|
| __ j(NOT_EQUAL, deopt);
|
|
|
| __ testq(index, Immediate(kSmiTagMask));
|
| @@ -527,26 +523,40 @@ void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
|
|
|
| LocationSummary* StoreIndexedComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 3;
|
| - return LocationSummary::Make(kNumInputs, Location::NoLocation());
|
| + if (receiver_type() == kGrowableObjectArray) {
|
| + 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 if (receiver_type() == kArray) {
|
| + return LocationSummary::Make(kNumInputs, Location::NoLocation());
|
| + } 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)));
|
|
|
| - __ pushq(receiver);
|
| - __ pushq(index);
|
| - __ pushq(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.
|
| @@ -554,6 +564,69 @@ 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();
|
| +
|
| + const Class& receiver_class =
|
| + Class::ZoneHandle(Isolate::Current()->class_table()->At(
|
| + receiver_type()));
|
| +
|
| + Label* deopt = compiler->AddDeoptStub(cid(),
|
| + token_index(),
|
| + try_index(),
|
| + kDeoptStoreIndexed,
|
| + receiver,
|
| + index,
|
| + value);
|
| +
|
| + __ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
|
| + __ j(ZERO, deopt);
|
| + __ CompareClassId(receiver, receiver_class.id());
|
| + __ j(NOT_EQUAL, deopt);
|
| +
|
| + __ testq(index, Immediate(kSmiTagMask));
|
| + __ j(NOT_ZERO, deopt);
|
| +
|
| + switch (receiver_type()) {
|
| + case kArray:
|
| + case kImmutableArray:
|
| + __ cmpq(index, FieldAddress(receiver, Array::length_offset()));
|
| + __ j(ABOVE_EQUAL, deopt);
|
| + // Note that index is Smi, i.e, times 4.
|
| + ASSERT(kSmiTagShift == 1);
|
| + __ StoreIntoObject(receiver,
|
| + FieldAddress(receiver, index, TIMES_4, sizeof(RawArray)),
|
| + value);
|
| + break;
|
| +
|
| + case kGrowableObjectArray: {
|
| + Register temp = locs()->temp(0).reg();
|
| + __ cmpq(index,
|
| + FieldAddress(receiver, GrowableObjectArray::length_offset()));
|
| + __ j(ABOVE_EQUAL, deopt);
|
| + __ movq(temp, FieldAddress(receiver, GrowableObjectArray::data_offset()));
|
| + // Note that index is Smi, i.e, times 4.
|
| + ASSERT(kSmiTagShift == 1);
|
| + __ StoreIntoObject(temp,
|
| + FieldAddress(temp, index, TIMES_4, sizeof(RawArray)),
|
| + value);
|
| + break;
|
| + }
|
| +
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| LocationSummary* InstanceSetterComp::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 2;
|
| return LocationSummary::Make(kNumInputs, Location::NoLocation());
|
|
|