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 29 matching lines...) Expand all Loading... |
6734 DONT_TRACK_ALLOCATION_SITE); | 6742 DONT_TRACK_ALLOCATION_SITE); |
6735 } else { | 6743 } else { |
6736 Handle<FixedArray> closure_literals(closure->literals(), isolate()); | 6744 Handle<FixedArray> closure_literals(closure->literals(), isolate()); |
6737 literal = AddInstruction( | 6745 literal = AddInstruction( |
6738 new(zone()) HObjectLiteral(context, | 6746 new(zone()) HObjectLiteral(context, |
6739 expr->constant_properties(), | 6747 expr->constant_properties(), |
6740 closure_literals, | 6748 closure_literals, |
6741 expr->fast_elements(), | 6749 expr->fast_elements(), |
6742 expr->literal_index(), | 6750 expr->literal_index(), |
6743 expr->depth(), | 6751 expr->depth(), |
| 6752 expr->may_store_doubles(), |
6744 expr->has_function())); | 6753 expr->has_function())); |
6745 } | 6754 } |
6746 | 6755 |
6747 // The object is expected in the bailout environment during computation | 6756 // The object is expected in the bailout environment during computation |
6748 // of the property values and is the value of the entire expression. | 6757 // of the property values and is the value of the entire expression. |
6749 Push(literal); | 6758 Push(literal); |
6750 | 6759 |
6751 expr->CalculateEmitStore(zone()); | 6760 expr->CalculateEmitStore(zone()); |
6752 | 6761 |
6753 for (int i = 0; i < expr->properties()->length(); i++) { | 6762 for (int i = 0; i < expr->properties()->length(); i++) { |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7040 bool is_in_object = index < 0; | 7049 bool is_in_object = index < 0; |
7041 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | 7050 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
7042 int offset = index * kPointerSize; | 7051 int offset = index * kPointerSize; |
7043 if (index < 0) { | 7052 if (index < 0) { |
7044 // Negative property indices are in-object properties, indexed | 7053 // Negative property indices are in-object properties, indexed |
7045 // from the end of the fixed part of the object. | 7054 // from the end of the fixed part of the object. |
7046 offset += map->instance_size(); | 7055 offset += map->instance_size(); |
7047 } else { | 7056 } else { |
7048 offset += FixedArray::kHeaderSize; | 7057 offset += FixedArray::kHeaderSize; |
7049 } | 7058 } |
| 7059 bool transition_to_field = lookup->IsTransitionToField(*map); |
| 7060 if (FLAG_track_double_fields && representation.IsDouble()) { |
| 7061 if (transition_to_field) { |
| 7062 NoObservableSideEffectsScope no_side_effects(this); |
| 7063 HInstruction* heap_number_size = AddInstruction(new(zone()) HConstant( |
| 7064 HeapNumber::kSize, Representation::Integer32())); |
| 7065 HInstruction* double_box = AddInstruction(new(zone()) HAllocate( |
| 7066 environment()->LookupContext(), heap_number_size, |
| 7067 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
| 7068 BuildStoreMap(double_box, isolate()->factory()->heap_number_map()); |
| 7069 AddInstruction(new(zone()) HStoreNamedField( |
| 7070 double_box, name, value, true, |
| 7071 Representation::Double(), HeapNumber::kValueOffset)); |
| 7072 value = double_box; |
| 7073 representation = Representation::Tagged(); |
| 7074 } else { |
| 7075 HInstruction* double_box = AddInstruction(new(zone()) HLoadNamedField( |
| 7076 object, is_in_object, Representation::Tagged(), offset)); |
| 7077 double_box->set_type(HType::HeapNumber()); |
| 7078 return new(zone()) HStoreNamedField( |
| 7079 double_box, name, value, true, |
| 7080 Representation::Double(), HeapNumber::kValueOffset); |
| 7081 } |
| 7082 } |
7050 HStoreNamedField* instr = new(zone()) HStoreNamedField( | 7083 HStoreNamedField* instr = new(zone()) HStoreNamedField( |
7051 object, name, value, is_in_object, representation, offset); | 7084 object, name, value, is_in_object, representation, offset); |
7052 if (lookup->IsTransitionToField(*map)) { | 7085 if (transition_to_field) { |
7053 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 7086 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
7054 instr->set_transition(transition); | 7087 instr->set_transition(transition); |
7055 // TODO(fschneider): Record the new map type of the object in the IR to | 7088 // TODO(fschneider): Record the new map type of the object in the IR to |
7056 // enable elimination of redundant checks after the transition store. | 7089 // enable elimination of redundant checks after the transition store. |
7057 instr->SetGVNFlag(kChangesMaps); | 7090 instr->SetGVNFlag(kChangesMaps); |
7058 } | 7091 } |
7059 return instr; | 7092 return instr; |
7060 } | 7093 } |
7061 | 7094 |
7062 | 7095 |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7757 : index * kPointerSize + FixedArray::kHeaderSize; | 7790 : index * kPointerSize + FixedArray::kHeaderSize; |
7758 return DoBuildLoadNamedField(object, inobject, representation, offset); | 7791 return DoBuildLoadNamedField(object, inobject, representation, offset); |
7759 } | 7792 } |
7760 | 7793 |
7761 | 7794 |
7762 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( | 7795 HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( |
7763 HValue* object, | 7796 HValue* object, |
7764 bool inobject, | 7797 bool inobject, |
7765 Representation representation, | 7798 Representation representation, |
7766 int offset) { | 7799 int offset) { |
7767 return new(zone()) HLoadNamedField(object, inobject, representation, offset); | 7800 bool load_double = false; |
| 7801 if (representation.IsDouble()) { |
| 7802 representation = Representation::Tagged(); |
| 7803 load_double = FLAG_track_double_fields; |
| 7804 } |
| 7805 HLoadNamedField* field = |
| 7806 new(zone()) HLoadNamedField(object, inobject, representation, offset); |
| 7807 if (load_double) { |
| 7808 AddInstruction(field); |
| 7809 field->set_type(HType::HeapNumber()); |
| 7810 return new(zone()) HLoadNamedField( |
| 7811 field, true, Representation::Double(), HeapNumber::kValueOffset); |
| 7812 } |
| 7813 return field; |
7768 } | 7814 } |
7769 | 7815 |
7770 | 7816 |
7771 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7817 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
7772 HValue* object, | 7818 HValue* object, |
7773 Handle<String> name, | 7819 Handle<String> name, |
7774 Property* expr) { | 7820 Property* expr) { |
7775 if (expr->IsUninitialized()) { | 7821 if (expr->IsUninitialized()) { |
7776 AddSoftDeoptimize(); | 7822 AddSoftDeoptimize(); |
7777 } | 7823 } |
(...skipping 2981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10759 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 10805 ElementsKind kind = boilerplate_object->map()->elements_kind(); |
10760 | 10806 |
10761 // Increase the offset so that subsequent objects end up right after | 10807 // Increase the offset so that subsequent objects end up right after |
10762 // this object and its backing store. | 10808 // this object and its backing store. |
10763 int object_offset = *offset; | 10809 int object_offset = *offset; |
10764 int object_size = boilerplate_object->map()->instance_size(); | 10810 int object_size = boilerplate_object->map()->instance_size(); |
10765 int elements_size = (elements->length() > 0 && | 10811 int elements_size = (elements->length() > 0 && |
10766 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 10812 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
10767 elements->Size() : 0; | 10813 elements->Size() : 0; |
10768 int elements_offset = *offset + object_size; | 10814 int elements_offset = *offset + object_size; |
10769 int inobject_properties = boilerplate_object->map()->inobject_properties(); | |
10770 if (create_allocation_site_info) { | 10815 if (create_allocation_site_info) { |
10771 elements_offset += AllocationSiteInfo::kSize; | 10816 elements_offset += AllocationSiteInfo::kSize; |
10772 *offset += AllocationSiteInfo::kSize; | 10817 *offset += AllocationSiteInfo::kSize; |
10773 } | 10818 } |
10774 | 10819 |
10775 *offset += object_size + elements_size; | 10820 *offset += object_size + elements_size; |
10776 | 10821 |
10777 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target, | 10822 HValue* object_elements = BuildCopyObjectHeader(boilerplate_object, target, |
10778 object_offset, elements_offset, elements_size); | 10823 object_offset, elements_offset, elements_size); |
10779 | 10824 |
10780 // Copy in-object properties. | 10825 // Copy in-object properties. |
10781 HValue* object_properties = | 10826 HValue* object_properties = |
10782 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); | 10827 AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
10783 for (int i = 0; i < inobject_properties; i++) { | 10828 |
| 10829 Handle<DescriptorArray> descriptors( |
| 10830 boilerplate_object->map()->instance_descriptors()); |
| 10831 int limit = boilerplate_object->map()->NumberOfOwnDescriptors(); |
| 10832 |
| 10833 for (int i = 0; i < limit; i++) { |
| 10834 PropertyDetails details = descriptors->GetDetails(i); |
| 10835 if (details.type() != FIELD) continue; |
| 10836 int index = descriptors->GetFieldIndex(i); |
| 10837 int property_offset = boilerplate_object->GetInObjectPropertyOffset(index); |
| 10838 Handle<Name> name(descriptors->GetKey(i)); |
10784 Handle<Object> value = | 10839 Handle<Object> value = |
10785 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), | 10840 Handle<Object>(boilerplate_object->InObjectPropertyAt(index), |
10786 isolate()); | 10841 isolate()); |
10787 if (value->IsJSObject()) { | 10842 if (value->IsJSObject()) { |
10788 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10843 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10789 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10844 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10790 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), | 10845 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(index), |
10791 isolate())); | 10846 isolate())); |
10792 HInstruction* value_instruction = | 10847 HInstruction* value_instruction = |
10793 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10848 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10794 // TODO(verwaest): choose correct storage. | |
10795 AddInstruction(new(zone) HStoreNamedField( | 10849 AddInstruction(new(zone) HStoreNamedField( |
10796 object_properties, factory->unknown_field_string(), value_instruction, | 10850 object_properties, name, value_instruction, true, |
10797 true, Representation::Tagged(), | 10851 Representation::Tagged(), property_offset)); |
10798 boilerplate_object->GetInObjectPropertyOffset(i))); | |
10799 BuildEmitDeepCopy(value_object, original_value_object, target, | 10852 BuildEmitDeepCopy(value_object, original_value_object, target, |
10800 offset, DONT_TRACK_ALLOCATION_SITE); | 10853 offset, DONT_TRACK_ALLOCATION_SITE); |
10801 } else { | 10854 } else { |
10802 // TODO(verwaest): choose correct storage. | 10855 Representation representation = details.representation(); |
10803 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10856 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
10804 value, Representation::Tagged())); | 10857 value, Representation::Tagged())); |
| 10858 if (representation.IsDouble()) { |
| 10859 HInstruction* double_box = |
| 10860 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
| 10861 BuildStoreMap(double_box, factory->heap_number_map()); |
| 10862 AddInstruction(new(zone) HStoreNamedField( |
| 10863 double_box, name, value_instruction, true, |
| 10864 Representation::Double(), HeapNumber::kValueOffset)); |
| 10865 value_instruction = double_box; |
| 10866 *offset += HeapNumber::kSize; |
| 10867 } |
10805 AddInstruction(new(zone) HStoreNamedField( | 10868 AddInstruction(new(zone) HStoreNamedField( |
10806 object_properties, factory->unknown_field_string(), value_instruction, | 10869 object_properties, name, value_instruction, true, |
10807 true, Representation::Tagged(), | 10870 Representation::Tagged(), property_offset)); |
10808 boilerplate_object->GetInObjectPropertyOffset(i))); | |
10809 } | 10871 } |
10810 } | 10872 } |
10811 | 10873 |
10812 // Build Allocation Site Info if desired | 10874 // Build Allocation Site Info if desired |
10813 if (create_allocation_site_info) { | 10875 if (create_allocation_site_info) { |
10814 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); | 10876 BuildCreateAllocationSiteInfo(target, JSArray::kSize, original_boilerplate); |
10815 } | 10877 } |
10816 | 10878 |
10817 if (object_elements != NULL) { | 10879 if (object_elements != NULL) { |
10818 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10880 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
(...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12291 } | 12353 } |
12292 } | 12354 } |
12293 | 12355 |
12294 #ifdef DEBUG | 12356 #ifdef DEBUG |
12295 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12357 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12296 if (allocator_ != NULL) allocator_->Verify(); | 12358 if (allocator_ != NULL) allocator_->Verify(); |
12297 #endif | 12359 #endif |
12298 } | 12360 } |
12299 | 12361 |
12300 } } // namespace v8::internal | 12362 } } // namespace v8::internal |
OLD | NEW |