Index: src/arm/lithium-codegen-arm.cc |
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
index 24231c594b5d234f88657865e572a1ea8ec60346..1fc51ebd4fa57f10f0866306d1655e692df2a94d 100644 |
--- a/src/arm/lithium-codegen-arm.cc |
+++ b/src/arm/lithium-codegen-arm.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); |
+ } |
} |
@@ -3072,12 +3076,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() |
+ ? ToRegister(instr->temp()) : ToRegister(instr->result()); |
if (instr->hydrogen()->is_in_object()) { |
- __ ldr(result, FieldMemOperand(object, instr->hydrogen()->offset())); |
+ __ ldr(temp, FieldMemOperand(object, instr->hydrogen()->offset())); |
} else { |
- __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
- __ ldr(result, FieldMemOperand(result, instr->hydrogen()->offset())); |
+ __ ldr(temp, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
+ __ ldr(temp, FieldMemOperand(temp, instr->hydrogen()->offset())); |
+ } |
+ |
+ if (instr->hydrogen()->representation().IsDouble()) { |
+ Label load_from_heap_number, done; |
+ DwVfpRegister result = ToDoubleRegister(instr->result()); |
+ SwVfpRegister flt_scratch = double_scratch0().low(); |
+ __ JumpIfNotSmi(temp, &load_from_heap_number); |
+ __ SmiUntag(temp); |
+ __ vmov(flt_scratch, temp); |
+ __ vcvt_f64_s32(result, flt_scratch); |
+ __ b(&done); |
+ __ sub(ip, temp, Operand(kHeapObjectTag)); |
+ __ vldr(result, ip, HeapNumber::kValueOffset); |
+ __ bind(&done); |
} |
} |
@@ -4240,15 +4262,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()) { |
- __ mov(scratch, Operand(instr->transition())); |
+ if (FLAG_track_fields && representation.IsSmi()) { |
+ __ SmiTag(value, value, SetCC); |
+ if (!instr->hydrogen()->value()->range()->IsInSmiRange()) { |
+ DeoptimizeIf(vs, instr->environment()); |
+ } |
+ } 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()); |
+ |
+ __ ldr(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()); |
+ } |
+ __ mov(scratch, Operand(transition)); |
__ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
if (instr->hydrogen()->NeedsWriteBarrierForMap()) { |
Register temp = ToRegister(instr->temp()); |