Chromium Code Reviews| Index: runtime/vm/intermediate_language_ia32.cc |
| diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc |
| index 31dbe5496e5b5afc45d0fb6df9a277cb121d2fa8..2bc8e2ede2ecbce66afef99eb49266bd06eb4e60 100644 |
| --- a/runtime/vm/intermediate_language_ia32.cc |
| +++ b/runtime/vm/intermediate_language_ia32.cc |
| @@ -1612,7 +1612,6 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| ASSERT(!compiler->is_optimizing()); |
| return; // Nothing to emit. |
| } |
| - |
| const intptr_t value_cid = value()->Type()->ToCid(); |
| Register value_reg = locs()->in(0).reg(); |
| @@ -1658,7 +1657,6 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| LoadValueCid(compiler, value_cid_reg, value_reg); |
| - |
| Label skip_length_check; |
| __ cmpl(value_cid_reg, field_cid_operand); |
| // Value CID != Field guard CID, skip length check. |
| @@ -1669,17 +1667,49 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ pushl(value_cid_reg); |
| __ movl(value_cid_reg, |
| FieldAddress(value_reg, Array::length_offset())); |
| - __ cmpl(value_cid_reg, Immediate(field_length)); |
| + __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length))); |
| __ popl(value_cid_reg); |
| } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| __ pushl(value_cid_reg); |
| __ movl(value_cid_reg, |
| FieldAddress(value_reg, TypedData::length_offset())); |
| - __ cmpl(value_cid_reg, Immediate(field_length)); |
| + __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length))); |
| __ popl(value_cid_reg); |
| } else { |
| ASSERT(field_cid == kIllegalCid); |
| - // Following jump cannot not occur, fall through. |
| + Label check_array, local_exit, local_fail; |
|
srdjan
2013/08/28 16:00:55
Optional: maybe rename the labels to be self-expla
srdjan
2013/08/28 16:00:55
Please remind me how can field_cid be kIllegalCid
Cutch
2013/08/28 19:20:36
field_cid is kIllegalCid and field_length is kUnkn
Cutch
2013/08/29 08:27:17
Done.
|
| + // Check field guard. |
| + __ cmpl(value_cid_reg, Immediate(kNullCid)); |
| + __ j(EQUAL, &local_fail); |
| + // Check for typed data array. |
| + __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid)); |
| + __ j(GREATER, &local_fail); // Not a typed array or a regular array. |
| + __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid)); |
| + __ j(LESS, &check_array); // Could still be a regular array. |
| + __ pushl(value_cid_reg); |
| + __ movl(value_cid_reg, |
| + FieldAddress(value_reg, TypedData::length_offset())); |
| + __ cmpl(field_length_operand, value_cid_reg); |
|
srdjan
2013/08/28 16:00:55
Eliminate push-pop, use cmpl(field_length, FieldAd
Cutch
2013/08/29 08:27:17
We do not know field_length at compile time, I've
srdjan
2013/08/29 16:05:25
I see: field_length_operand is an address, not a r
|
| + __ popl(value_cid_reg); |
| + __ jmp(&local_exit); |
| + // Check for regular array. |
| + __ Bind(&check_array); |
| + __ cmpl(value_cid_reg, Immediate(kImmutableArrayCid)); |
| + __ j(GREATER, &local_fail); |
| + __ cmpl(value_cid_reg, Immediate(kArrayCid)); |
| + __ j(LESS, &local_fail); |
| + __ pushl(value_cid_reg); |
| + __ movl(value_cid_reg, |
| + FieldAddress(value_reg, Array::length_offset())); |
| + __ cmpl(field_length_operand, value_cid_reg); |
|
srdjan
2013/08/28 16:00:55
Use __ cmpl(field_length_operand, FieldAddress(...
Cutch
2013/08/29 08:27:17
field_length_operand is a FieldAddress there is no
|
| + __ popl(value_cid_reg); |
| + __ jmp(&local_exit); |
| + |
| + __ Bind(&local_fail); |
| + __ movl(field_length_operand, |
| + Immediate(Smi::RawValue(Field::kNoFixedLength))); |
| + |
| + __ Bind(&local_exit); |
| } |
| __ j(NOT_EQUAL, fail); |
| } |
| @@ -1704,22 +1734,23 @@ 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)) { |
| __ pushl(value_cid_reg); |
| __ movl(value_cid_reg, |
| FieldAddress(value_reg, Array::length_offset())); |
| - __ cmpl(value_cid_reg, Immediate(field_length)); |
| + __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length))); |
|
srdjan
2013/08/28 16:00:55
Eliminate push/pop by using __cmpl(FieldAddress(..
Cutch
2013/08/29 08:27:17
Done.
|
| __ popl(value_cid_reg); |
| - } else if (RawObject::IsTypedDataClassId(field_cid)) { |
| + } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| __ pushl(value_cid_reg); |
| __ movl(value_cid_reg, |
| FieldAddress(value_reg, TypedData::length_offset())); |
| - __ cmpl(value_cid_reg, Immediate(field_length)); |
| + __ cmpl(value_cid_reg, Immediate(Smi::RawValue(field_length))); |
|
srdjan
2013/08/28 16:00:55
Eliminate push/pop
Cutch
2013/08/29 08:27:17
Done.
|
| __ popl(value_cid_reg); |
| } else { |
| ASSERT(field_cid == kIllegalCid); |
| // Following jump cannot not occur, fall through. |
| } |
| + __ j(NOT_EQUAL, fail); |
| } |
| // Not identical, possibly null. |
| __ Bind(&skip_length_check); |
| @@ -1727,7 +1758,6 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| // Jump when class id guard and list length guard are okay. |
| __ j(EQUAL, &ok); |
| - |
| // Check if guard field is uninitialized. |
| __ cmpl(field_cid_operand, Immediate(kIllegalCid)); |
| // Jump to failure path when guard field has been initialized and |
| @@ -1766,7 +1796,8 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| __ jmp(&local_exit); // Updated field length from regular array. |
| __ Bind(&local_fail); |
| - __ movl(field_length_operand, Immediate(Field::kNoFixedLength)); |
| + __ movl(field_length_operand, |
| + Immediate(Smi::RawValue(Field::kNoFixedLength))); |
| __ Bind(&local_exit); |
| } |
| @@ -1780,18 +1811,21 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| ASSERT(field_reg != kNoRegister); |
| __ movl(field_cid_operand, Immediate(value_cid)); |
| __ movl(field_nullability_operand, Immediate(value_cid)); |
| - if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) { |
| - // Destroy value_cid_reg (safe because we are finished with it). |
| - __ movl(value_cid_reg, |
| - FieldAddress(value_reg, Array::length_offset())); |
| - __ movl(field_length_operand, value_cid_reg); |
| - } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| - // Destroy value_cid_reg (safe because we are finished with it). |
| - __ movl(value_cid_reg, |
| - FieldAddress(value_reg, TypedData::length_offset())); |
| - __ movl(field_length_operand, value_cid_reg); |
| - } else { |
| - __ movl(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). |
| + __ movl(value_cid_reg, |
| + FieldAddress(value_reg, Array::length_offset())); |
| + __ movl(field_length_operand, value_cid_reg); |
| + } else if (RawObject::IsTypedDataClassId(value_cid)) { |
| + // Destroy value_cid_reg (safe because we are finished with it). |
| + __ movl(value_cid_reg, |
| + FieldAddress(value_reg, TypedData::length_offset())); |
| + __ movl(field_length_operand, value_cid_reg); |
| + } else { |
| + __ movl(field_length_operand, |
| + Immediate(Smi::RawValue(Field::kNoFixedLength))); |
| + } |
| } |
| } |
| @@ -1800,7 +1834,6 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| } |
| } else { |
| // Field guard class has been initialized and is known. |
| - |
| if (field_reg != kNoRegister) { |
| __ LoadObject(field_reg, Field::ZoneHandle(field().raw())); |
| } |