Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index 0c2983f23e7c10e953084e2ccc85d885108b80d9..199049ba49da32f9235d537554ffb54b9e284912 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -91,6 +91,10 @@ void LCodeGen::FinishCode(Handle<Code> code) { |
prototype_maps_.at(i)->AddDependentCode( |
DependentCode::kPrototypeCheckGroup, code); |
} |
+ for (int i = 0 ; i < transition_maps_.length(); i++) { |
+ transition_maps_.at(i)->AddDependentCode( |
+ DependentCode::kTransitionGroup, code); |
+ } |
} |
@@ -2685,12 +2689,30 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
Register object = ToRegister(instr->object()); |
- Register result = ToRegister(instr->result()); |
+ if (!FLAG_track_double_fields) { |
+ ASSERT(!instr->hydrogen()->representation().IsDouble()); |
+ } |
+ Register temp = instr->hydrogen()->representation().IsDouble() |
+ ? scratch0() : ToRegister(instr->result()); |
if (instr->hydrogen()->is_in_object()) { |
- __ lw(result, FieldMemOperand(object, instr->hydrogen()->offset())); |
+ __ lw(temp, FieldMemOperand(object, instr->hydrogen()->offset())); |
} else { |
- __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
- __ lw(result, FieldMemOperand(result, instr->hydrogen()->offset())); |
+ __ lw(temp, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
+ __ lw(temp, FieldMemOperand(temp, instr->hydrogen()->offset())); |
+ } |
+ |
+ if (instr->hydrogen()->representation().IsDouble()) { |
+ Label load_from_heap_number, done; |
+ DoubleRegister result = ToDoubleRegister(instr->result()); |
+ FPURegister flt_scratch = double_scratch0().low(); |
+ __ JumpIfNotSmi(temp, &load_from_heap_number); |
+ __ SmiUntag(temp); |
+ __ mtc1(temp, flt_scratch); |
+ __ cvt_d_w(result, flt_scratch); |
+ __ Branch(&done); |
+ __ bind(&load_from_heap_number); |
+ __ ldc1(result, FieldMemOperand(temp, HeapNumber::kValueOffset)); |
+ __ bind(&done); |
} |
} |
@@ -3919,15 +3941,37 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) { |
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
+ Representation representation = instr->representation(); |
+ |
Register object = ToRegister(instr->object()); |
Register value = ToRegister(instr->value()); |
+ ASSERT(!object.is(value)); |
Register scratch = scratch0(); |
int offset = instr->offset(); |
- ASSERT(!object.is(value)); |
- |
- if (!instr->transition().is_null()) { |
- __ li(scratch, Operand(instr->transition())); |
+ if (FLAG_track_fields && representation.IsSmi()) { |
+ __ SmiTagCheckOverflow(value, value, scratch); |
+ if (!instr->hydrogen()->value()->range()->IsInSmiRange()) { |
+ DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); |
+ } |
+ } else if (FLAG_track_double_fields && representation.IsDouble() && |
+ !instr->hydrogen()->value()->type().IsSmi() && |
+ !instr->hydrogen()->value()->type().IsHeapNumber()) { |
+ Label do_store; |
+ __ JumpIfSmi(value, &do_store); |
+ Handle<Map> map(isolate()->factory()->heap_number_map()); |
+ |
+ __ lw(scratch, FieldMemOperand(value, HeapObject::kMapOffset)); |
+ DoCheckMapCommon(scratch, map, REQUIRE_EXACT_MAP, instr->environment()); |
+ __ bind(&do_store); |
+ } |
+ |
+ Handle<Map> transition = instr->transition(); |
+ if (!transition.is_null()) { |
+ if (transition->CanBeDeprecated()) { |
+ transition_maps_.Add(transition, info()->zone()); |
+ } |
+ __ li(scratch, Operand(transition)); |
__ sw(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
if (instr->hydrogen()->NeedsWriteBarrierForMap()) { |
Register temp = ToRegister(instr->temp()); |