| Index: runtime/vm/intermediate_language_x64.cc
|
| diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
|
| index c5a1bf3af2a6a1a2ff56a8a6b044f5122cf1ba19..d4757fc6100639a821d823cbee188d19ed8a7376 100644
|
| --- a/runtime/vm/intermediate_language_x64.cc
|
| +++ b/runtime/vm/intermediate_language_x64.cc
|
| @@ -1555,7 +1555,7 @@ LocationSummary* GuardFieldInstr::MakeLocationSummary() const {
|
| void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| const intptr_t field_cid = field().guarded_cid();
|
| const intptr_t nullability = field().is_nullable() ? kNullCid : kIllegalCid;
|
| - const intptr_t field_length = field().guarded_list_length();
|
| + const intptr_t field_length = Smi::RawValue(field().guarded_list_length());
|
| const bool field_has_length = field().needs_length_check();
|
| const bool needs_value_temp_reg =
|
| (field_has_length || ((value()->Type()->ToCid() == kDynamicCid) &&
|
| @@ -1602,7 +1602,7 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| }
|
|
|
| __ LoadObject(field_reg, Field::ZoneHandle(field().raw()));
|
| -
|
| + int64_t raw_no_fixed_length = Smi::RawValue(Field::kNoFixedLength);
|
| FieldAddress field_cid_operand(field_reg, Field::guarded_cid_offset());
|
| FieldAddress field_nullability_operand(
|
| field_reg, Field::is_nullable_offset());
|
| @@ -1637,7 +1637,37 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ popq(value_cid_reg);
|
| } else {
|
| ASSERT(field_cid == kIllegalCid);
|
| - // Following jump cannot not occur, fall through.
|
| + Label check_array, local_exit, local_fail;
|
| + __ cmpq(value_cid_reg, Immediate(kNullCid));
|
| + __ j(EQUAL, &local_fail);
|
| + // Check for typed data array.
|
| + __ cmpq(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
|
| + __ j(GREATER, &local_fail); // Not a typed array or a regular array.
|
| + __ cmpq(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
|
| + __ j(LESS, &check_array); // Could still be a regular array.
|
| + __ pushq(value_cid_reg);
|
| + __ movq(value_cid_reg,
|
| + FieldAddress(value_reg, TypedData::length_offset()));
|
| + __ cmpq(field_length_operand, value_cid_reg);
|
| + __ popq(value_cid_reg);
|
| + __ jmp(&local_exit);
|
| + // Check for regular array.
|
| + __ Bind(&check_array);
|
| + __ cmpq(value_cid_reg, Immediate(kImmutableArrayCid));
|
| + __ j(GREATER, &local_fail);
|
| + __ cmpq(value_cid_reg, Immediate(kArrayCid));
|
| + __ j(LESS, &local_fail);
|
| + __ pushq(value_cid_reg);
|
| + __ movq(value_cid_reg,
|
| + FieldAddress(value_reg, Array::length_offset()));
|
| + __ cmpq(field_length_operand, value_cid_reg);
|
| + __ popq(value_cid_reg);
|
| + __ jmp(&local_exit);
|
| +
|
| + __ Bind(&local_fail);
|
| + __ movq(field_length_operand, Immediate(raw_no_fixed_length));
|
| +
|
| + __ Bind(&local_exit);
|
| }
|
| __ j(NOT_EQUAL, fail);
|
| }
|
| @@ -1658,13 +1688,13 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
|
| }
|
| ASSERT(value_cid_reg != kNoRegister);
|
| - if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
|
| + if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
|
| __ pushq(value_cid_reg);
|
| __ movq(value_cid_reg,
|
| FieldAddress(value_reg, Array::length_offset()));
|
| __ cmpq(value_cid_reg, Immediate(field_length));
|
| __ popq(value_cid_reg);
|
| - } else if (RawObject::IsTypedDataClassId(field_cid)) {
|
| + } else if (RawObject::IsTypedDataClassId(value_cid)) {
|
| __ pushq(value_cid_reg);
|
| __ movq(value_cid_reg,
|
| FieldAddress(value_reg, TypedData::length_offset()));
|
| @@ -1674,6 +1704,7 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT(field_cid == kIllegalCid);
|
| // Following jump cannot not occur, fall through.
|
| }
|
| + __ j(NOT_EQUAL, fail);
|
| }
|
| // Not identical, possibly null.
|
| __ Bind(&skip_length_check);
|
| @@ -1713,7 +1744,7 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| __ jmp(&local_exit); // Updated field length from regular array.
|
|
|
| __ Bind(&local_fail);
|
| - __ movq(field_length_operand, Immediate(Field::kNoFixedLength));
|
| + __ movq(field_length_operand, Immediate(raw_no_fixed_length));
|
|
|
| __ Bind(&local_exit);
|
| }
|
| @@ -1727,21 +1758,22 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| ASSERT(field_reg != kNoRegister);
|
| __ movq(field_cid_operand, Immediate(value_cid));
|
| __ movq(field_nullability_operand, Immediate(value_cid));
|
| - if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
|
| - // Destroy value_cid_reg (safe because we are finished with it).
|
| - __ movq(value_cid_reg,
|
| - FieldAddress(value_reg, Array::length_offset()));
|
| - __ movq(field_length_operand, value_cid_reg);
|
| - } else if (RawObject::IsTypedDataClassId(value_cid)) {
|
| - // Destroy value_cid_reg (safe because we are finished with it).
|
| - __ movq(value_cid_reg,
|
| - FieldAddress(value_reg, TypedData::length_offset()));
|
| - __ movq(field_length_operand, value_cid_reg);
|
| - } else {
|
| - __ movq(field_length_operand, Immediate(Field::kNoFixedLength));
|
| + if (field_has_length) {
|
| + if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
|
| + // Destroy value_cid_reg (safe because we are finished with it).
|
| + __ movq(value_cid_reg,
|
| + FieldAddress(value_reg, Array::length_offset()));
|
| + __ movq(field_length_operand, value_cid_reg);
|
| + } else if (RawObject::IsTypedDataClassId(value_cid)) {
|
| + // Destroy value_cid_reg (safe because we are finished with it).
|
| + __ movq(value_cid_reg,
|
| + FieldAddress(value_reg, TypedData::length_offset()));
|
| + __ movq(field_length_operand, value_cid_reg);
|
| + } else {
|
| + __ movq(field_length_operand, Immediate(raw_no_fixed_length));
|
| + }
|
| }
|
| }
|
| -
|
| if (!ok_is_fall_through) {
|
| __ jmp(&ok);
|
| }
|
|
|