Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: src/hydrogen.cc

Issue 14850006: Use mutable heapnumbers to store doubles in fields. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Ported to ARM and x64 Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap-snapshot-generator.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698