Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1209)

Unified Diff: runtime/vm/intermediate_language_ia32.cc

Issue 22915008: Tests for GuardField length check along with bug fixes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/intermediate_language_ia32.cc
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index bdc4599ec00db1c9ebd6571d199f574bdca84fe0..3fe8ebcba21c0a5cf80449d0083c74c00187800b 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1539,7 +1539,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();
@@ -1585,7 +1584,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.
@@ -1596,17 +1594,53 @@ 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.
+ ASSERT(field_length == Field::kUnknownFixedLength);
+ // At compile time we do not know the type of the field nor its
+ // length. At execution time we may have set the class id and
+ // list length so we compare the guarded length with the
+ // list length here, without this check the list length could change
+ // without triggering a deoptimization.
+ Label check_array, length_compared, no_fixed_length;
+ __ cmpl(value_cid_reg, Immediate(kNullCid));
+ __ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
+ // Check for typed data array.
+ __ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
+ // Not a typed array or a regular array.
+ __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
+ __ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
+ // Could still be a regular array.
+ __ j(LESS, &check_array, Assembler::kNearJump);
+ __ pushl(value_cid_reg);
+ __ movl(value_cid_reg,
+ FieldAddress(value_reg, TypedData::length_offset()));
+ __ cmpl(field_length_operand, value_cid_reg);
+ __ popl(value_cid_reg);
+ __ jmp(&length_compared, Assembler::kNearJump);
+ // Check for regular array.
+ __ Bind(&check_array);
+ __ cmpl(value_cid_reg, Immediate(kImmutableArrayCid));
+ __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
+ __ cmpl(value_cid_reg, Immediate(kArrayCid));
+ __ j(LESS, &no_fixed_length, Assembler::kNearJump);
+ __ pushl(value_cid_reg);
+ __ movl(value_cid_reg,
+ FieldAddress(value_reg, Array::length_offset()));
+ __ cmpl(field_length_operand, value_cid_reg);
+ __ popl(value_cid_reg);
+ __ jmp(&length_compared, Assembler::kNearJump);
+ __ Bind(&no_fixed_length);
+ __ jmp(fail);
+ __ Bind(&length_compared);
}
__ j(NOT_EQUAL, fail);
}
@@ -1625,28 +1659,25 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ j(NOT_EQUAL, &skip_length_check);
// Insert length check.
if (field_has_length) {
- if (value_cid_reg == kNoRegister) {
- ASSERT(!compiler->is_optimizing());
- value_cid_reg = EDX;
- ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
- }
ASSERT(value_cid_reg != kNoRegister);
- if ((field_cid == kArrayCid) || (field_cid == kImmutableArrayCid)) {
- __ pushl(value_cid_reg);
- __ movl(value_cid_reg,
- FieldAddress(value_reg, Array::length_offset()));
- __ cmpl(value_cid_reg, Immediate(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));
- __ popl(value_cid_reg);
+ if ((value_cid == kArrayCid) || (value_cid == kImmutableArrayCid)) {
+ __ cmpl(FieldAddress(value_reg, Array::length_offset()),
+ Immediate(Smi::RawValue(field_length)));
+ } else if (RawObject::IsTypedDataClassId(value_cid)) {
+ __ cmpl(FieldAddress(value_reg, TypedData::length_offset()),
+ Immediate(Smi::RawValue(field_length)));
+ } else if (field_cid != kIllegalCid) {
+ ASSERT(field_cid != value_cid);
+ ASSERT(field_length >= 0);
+ // Field has a known class id and length. At compile time it is
+ // known that the value's class id is not a fixed length list.
+ __ jmp(fail);
} else {
ASSERT(field_cid == kIllegalCid);
+ ASSERT(field_length == Field::kUnknownFixedLength);
// Following jump cannot not occur, fall through.
}
+ __ j(NOT_EQUAL, fail);
}
// Not identical, possibly null.
__ Bind(&skip_length_check);
@@ -1654,7 +1685,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
@@ -1667,58 +1697,59 @@ void GuardFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
__ movl(field_cid_operand, value_cid_reg);
__ movl(field_nullability_operand, value_cid_reg);
if (field_has_length) {
- Label check_array, local_exit, local_fail;
+ Label check_array, length_set, no_fixed_length;
__ cmpl(value_cid_reg, Immediate(kNullCid));
- __ j(EQUAL, &local_fail);
+ __ j(EQUAL, &no_fixed_length, Assembler::kNearJump);
// Check for typed data array.
__ cmpl(value_cid_reg, Immediate(kTypedDataFloat32x4ArrayCid));
- __ j(GREATER, &local_fail); // Not a typed array or a regular array.
+ // Not a typed array or a regular array.
+ __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
__ cmpl(value_cid_reg, Immediate(kTypedDataInt8ArrayCid));
- __ j(LESS, &check_array); // Could still be a regular array.
+ // Could still be a regular array.
+ __ j(LESS, &check_array, Assembler::kNearJump);
// 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);
- __ jmp(&local_exit); // Updated field length typed data array.
+ // Updated field length typed data array.
+ __ jmp(&length_set, Assembler::kNearJump);
// Check for regular array.
__ Bind(&check_array);
__ cmpl(value_cid_reg, Immediate(kImmutableArrayCid));
- __ j(GREATER, &local_fail);
+ __ j(GREATER, &no_fixed_length, Assembler::kNearJump);
__ cmpl(value_cid_reg, Immediate(kArrayCid));
- __ j(LESS, &local_fail);
+ __ j(LESS, &no_fixed_length, Assembler::kNearJump);
// 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);
- __ jmp(&local_exit); // Updated field length from regular array.
-
- __ Bind(&local_fail);
- __ movl(field_length_operand, Immediate(Field::kNoFixedLength));
-
- __ Bind(&local_exit);
+ // Updated field length from regular array.
+ __ jmp(&length_set, Assembler::kNearJump);
+ __ Bind(&no_fixed_length);
+ __ movl(field_length_operand,
+ Immediate(Smi::RawValue(Field::kNoFixedLength)));
+ __ Bind(&length_set);
}
} else {
- if (value_cid_reg == kNoRegister) {
- ASSERT(!compiler->is_optimizing());
- value_cid_reg = EDX;
- ASSERT((value_cid_reg != value_reg) && (field_reg != value_cid_reg));
- }
- ASSERT(value_cid_reg != kNoRegister);
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) {
+ ASSERT(value_cid_reg != kNoRegister);
+ 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)));
+ }
}
}
@@ -1727,7 +1758,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()));
}
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intermediate_language_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698