Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 3c03b1560841bcd17587293056cb0771d681f8a7..29b2482199910ff3191a430e959a3910a318f3ac 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -6679,10 +6679,16 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate, |
if (properties->length() > 0) { |
return false; |
} else { |
- int nof = boilerplate->map()->inobject_properties(); |
- for (int i = 0; i < nof; i++) { |
+ Handle<DescriptorArray> descriptors( |
+ boilerplate->map()->instance_descriptors()); |
+ int limit = boilerplate->map()->NumberOfOwnDescriptors(); |
+ for (int i = 0; i < limit; i++) { |
+ PropertyDetails details = descriptors->GetDetails(i); |
+ if (details.type() != FIELD) continue; |
+ Representation representation = details.representation(); |
+ int index = descriptors->GetFieldIndex(i); |
if ((*max_properties)-- == 0) return false; |
- Handle<Object> value(boilerplate->InObjectPropertyAt(i), isolate); |
+ Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate); |
if (value->IsJSObject()) { |
Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
if (!IsFastLiteral(value_object, |
@@ -6692,6 +6698,8 @@ static bool IsFastLiteral(Handle<JSObject> boilerplate, |
pointer_size)) { |
return false; |
} |
+ } else if (representation.IsDouble()) { |
+ *data_size += HeapNumber::kSize; |
} |
} |
} |
@@ -6741,6 +6749,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
expr->fast_elements(), |
expr->literal_index(), |
expr->depth(), |
+ expr->may_store_doubles(), |
expr->has_function())); |
} |
@@ -7047,9 +7056,33 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
} else { |
offset += FixedArray::kHeaderSize; |
} |
+ bool transition_to_field = lookup->IsTransitionToField(*map); |
+ if (FLAG_track_double_fields && representation.IsDouble()) { |
+ if (transition_to_field) { |
+ NoObservableSideEffectsScope no_side_effects(this); |
+ HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( |
+ HeapNumber::kSize, Representation::Integer32())); |
+ HInstruction* double_box = AddInstruction(new(zone()) HAllocate( |
+ environment()->LookupContext(), heap_number_size, |
+ HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
+ BuildStoreMap(double_box, isolate()->factory()->heap_number_map()); |
+ AddInstruction(new(zone()) HStoreNamedField( |
+ double_box, name, value, true, |
+ Representation::Double(), HeapNumber::kValueOffset)); |
+ value = double_box; |
+ representation = Representation::Tagged(); |
+ } else { |
+ HInstruction* double_box = AddInstruction(new(zone()) HLoadNamedField( |
+ object, is_in_object, Representation::Tagged(), offset)); |
+ double_box->set_type(HType::HeapNumber()); |
+ return new(zone()) HStoreNamedField( |
+ double_box, name, value, true, |
+ Representation::Double(), HeapNumber::kValueOffset); |
+ } |
+ } |
HStoreNamedField* instr = new(zone()) HStoreNamedField( |
object, name, value, is_in_object, representation, offset); |
- if (lookup->IsTransitionToField(*map)) { |
+ if (transition_to_field) { |
Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
instr->set_transition(transition); |
// TODO(fschneider): Record the new map type of the object in the IR to |
@@ -7764,7 +7797,20 @@ HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( |
bool inobject, |
Representation representation, |
int offset) { |
- return new(zone()) HLoadNamedField(object, inobject, representation, offset); |
+ bool load_double = false; |
+ if (representation.IsDouble()) { |
+ representation = Representation::Tagged(); |
+ load_double = FLAG_track_double_fields; |
+ } |
+ HLoadNamedField* field = |
+ new(zone()) HLoadNamedField(object, inobject, representation, offset); |
+ if (load_double) { |
+ AddInstruction(field); |
+ field->set_type(HType::HeapNumber()); |
+ return new(zone()) HLoadNamedField( |
+ field, true, Representation::Double(), HeapNumber::kValueOffset); |
+ } |
+ return field; |
} |
@@ -10766,7 +10812,6 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
elements->Size() : 0; |
int elements_offset = *offset + object_size; |
- int inobject_properties = boilerplate_object->map()->inobject_properties(); |
if (create_allocation_site_info) { |
elements_offset += AllocationSiteInfo::kSize; |
*offset += AllocationSiteInfo::kSize; |
@@ -10780,32 +10825,49 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
// Copy in-object properties. |
HValue* object_properties = |
AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
- for (int i = 0; i < inobject_properties; i++) { |
+ |
+ Handle<DescriptorArray> descriptors( |
+ boilerplate_object->map()->instance_descriptors()); |
+ int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
+ |
+ for (int i = 0; i < limit; i++) { |
+ PropertyDetails details = descriptors->GetDetails(i); |
+ if (details.type() != FIELD) continue; |
+ int index = descriptors->GetFieldIndex(i); |
+ int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
+ Handle<Name> name(descriptors->GetKey(i)); |
Handle<Object> value = |
- Handle<Object>(boilerplate_object->InObjectPropertyAt(i), |
+ Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
isolate()); |
if (value->IsJSObject()) { |
Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
- Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), |
+ Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
isolate())); |
HInstruction* value_instruction = |
AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
- // TODO(verwaest): choose correct storage. |
AddInstruction(new(zone) HStoreNamedField( |
- object_properties, factory->unknown_field_string(), value_instruction, |
- true, Representation::Tagged(), |
- boilerplate_object->GetInObjectPropertyOffset(i))); |
+ object_properties, name, value_instruction, true, |
+ Representation::Tagged(), property_offset)); |
BuildEmitDeepCopy(value_object, original_value_object, target, |
offset, DONT_TRACK_ALLOCATION_SITE); |
} else { |
- // TODO(verwaest): choose correct storage. |
+ Representation representation = details.representation(); |
HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
value, Representation::Tagged())); |
+ if (representation.IsDouble()) { |
+ HInstruction* double_box = |
+ AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
+ BuildStoreMap(double_box, factory->heap_number_map()); |
+ AddInstruction(new(zone) HStoreNamedField( |
+ double_box, name, value_instruction, true, |
+ Representation::Double(), HeapNumber::kValueOffset)); |
+ value_instruction = double_box; |
+ *offset += HeapNumber::kSize; |
+ } |
AddInstruction(new(zone) HStoreNamedField( |
- object_properties, factory->unknown_field_string(), value_instruction, |
- true, Representation::Tagged(), |
- boilerplate_object->GetInObjectPropertyOffset(i))); |
+ object_properties, name, value_instruction, true, |
+ Representation::Tagged(), property_offset)); |
} |
} |