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 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |