OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 6661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6672 *pointer_size += FixedArray::SizeFor(length); | 6672 *pointer_size += FixedArray::SizeFor(length); |
6673 } else { | 6673 } else { |
6674 return false; | 6674 return false; |
6675 } | 6675 } |
6676 } | 6676 } |
6677 | 6677 |
6678 Handle<FixedArray> properties(boilerplate->properties()); | 6678 Handle<FixedArray> properties(boilerplate->properties()); |
6679 if (properties->length() > 0) { | 6679 if (properties->length() > 0) { |
6680 return false; | 6680 return false; |
6681 } else { | 6681 } else { |
6682 int nof = boilerplate->map()->inobject_properties(); | 6682 Handle<DescriptorArray> descriptors( |
6683 for (int i = 0; i < nof; i++) { | 6683 boilerplate->map()->instance_descriptors()); |
| 6684 int limit = boilerplate->map()->NumberOfOwnDescriptors(); |
| 6685 for (int i = 0; i < limit; i++) { |
| 6686 PropertyDetails details = descriptors->GetDetails(i); |
| 6687 if (details.type() != FIELD) continue; |
| 6688 Representation representation = details.representation(); |
| 6689 int index = descriptors->GetFieldIndex(i); |
6684 if ((*max_properties)-- == 0) return false; | 6690 if ((*max_properties)-- == 0) return false; |
6685 Handle<Object> value(boilerplate->InObjectPropertyAt(i), isolate); | 6691 Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate); |
6686 if (value->IsJSObject()) { | 6692 if (value->IsJSObject()) { |
6687 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 6693 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
6688 if (!IsFastLiteral(value_object, | 6694 if (!IsFastLiteral(value_object, |
6689 max_depth - 1, | 6695 max_depth - 1, |
6690 max_properties, | 6696 max_properties, |
6691 data_size, | 6697 data_size, |
6692 pointer_size)) { | 6698 pointer_size)) { |
6693 return false; | 6699 return false; |
6694 } | 6700 } |
| 6701 } else if (representation.IsDouble()) { |
| 6702 *data_size += HeapNumber::kSize; |
6695 } | 6703 } |
6696 } | 6704 } |
6697 } | 6705 } |
6698 | 6706 |
6699 *pointer_size += boilerplate->map()->instance_size(); | 6707 *pointer_size += boilerplate->map()->instance_size(); |
6700 return true; | 6708 return true; |
6701 } | 6709 } |
6702 | 6710 |
6703 | 6711 |
6704 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 6712 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7040 bool is_in_object = index < 0; | 7048 bool is_in_object = index < 0; |
7041 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 7049 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
7042 int offset = index * kPointerSize; | 7050 int offset = index * kPointerSize; |
7043 if (index < 0) { | 7051 if (index < 0) { |
7044 // Negative property indices are in-object properties, indexed | 7052 // Negative property indices are in-object properties, indexed |
7045 // from the end of the fixed part of the object. | 7053 // from the end of the fixed part of the object. |
7046 offset += map->instance_size(); | 7054 offset += map->instance_size(); |
7047 } else { | 7055 } else { |
7048 offset += FixedArray::kHeaderSize; | 7056 offset += FixedArray::kHeaderSize; |
7049 } | 7057 } |
| 7058 bool transition_to_field = lookup->IsTransitionToField(*map); |
| 7059 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 7060 if (transition_to_field) { |
| 7061 NoObservableSideEffectsScope no_side_effects(this); |
| 7062 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( |
| 7063 HeapNumber::kSize, Representation::Integer32())); |
| 7064 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( |
| 7065 environment()->LookupContext(), heap_number_size, |
| 7066 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
| 7067 BuildStoreMap(double_box, isolate()->factory()->heap_number_map()); |
| 7068 AddInstruction(new(zone()) HStoreNamedField( |
| 7069 double_box, name, value, true, |
| 7070 Representation::Double(), HeapNumber::kValueOffset)); |
| 7071 value = double_box; |
| 7072 representation = Representation::Tagged(); |
| 7073 } else { |
| 7074 HInstruction* double_box = AddInstruction(new(zone()) HLoadNamedField( |
| 7075 object, is_in_object, Representation::Tagged(), offset)); |
| 7076 double_box->set_type(HType::HeapNumber()); |
| 7077 return new(zone()) HStoreNamedField( |
| 7078 double_box, name, value, true, |
| 7079 Representation::Double(), HeapNumber::kValueOffset); |
| 7080 } |
| 7081 } |
7050 HStoreNamedField* instr = new(zone()) HStoreNamedField( | 7082 HStoreNamedField* instr = new(zone()) HStoreNamedField( |
7051 object, name, value, is_in_object, representation, offset); | 7083 object, name, value, is_in_object, representation, offset); |
7052 if (lookup->IsTransitionToField(*map)) { | 7084 if (transition_to_field) { |
7053 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 7085 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
7054 instr->set_transition(transition); | 7086 instr->set_transition(transition); |
7055 // TODO(fschneider): Record the new map type of the object in the IR to | 7087 // TODO(fschneider): Record the new map type of the object in the IR to |
7056 // enable elimination of redundant checks after the transition store. | 7088 // enable elimination of redundant checks after the transition store. |
7057 instr->SetGVNFlag(kChangesMaps); | 7089 instr->SetGVNFlag(kChangesMaps); |
7058 } | 7090 } |
7059 return instr; | 7091 return instr; |
7060 } | 7092 } |
7061 | 7093 |
7062 | 7094 |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7757 : index * kPointerSize + FixedArray::kHeaderSize; | 7789 : index * kPointerSize + FixedArray::kHeaderSize; |
7758 return DoBuildLoadNamedField(object, inobject, representation, offset); | 7790 return DoBuildLoadNamedField(object, inobject, representation, offset); |
7759 } | 7791 } |
7760 | 7792 |
7761 | 7793 |
7762 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( | 7794 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( |
7763 HValue* object, | 7795 HValue* object, |
7764 bool inobject, | 7796 bool inobject, |
7765 Representation representation, | 7797 Representation representation, |
7766 int offset) { | 7798 int offset) { |
7767 return new(zone()) HLoadNamedField(object, inobject, representation, offset); | 7799 bool load_double = false; |
| 7800 if (representation.IsDouble()) { |
| 7801 representation = Representation::Tagged(); |
| 7802 load_double = FLAG_track_double_fields; |
| 7803 } |
| 7804 HLoadNamedField* field = |
| 7805 new(zone()) HLoadNamedField(object, inobject, representation, offset); |
| 7806 if (load_double) { |
| 7807 AddInstruction(field); |
| 7808 field->set_type(HType::HeapNumber()); |
| 7809 return new(zone()) HLoadNamedField( |
| 7810 field, true, Representation::Double(), HeapNumber::kValueOffset); |
| 7811 } |
| 7812 return field; |
7768 } | 7813 } |
7769 | 7814 |
7770 | 7815 |
7771 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7816 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
7772 HValue* object, | 7817 HValue* object, |
7773 Handle<String> name, | 7818 Handle<String> name, |
7774 Property* expr) { | 7819 Property* expr) { |
7775 if (expr->IsUninitialized()) { | 7820 if (expr->IsUninitialized()) { |
7776 AddSoftDeoptimize(); | 7821 AddSoftDeoptimize(); |
7777 } | 7822 } |
(...skipping 2981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10759 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 10804 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
10760 | 10805 |
10761 // Increase the offset so that subsequent objects end up right after | 10806 // Increase the offset so that subsequent objects end up right after |
10762 // this object and its backing store. | 10807 // this object and its backing store. |
10763 int object_offset = *offset; | 10808 int object_offset = *offset; |
10764 int object_size = boilerplate_object->map()->instance_size(); | 10809 int object_size = boilerplate_object->map()->instance_size(); |
10765 int elements_size = (elements->length() > 0 && | 10810 int elements_size = (elements->length() > 0 && |
10766 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 10811 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
10767 elements->Size() : 0; | 10812 elements->Size() : 0; |
10768 int elements_offset = *offset + object_size; | 10813 int elements_offset = *offset + object_size; |
10769 int inobject_properties = boilerplate_object->map()->inobject_properties(); | |
10770 if (create_allocation_site_info) { | 10814 if (create_allocation_site_info) { |
10771 elements_offset += AllocationSiteInfo::kSize; | 10815 elements_offset += AllocationSiteInfo::kSize; |
10772 *offset += AllocationSiteInfo::kSize; | 10816 *offset += AllocationSiteInfo::kSize; |
10773 } | 10817 } |
10774 | 10818 |
10775 *offset += object_size + elements_size; | 10819 *offset += object_size + elements_size; |
10776 | 10820 |
10777 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target, | 10821 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target, |
10778 object_offset, elements_offset, elements_size); | 10822 object_offset, elements_offset, elements_size); |
10779 | 10823 |
10780 // Copy in-object properties. | 10824 // Copy in-object properties. |
10781 HValue* object_properties = | 10825 HValue* object_properties = |
10782 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10826 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
10783 for (int i = 0; i < inobject_properties; i++) { | 10827 |
| 10828 Handle<DescriptorArray> descriptors( |
| 10829 boilerplate_object->map()->instance_descriptors()); |
| 10830 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 10831 |
| 10832 for (int i = 0; i < limit; i++) { |
| 10833 PropertyDetails details = descriptors->GetDetails(i); |
| 10834 if (details.type() != FIELD) continue; |
| 10835 int index = descriptors->GetFieldIndex(i); |
| 10836 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 10837 Handle<Name> name(descriptors->GetKey(i)); |
10784 Handle<Object> value = | 10838 Handle<Object> value = |
10785 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), | 10839 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
10786 isolate()); | 10840 isolate()); |
10787 if (value->IsJSObject()) { | 10841 if (value->IsJSObject()) { |
10788 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10842 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10789 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10843 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10790 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), | 10844 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
10791 isolate())); | 10845 isolate())); |
10792 HInstruction* value_instruction = | 10846 HInstruction* value_instruction = |
10793 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10847 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10794 // TODO(verwaest): choose correct storage. | |
10795 AddInstruction(new(zone) HStoreNamedField( | 10848 AddInstruction(new(zone) HStoreNamedField( |
10796 object_properties, factory->unknown_field_string(), value_instruction, | 10849 object_properties, name, value_instruction, true, |
10797 true, Representation::Tagged(), | 10850 Representation::Tagged(), property_offset)); |
10798 boilerplate_object->GetInObjectPropertyOffset(i))); | |
10799 BuildEmitDeepCopy(value_object, original_value_object, target, | 10851 BuildEmitDeepCopy(value_object, original_value_object, target, |
10800 offset, DONT_TRACK_ALLOCATION_SITE); | 10852 offset, DONT_TRACK_ALLOCATION_SITE); |
10801 } else { | 10853 } else { |
10802 // TODO(verwaest): choose correct storage. | 10854 Representation representation = details.representation(); |
10803 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10855 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10804 value, Representation::Tagged())); | 10856 value, Representation::Tagged())); |
| 10857 if (representation.IsDouble()) { |
| 10858 HInstruction* double_box = |
| 10859 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
| 10860 BuildStoreMap(double_box, factory->heap_number_map()); |
| 10861 AddInstruction(new(zone) HStoreNamedField( |
| 10862 double_box, name, value_instruction, true, |
| 10863 Representation::Double(), HeapNumber::kValueOffset)); |
| 10864 value_instruction = double_box; |
| 10865 *offset += HeapNumber::kSize; |
| 10866 } |
10805 AddInstruction(new(zone) HStoreNamedField( | 10867 AddInstruction(new(zone) HStoreNamedField( |
10806 object_properties, factory->unknown_field_string(), value_instruction, | 10868 object_properties, name, value_instruction, true, |
10807 true, Representation::Tagged(), | 10869 Representation::Tagged(), property_offset)); |
10808 boilerplate_object->GetInObjectPropertyOffset(i))); | |
10809 } | 10870 } |
10810 } | 10871 } |
10811 | 10872 |
10812 // Build Allocation Site Info if desired | 10873 // Build Allocation Site Info if desired |
10813 if (create_allocation_site_info) { | 10874 if (create_allocation_site_info) { |
10814 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10875 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10815 } | 10876 } |
10816 | 10877 |
10817 if (object_elements != NULL) { | 10878 if (object_elements != NULL) { |
10818 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10879 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12291 } | 12352 } |
12292 } | 12353 } |
12293 | 12354 |
12294 #ifdef DEBUG | 12355 #ifdef DEBUG |
12295 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12356 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12296 if (allocator_ != NULL) allocator_->Verify(); | 12357 if (allocator_ != NULL) allocator_->Verify(); |
12297 #endif | 12358 #endif |
12298 } | 12359 } |
12299 | 12360 |
12300 } } // namespace v8::internal | 12361 } } // namespace v8::internal |
OLD | NEW |