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

Side by Side Diff: src/hydrogen.cc

Issue 18503006: Move representation into HObjectAccess and remove from HLoadNamedField and HStoreNamedField. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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
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 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 capacity_checker.Else(); 1152 capacity_checker.Else();
1153 1153
1154 environment()->Push(elements); 1154 environment()->Push(elements);
1155 capacity_checker.End(); 1155 capacity_checker.End();
1156 1156
1157 if (is_js_array) { 1157 if (is_js_array) {
1158 HValue* new_length = AddInstruction( 1158 HValue* new_length = AddInstruction(
1159 HAdd::New(zone, context, length, graph_->GetConstant1())); 1159 HAdd::New(zone, context, length, graph_->GetConstant1()));
1160 new_length->ClearFlag(HValue::kCanOverflow); 1160 new_length->ClearFlag(HValue::kCanOverflow);
1161 1161
1162 Representation representation = IsFastElementsKind(kind) 1162 AddStore(object, HObjectAccess::ForArrayLength(IsFastElementsKind(kind)),
1163 ? Representation::Smi() : Representation::Tagged(); 1163 new_length);
1164 AddStore(object, HObjectAccess::ForArrayLength(), new_length,
1165 representation);
1166 } 1164 }
1167 1165
1168 length_checker.Else(); 1166 length_checker.Else();
1169 1167
1170 Add<HBoundsCheck>(key, length); 1168 Add<HBoundsCheck>(key, length);
1171 environment()->Push(elements); 1169 environment()->Push(elements);
1172 1170
1173 length_checker.End(); 1171 length_checker.End();
1174 1172
1175 return environment()->Pop(); 1173 return environment()->Pop();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 HValue* elements = AddLoadElements(object, mapcheck); 1232 HValue* elements = AddLoadElements(object, mapcheck);
1235 if (is_store && (fast_elements || fast_smi_only_elements) && 1233 if (is_store && (fast_elements || fast_smi_only_elements) &&
1236 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 1234 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
1237 HCheckMaps* check_cow_map = HCheckMaps::New( 1235 HCheckMaps* check_cow_map = HCheckMaps::New(
1238 elements, isolate()->factory()->fixed_array_map(), zone); 1236 elements, isolate()->factory()->fixed_array_map(), zone);
1239 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1237 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1240 AddInstruction(check_cow_map); 1238 AddInstruction(check_cow_map);
1241 } 1239 }
1242 HInstruction* length = NULL; 1240 HInstruction* length = NULL;
1243 if (is_js_array) { 1241 if (is_js_array) {
1244 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, 1242 length = AddLoad(object, HObjectAccess::ForArrayLength(true), mapcheck);
1245 Representation::Smi());
1246 } else { 1243 } else {
1247 length = AddLoadFixedArrayLength(elements); 1244 length = AddLoadFixedArrayLength(elements);
1248 } 1245 }
1249 length->set_type(HType::Smi()); 1246 length->set_type(HType::Smi());
1250 HValue* checked_key = NULL; 1247 HValue* checked_key = NULL;
1251 if (IsExternalArrayElementsKind(elements_kind)) { 1248 if (IsExternalArrayElementsKind(elements_kind)) {
1252 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 1249 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
1253 NoObservableSideEffectsScope no_effects(this); 1250 NoObservableSideEffectsScope no_effects(this);
1254 HLoadExternalArrayPointer* external_elements = 1251 HLoadExternalArrayPointer* external_elements =
1255 Add<HLoadExternalArrayPointer>(elements); 1252 Add<HLoadExternalArrayPointer>(elements);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 1350
1354 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 1351 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
1355 ElementsKind kind, 1352 ElementsKind kind,
1356 HValue* capacity) { 1353 HValue* capacity) {
1357 Factory* factory = isolate()->factory(); 1354 Factory* factory = isolate()->factory();
1358 Handle<Map> map = IsFastDoubleElementsKind(kind) 1355 Handle<Map> map = IsFastDoubleElementsKind(kind)
1359 ? factory->fixed_double_array_map() 1356 ? factory->fixed_double_array_map()
1360 : factory->fixed_array_map(); 1357 : factory->fixed_array_map();
1361 1358
1362 AddStoreMapConstant(elements, map); 1359 AddStoreMapConstant(elements, map);
1363 Representation representation = IsFastElementsKind(kind) 1360 AddStore(elements,
1364 ? Representation::Smi() : Representation::Tagged(); 1361 HObjectAccess::ForFixedArrayLength(IsFastElementsKind(kind)), capacity);
danno 2013/07/08 11:12:25 This is always Smi()
1365 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
1366 representation);
1367 } 1362 }
1368 1363
1369 1364
1370 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( 1365 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
1371 HValue* context, 1366 HValue* context,
1372 ElementsKind kind, 1367 ElementsKind kind,
1373 HValue* capacity) { 1368 HValue* capacity) {
1374 HValue* new_elements = BuildAllocateElements(context, kind, capacity); 1369 HValue* new_elements = BuildAllocateElements(context, kind, capacity);
1375 BuildInitializeElementsHeader(new_elements, kind, capacity); 1370 BuildInitializeElementsHeader(new_elements, kind, capacity);
1376 return new_elements; 1371 return new_elements;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 } 1405 }
1411 1406
1412 1407
1413 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1408 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1414 HValue* typecheck) { 1409 HValue* typecheck) {
1415 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1410 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1416 } 1411 }
1417 1412
1418 1413
1419 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1414 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1420 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(), 1415 return AddLoad(object, HObjectAccess::ForFixedArrayLength(true));
1421 NULL, Representation::Smi());
1422 instr->set_type(HType::Smi());
1423 return instr;
1424 } 1416 }
1425 1417
1426 1418
1427 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, 1419 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context,
1428 HValue* old_capacity) { 1420 HValue* old_capacity) {
1429 Zone* zone = this->zone(); 1421 Zone* zone = this->zone();
1430 HValue* half_old_capacity = 1422 HValue* half_old_capacity =
1431 AddInstruction(HShr::New(zone, context, old_capacity, 1423 AddInstruction(HShr::New(zone, context, old_capacity,
1432 graph_->GetConstant1())); 1424 graph_->GetConstant1()));
1433 half_old_capacity->ClearFlag(HValue::kCanOverflow); 1425 half_old_capacity->ClearFlag(HValue::kCanOverflow);
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 allocation_site_payload_(NULL), 1739 allocation_site_payload_(NULL),
1748 constructor_function_(constructor_function) { 1740 constructor_function_(constructor_function) {
1749 } 1741 }
1750 1742
1751 1743
1752 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { 1744 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
1753 if (kind_ == GetInitialFastElementsKind()) { 1745 if (kind_ == GetInitialFastElementsKind()) {
1754 // No need for a context lookup if the kind_ matches the initial 1746 // No need for a context lookup if the kind_ matches the initial
1755 // map, because we can just load the map in that case. 1747 // map, because we can just load the map in that case.
1756 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1748 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1757 HInstruction* load = 1749 return builder()->AddInstruction(
1758 builder()->BuildLoadNamedField(constructor_function_, 1750 builder()->BuildLoadNamedField(constructor_function_, access));
1759 access,
1760 Representation::Tagged());
1761 return builder()->AddInstruction(load);
1762 } 1751 }
1763 1752
1764 HInstruction* native_context = builder()->BuildGetNativeContext(context); 1753 HInstruction* native_context = builder()->BuildGetNativeContext(context);
1765 HInstruction* index = builder()->Add<HConstant>( 1754 HInstruction* index = builder()->Add<HConstant>(
1766 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1755 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1767 1756
1768 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1757 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1769 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1758 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1770 1759
1771 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1760 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1772 1761
1773 return builder()->Add<HLoadKeyed>( 1762 return builder()->Add<HLoadKeyed>(
1774 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1763 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1775 } 1764 }
1776 1765
1777 1766
1778 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1767 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1779 // Find the map near the constructor function 1768 // Find the map near the constructor function
1780 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1769 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1781 return builder()->AddInstruction( 1770 return builder()->AddInstruction(
1782 builder()->BuildLoadNamedField(constructor_function_, 1771 builder()->BuildLoadNamedField(constructor_function_, access));
1783 access,
1784 Representation::Tagged()));
1785 } 1772 }
1786 1773
1787 1774
1788 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1775 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1789 HValue* length_node) { 1776 HValue* length_node) {
1790 HValue* context = builder()->environment()->LookupContext(); 1777 HValue* context = builder()->environment()->LookupContext();
1791 ASSERT(length_node != NULL); 1778 ASSERT(length_node != NULL);
1792 1779
1793 int base_size = JSArray::kSize; 1780 int base_size = JSArray::kSize;
1794 if (mode_ == TRACK_ALLOCATION_SITE) { 1781 if (mode_ == TRACK_ALLOCATION_SITE) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, 1866 builder()->BuildFillElementsWithHole(context, elements_location_, kind_,
1880 graph()->GetConstant0(), capacity); 1867 graph()->GetConstant0(), capacity);
1881 } 1868 }
1882 1869
1883 return new_object; 1870 return new_object;
1884 } 1871 }
1885 1872
1886 1873
1887 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, 1874 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
1888 HObjectAccess access, 1875 HObjectAccess access,
1889 HValue *val, 1876 HValue *val) {
1890 Representation representation) { 1877 return Add<HStoreNamedField>(object, access, val);
1891 return Add<HStoreNamedField>(object, access, val, representation);
1892 } 1878 }
1893 1879
1894 1880
1895 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, 1881 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
1896 HObjectAccess access, 1882 HObjectAccess access,
1897 HValue *typecheck, 1883 HValue *typecheck) {
1898 Representation representation) { 1884 return Add<HLoadNamedField>(object, access, typecheck);
1899 return Add<HLoadNamedField>(object, access, typecheck, representation);
1900 } 1885 }
1901 1886
1902 1887
1903 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, 1888 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object,
1904 Handle<Map> map) { 1889 Handle<Map> map) {
1905 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), 1890 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
1906 Add<HConstant>(map)); 1891 Add<HConstant>(map));
1907 } 1892 }
1908 1893
1909 1894
(...skipping 3776 matching lines...) Expand 10 before | Expand all | Expand 10 after
5686 if (!is_store) return false; 5671 if (!is_store) return false;
5687 5672
5688 // 2nd chance: A store into a non-existent field can still be inlined if we 5673 // 2nd chance: A store into a non-existent field can still be inlined if we
5689 // have a matching transition and some room left in the object. 5674 // have a matching transition and some room left in the object.
5690 type->LookupTransition(NULL, *name, lookup); 5675 type->LookupTransition(NULL, *name, lookup);
5691 return lookup->IsTransitionToField(*type) && 5676 return lookup->IsTransitionToField(*type) &&
5692 (type->unused_property_fields() > 0); 5677 (type->unused_property_fields() > 0);
5693 } 5678 }
5694 5679
5695 5680
5696 static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
5697 LookupResult* lookup) {
5698 if (lookup->IsField()) {
5699 return lookup->representation();
5700 } else {
5701 Map* transition = lookup->GetTransitionMapFromMap(*type);
5702 int descriptor = transition->LastAdded();
5703 PropertyDetails details =
5704 transition->instance_descriptors()->GetDetails(descriptor);
5705 return details.representation();
5706 }
5707 }
5708
5709
5710 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 5681 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
5711 BuildCheckHeapObject(object); 5682 BuildCheckHeapObject(object);
5712 AddInstruction(HCheckMaps::New(object, map, zone())); 5683 AddInstruction(HCheckMaps::New(object, map, zone()));
5713 } 5684 }
5714 5685
5715 5686
5716 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, 5687 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object,
5717 Handle<Map> map) { 5688 Handle<Map> map) {
5718 BuildCheckHeapObject(object); 5689 BuildCheckHeapObject(object);
5719 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); 5690 AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone()));
(...skipping 30 matching lines...) Expand all
5750 } 5721 }
5751 ASSERT(proto->GetPrototype(isolate())->IsNull()); 5722 ASSERT(proto->GetPrototype(isolate())->IsNull());
5752 } 5723 }
5753 ASSERT(proto->IsJSObject()); 5724 ASSERT(proto->IsJSObject());
5754 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), 5725 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())),
5755 Handle<JSObject>(JSObject::cast(proto)), 5726 Handle<JSObject>(JSObject::cast(proto)),
5756 zone(), top_info()); 5727 zone(), top_info());
5757 } 5728 }
5758 5729
5759 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); 5730 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
5760 Representation representation = ComputeLoadStoreRepresentation(map, lookup);
5761 bool transition_to_field = lookup->IsTransitionToField(*map); 5731 bool transition_to_field = lookup->IsTransitionToField(*map);
5762 5732
5763 HStoreNamedField *instr; 5733 HStoreNamedField *instr;
5764 if (FLAG_track_double_fields && representation.IsDouble()) { 5734 if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
5735 HObjectAccess heap_number_access =
5736 field_access.WithRepresentation(Representation::Tagged());
5765 if (transition_to_field) { 5737 if (transition_to_field) {
5766 // The store requires a mutable HeapNumber to be allocated. 5738 // The store requires a mutable HeapNumber to be allocated.
5767 NoObservableSideEffectsScope no_side_effects(this); 5739 NoObservableSideEffectsScope no_side_effects(this);
5768 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); 5740 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
5769 HInstruction* double_box = Add<HAllocate>( 5741 HInstruction* heap_number = Add<HAllocate>(
5770 environment()->LookupContext(), heap_number_size, 5742 environment()->LookupContext(), heap_number_size,
5771 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); 5743 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
5772 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); 5744 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
5773 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 5745 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value);
5774 value, Representation::Double()); 5746 instr = new(zone()) HStoreNamedField(
5775 instr = new(zone()) HStoreNamedField(object, field_access, double_box); 5747 object, heap_number_access, heap_number);
5776 } else { 5748 } else {
5777 // Already holds a HeapNumber; load the box and write its value field. 5749 // Already holds a HeapNumber; load the box and write its value field.
5778 HInstruction* double_box = AddLoad(object, field_access); 5750 HInstruction* heap_number = AddLoad(object, heap_number_access);
5779 double_box->set_type(HType::HeapNumber()); 5751 heap_number->set_type(HType::HeapNumber());
5780 instr = new(zone()) HStoreNamedField(double_box, 5752 instr = new(zone()) HStoreNamedField(heap_number,
5781 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); 5753 HObjectAccess::ForHeapNumberValue(), value);
5782 } 5754 }
5783 } else { 5755 } else {
5784 // This is a non-double store. 5756 // This is a normal store.
5785 instr = new(zone()) HStoreNamedField( 5757 instr = new(zone()) HStoreNamedField(object, field_access, value);
5786 object, field_access, value, representation);
5787 } 5758 }
5788 5759
5789 if (transition_to_field) { 5760 if (transition_to_field) {
5790 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); 5761 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map));
5791 instr->SetTransition(transition, top_info()); 5762 instr->SetTransition(transition, top_info());
5792 // TODO(fschneider): Record the new map type of the object in the IR to 5763 // TODO(fschneider): Record the new map type of the object in the IR to
5793 // enable elimination of redundant checks after the transition store. 5764 // enable elimination of redundant checks after the transition store.
5794 instr->SetGVNFlag(kChangesMaps); 5765 instr->SetGVNFlag(kChangesMaps);
5795 } 5766 }
5796 return instr; 5767 return instr;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
5845 Property* expr, 5816 Property* expr,
5846 HValue* object, 5817 HValue* object,
5847 SmallMapList* types, 5818 SmallMapList* types,
5848 Handle<String> name) { 5819 Handle<String> name) {
5849 // Use monomorphic load if property lookup results in the same field index 5820 // Use monomorphic load if property lookup results in the same field index
5850 // for all maps. Requires special map check on the set of all handled maps. 5821 // for all maps. Requires special map check on the set of all handled maps.
5851 if (types->length() > kMaxLoadPolymorphism) return NULL; 5822 if (types->length() > kMaxLoadPolymorphism) return NULL;
5852 5823
5853 LookupResult lookup(isolate()); 5824 LookupResult lookup(isolate());
5854 int count; 5825 int count;
5855 Representation representation = Representation::None();
5856 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 5826 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
5857 for (count = 0; count < types->length(); ++count) { 5827 for (count = 0; count < types->length(); ++count) {
5858 Handle<Map> map = types->at(count); 5828 Handle<Map> map = types->at(count);
5859 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 5829 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
5860 5830
5861 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 5831 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
5862 Representation new_representation =
5863 ComputeLoadStoreRepresentation(map, &lookup);
5864 5832
5865 if (count == 0) { 5833 if (count == 0) {
5866 // First time through the loop; set access and representation. 5834 // First time through the loop; set access and representation.
5867 access = new_access; 5835 access = new_access;
5868 } else if (!representation.IsCompatibleForLoad(new_representation)) { 5836 } else if (!access.representation().IsCompatibleForLoad(
5837 new_access.representation())) {
5869 // Representations did not match. 5838 // Representations did not match.
5870 break; 5839 break;
5871 } else if (access.offset() != new_access.offset()) { 5840 } else if (access.offset() != new_access.offset()) {
5872 // Offsets did not match. 5841 // Offsets did not match.
5873 break; 5842 break;
5874 } else if (access.IsInobject() != new_access.IsInobject()) { 5843 } else if (access.IsInobject() != new_access.IsInobject()) {
5875 // In-objectness did not match. 5844 // In-objectness did not match.
5876 break; 5845 break;
5877 } 5846 }
5878 representation = representation.generalize(new_representation); 5847 access = access.WithRepresentation(
5848 access.representation().generalize(new_access.representation()));
5879 } 5849 }
5880 5850
5881 if (count != types->length()) return NULL; 5851 if (count != types->length()) return NULL;
5882 5852
5883 // Everything matched; can use monomorphic load. 5853 // Everything matched; can use monomorphic load.
5884 BuildCheckHeapObject(object); 5854 BuildCheckHeapObject(object);
5885 AddInstruction(HCheckMaps::New(object, types, zone())); 5855 AddInstruction(HCheckMaps::New(object, types, zone()));
5886 return BuildLoadNamedField(object, access, representation); 5856 return BuildLoadNamedField(object, access);
5887 } 5857 }
5888 5858
5889 5859
5890 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( 5860 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(
5891 Property* expr, 5861 Property* expr,
5892 HValue* object, 5862 HValue* object,
5893 SmallMapList* types, 5863 SmallMapList* types,
5894 Handle<String> name) { 5864 Handle<String> name) {
5895 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( 5865 HInstruction* instr = TryLoadPolymorphicAsMonomorphic(
5896 expr, object, types, name); 5866 expr, object, types, name);
(...skipping 26 matching lines...) Expand all
5923 LookupResult lookup(isolate()); 5893 LookupResult lookup(isolate());
5924 int count; 5894 int count;
5925 Representation representation = Representation::None(); 5895 Representation representation = Representation::None();
5926 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. 5896 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused.
5927 for (count = 0; count < types->length(); ++count) { 5897 for (count = 0; count < types->length(); ++count) {
5928 Handle<Map> map = types->at(count); 5898 Handle<Map> map = types->at(count);
5929 // Pass false to ignore transitions. 5899 // Pass false to ignore transitions.
5930 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; 5900 if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
5931 5901
5932 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); 5902 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
5933 Representation new_representation = 5903 Representation new_representation = new_access.representation();
5934 ComputeLoadStoreRepresentation(map, &lookup);
5935 5904
5936 if (count == 0) { 5905 if (count == 0) {
5937 // First time through the loop; set access and representation. 5906 // First time through the loop; set access and representation.
5938 access = new_access; 5907 access = new_access;
5939 representation = new_representation; 5908 representation = new_representation;
5940 } else if (!representation.IsCompatibleForStore(new_representation)) { 5909 } else if (!representation.IsCompatibleForStore(new_representation)) {
5941 // Representations did not match. 5910 // Representations did not match.
5942 break; 5911 break;
5943 } else if (access.offset() != new_access.offset()) { 5912 } else if (access.offset() != new_access.offset()) {
5944 // Offsets did not match. 5913 // Offsets did not match.
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
6493 HValue* context = environment()->LookupContext(); 6462 HValue* context = environment()->LookupContext();
6494 HValue* value = environment()->Pop(); 6463 HValue* value = environment()->Pop();
6495 HThrow* instr = Add<HThrow>(context, value); 6464 HThrow* instr = Add<HThrow>(context, value);
6496 instr->set_position(expr->position()); 6465 instr->set_position(expr->position());
6497 AddSimulate(expr->id()); 6466 AddSimulate(expr->id());
6498 current_block()->FinishExit(new(zone()) HAbnormalExit); 6467 current_block()->FinishExit(new(zone()) HAbnormalExit);
6499 set_current_block(NULL); 6468 set_current_block(NULL);
6500 } 6469 }
6501 6470
6502 6471
6503 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( 6472 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
6504 HValue* object, 6473 HObjectAccess access) {
6505 HObjectAccess access, 6474 if (FLAG_track_double_fields && access.representation().IsDouble()) {
6506 Representation representation) { 6475 // load the heap number
6507 bool load_double = false; 6476 HLoadNamedField* heap_number =
6508 if (representation.IsDouble()) { 6477 AddLoad(object, access.WithRepresentation(Representation::Tagged()));
6509 representation = Representation::Tagged(); 6478 heap_number->set_type(HType::HeapNumber());
6510 load_double = FLAG_track_double_fields; 6479 // load the double value from it
6480 return new(zone()) HLoadNamedField(heap_number,
6481 HObjectAccess::ForHeapNumberValue(), NULL);
6511 } 6482 }
6512 HLoadNamedField* field = 6483 return new(zone()) HLoadNamedField(object, access, NULL);
6513 new(zone()) HLoadNamedField(object, access, NULL, representation);
6514 if (load_double) {
6515 AddInstruction(field);
6516 field->set_type(HType::HeapNumber());
6517 return new(zone()) HLoadNamedField(field,
6518 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double());
6519 }
6520 return field;
6521 } 6484 }
6522 6485
6523 6486
6524 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( 6487 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric(
6525 HValue* object, 6488 HValue* object,
6526 Handle<String> name, 6489 Handle<String> name,
6527 Property* expr) { 6490 Property* expr) {
6528 if (expr->IsUninitialized()) { 6491 if (expr->IsUninitialized()) {
6529 AddSoftDeoptimize(); 6492 AddSoftDeoptimize();
6530 } 6493 }
(...skipping 28 matching lines...) Expand all
6559 return new(zone()) HLoadNamedField(object, 6522 return new(zone()) HLoadNamedField(object,
6560 HObjectAccess::ForArrayLength()); 6523 HObjectAccess::ForArrayLength());
6561 } 6524 }
6562 } 6525 }
6563 6526
6564 LookupResult lookup(isolate()); 6527 LookupResult lookup(isolate());
6565 map->LookupDescriptor(NULL, *name, &lookup); 6528 map->LookupDescriptor(NULL, *name, &lookup);
6566 if (lookup.IsField()) { 6529 if (lookup.IsField()) {
6567 AddCheckMap(object, map); 6530 AddCheckMap(object, map);
6568 return BuildLoadNamedField(object, 6531 return BuildLoadNamedField(object,
6569 HObjectAccess::ForField(map, &lookup, name), 6532 HObjectAccess::ForField(map, &lookup, name));
6570 ComputeLoadStoreRepresentation(map, &lookup));
6571 } 6533 }
6572 6534
6573 // Handle a load of a constant known function. 6535 // Handle a load of a constant known function.
6574 if (lookup.IsConstantFunction()) { 6536 if (lookup.IsConstantFunction()) {
6575 AddCheckMap(object, map); 6537 AddCheckMap(object, map);
6576 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); 6538 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map));
6577 return new(zone()) HConstant(function); 6539 return new(zone()) HConstant(function);
6578 } 6540 }
6579 6541
6580 // Handle a load from a known field somewhere in the prototype chain. 6542 // Handle a load from a known field somewhere in the prototype chain.
6581 LookupInPrototypes(map, name, &lookup); 6543 LookupInPrototypes(map, name, &lookup);
6582 if (lookup.IsField()) { 6544 if (lookup.IsField()) {
6583 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6545 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6584 Handle<JSObject> holder(lookup.holder()); 6546 Handle<JSObject> holder(lookup.holder());
6585 Handle<Map> holder_map(holder->map()); 6547 Handle<Map> holder_map(holder->map());
6586 AddCheckMap(object, map); 6548 AddCheckMap(object, map);
6587 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 6549 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
6588 HValue* holder_value = Add<HConstant>(holder); 6550 HValue* holder_value = Add<HConstant>(holder);
6589 return BuildLoadNamedField(holder_value, 6551 return BuildLoadNamedField(holder_value,
6590 HObjectAccess::ForField(holder_map, &lookup, name), 6552 HObjectAccess::ForField(holder_map, &lookup, name));
6591 ComputeLoadStoreRepresentation(map, &lookup));
6592 } 6553 }
6593 6554
6594 // Handle a load of a constant function somewhere in the prototype chain. 6555 // Handle a load of a constant function somewhere in the prototype chain.
6595 if (lookup.IsConstantFunction()) { 6556 if (lookup.IsConstantFunction()) {
6596 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6557 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6597 Handle<JSObject> holder(lookup.holder()); 6558 Handle<JSObject> holder(lookup.holder());
6598 Handle<Map> holder_map(holder->map()); 6559 Handle<Map> holder_map(holder->map());
6599 AddCheckMap(object, map); 6560 AddCheckMap(object, map);
6600 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); 6561 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
6601 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); 6562 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map));
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
6853 // it's a keyed property) and registered in the full codegen. 6814 // it's a keyed property) and registered in the full codegen.
6854 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); 6815 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
6855 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); 6816 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
6856 HHasInstanceTypeAndBranch* typecheck = 6817 HHasInstanceTypeAndBranch* typecheck =
6857 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); 6818 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
6858 typecheck->SetSuccessorAt(0, if_jsarray); 6819 typecheck->SetSuccessorAt(0, if_jsarray);
6859 typecheck->SetSuccessorAt(1, if_fastobject); 6820 typecheck->SetSuccessorAt(1, if_fastobject);
6860 current_block()->Finish(typecheck); 6821 current_block()->Finish(typecheck);
6861 6822
6862 set_current_block(if_jsarray); 6823 set_current_block(if_jsarray);
6863 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), 6824 HInstruction* length = AddLoad(object,
6864 typecheck, Representation::Smi()); 6825 HObjectAccess::ForArrayLength(true), typecheck);
6865 length->set_type(HType::Smi()); 6826 length->set_type(HType::Smi());
6866 6827
6867 checked_key = Add<HBoundsCheck>(key, length); 6828 checked_key = Add<HBoundsCheck>(key, length);
6868 access = AddInstruction(BuildFastElementAccess( 6829 access = AddInstruction(BuildFastElementAccess(
6869 elements, checked_key, val, elements_kind_branch, 6830 elements, checked_key, val, elements_kind_branch,
6870 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); 6831 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
6871 if (!is_store) { 6832 if (!is_store) {
6872 Push(access); 6833 Push(access);
6873 } 6834 }
6874 6835
(...skipping 2704 matching lines...) Expand 10 before | Expand all | Expand 10 after
9579 AddStore(object_header, access, properties); 9540 AddStore(object_header, access, properties);
9580 9541
9581 if (boilerplate_object->IsJSArray()) { 9542 if (boilerplate_object->IsJSArray()) {
9582 Handle<JSArray> boilerplate_array = 9543 Handle<JSArray> boilerplate_array =
9583 Handle<JSArray>::cast(boilerplate_object); 9544 Handle<JSArray>::cast(boilerplate_object);
9584 Handle<Object> length_field = 9545 Handle<Object> length_field =
9585 Handle<Object>(boilerplate_array->length(), isolate()); 9546 Handle<Object>(boilerplate_array->length(), isolate());
9586 HInstruction* length = Add<HConstant>(length_field); 9547 HInstruction* length = Add<HConstant>(length_field);
9587 9548
9588 ASSERT(boilerplate_array->length()->IsSmi()); 9549 ASSERT(boilerplate_array->length()->IsSmi());
9589 Representation representation = 9550 AddStore(object_header, HObjectAccess::ForArrayLength(
9590 IsFastElementsKind(boilerplate_array->GetElementsKind()) 9551 IsFastElementsKind(boilerplate_array->GetElementsKind())),
9591 ? Representation::Smi() : Representation::Tagged(); 9552 length);
9592 AddStore(object_header, HObjectAccess::ForArrayLength(),
9593 length, representation);
9594 } 9553 }
9595 9554
9596 return result; 9555 return result;
9597 } 9556 }
9598 9557
9599 9558
9600 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( 9559 void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
9601 Handle<JSObject> boilerplate_object, 9560 Handle<JSObject> boilerplate_object,
9602 Handle<JSObject> original_boilerplate_object, 9561 Handle<JSObject> original_boilerplate_object,
9603 HValue* object_properties, 9562 HValue* object_properties,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
9648 if (data_target != NULL) { 9607 if (data_target != NULL) {
9649 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); 9608 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset);
9650 *data_offset += HeapNumber::kSize; 9609 *data_offset += HeapNumber::kSize;
9651 } else { 9610 } else {
9652 double_box = Add<HInnerAllocatedObject>(target, *offset); 9611 double_box = Add<HInnerAllocatedObject>(target, *offset);
9653 *offset += HeapNumber::kSize; 9612 *offset += HeapNumber::kSize;
9654 } 9613 }
9655 AddStoreMapConstant(double_box, 9614 AddStoreMapConstant(double_box,
9656 isolate()->factory()->heap_number_map()); 9615 isolate()->factory()->heap_number_map());
9657 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), 9616 AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
9658 value_instruction, Representation::Double()); 9617 value_instruction);
9659 value_instruction = double_box; 9618 value_instruction = double_box;
9660 } 9619 }
9661 9620
9662 AddStore(object_properties, access, value_instruction); 9621 AddStore(object_properties, access, value_instruction);
9663 } 9622 }
9664 } 9623 }
9665 9624
9666 int inobject_properties = boilerplate_object->map()->inobject_properties(); 9625 int inobject_properties = boilerplate_object->map()->inobject_properties();
9667 HInstruction* value_instruction = 9626 HInstruction* value_instruction =
9668 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 9627 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
(...skipping 1369 matching lines...) Expand 10 before | Expand all | Expand 10 after
11038 if (ShouldProduceTraceOutput()) { 10997 if (ShouldProduceTraceOutput()) {
11039 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10998 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11040 } 10999 }
11041 11000
11042 #ifdef DEBUG 11001 #ifdef DEBUG
11043 graph_->Verify(false); // No full verify. 11002 graph_->Verify(false); // No full verify.
11044 #endif 11003 #endif
11045 } 11004 }
11046 11005
11047 } } // namespace v8::internal 11006 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698