OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1085 capacity_checker.Else(); | 1085 capacity_checker.Else(); |
1086 | 1086 |
1087 environment()->Push(elements); | 1087 environment()->Push(elements); |
1088 capacity_checker.End(); | 1088 capacity_checker.End(); |
1089 | 1089 |
1090 if (is_js_array) { | 1090 if (is_js_array) { |
1091 HValue* new_length = AddInstruction( | 1091 HValue* new_length = AddInstruction( |
1092 HAdd::New(zone, context, key, graph_->GetConstant1())); | 1092 HAdd::New(zone, context, key, graph_->GetConstant1())); |
1093 new_length->ClearFlag(HValue::kCanOverflow); | 1093 new_length->ClearFlag(HValue::kCanOverflow); |
1094 | 1094 |
1095 Representation representation = IsFastElementsKind(kind) | 1095 AddStore(object, HObjectAccess::ForArrayLength(kind), new_length); |
1096 ? Representation::Smi() : Representation::Tagged(); | |
1097 AddStore(object, HObjectAccess::ForArrayLength(), new_length, | |
1098 representation); | |
1099 } | 1096 } |
1100 | 1097 |
1101 length_checker.Else(); | 1098 length_checker.Else(); |
1102 Add<HBoundsCheck>(key, length); | 1099 Add<HBoundsCheck>(key, length); |
1103 | 1100 |
1104 environment()->Push(elements); | 1101 environment()->Push(elements); |
1105 length_checker.End(); | 1102 length_checker.End(); |
1106 | 1103 |
1107 return environment()->Pop(); | 1104 return environment()->Pop(); |
1108 } | 1105 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1156 | 1153 |
1157 IfBuilder if_builder(this); | 1154 IfBuilder if_builder(this); |
1158 | 1155 |
1159 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); | 1156 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); |
1160 | 1157 |
1161 if_builder.Then(); | 1158 if_builder.Then(); |
1162 | 1159 |
1163 HInstruction* elements_length = AddLoadFixedArrayLength(elements); | 1160 HInstruction* elements_length = AddLoadFixedArrayLength(elements); |
1164 | 1161 |
1165 HInstruction* array_length = is_jsarray | 1162 HInstruction* array_length = is_jsarray |
1166 ? AddLoad(object, HObjectAccess::ForArrayLength(), | 1163 ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL) |
1167 NULL, Representation::Smi()) | |
1168 : elements_length; | 1164 : elements_length; |
1169 array_length->set_type(HType::Smi()); | |
1170 | 1165 |
1171 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, | 1166 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, |
1172 array_length, elements_length); | 1167 array_length, elements_length); |
1173 | 1168 |
1174 if_builder.End(); | 1169 if_builder.End(); |
1175 } | 1170 } |
1176 | 1171 |
1177 AddStore(object, HObjectAccess::ForMap(), map); | 1172 AddStore(object, HObjectAccess::ForMap(), map); |
1178 } | 1173 } |
1179 | 1174 |
(...skipping 27 matching lines...) Expand all Loading... |
1207 HValue* elements = AddLoadElements(object, mapcheck); | 1202 HValue* elements = AddLoadElements(object, mapcheck); |
1208 if (is_store && (fast_elements || fast_smi_only_elements) && | 1203 if (is_store && (fast_elements || fast_smi_only_elements) && |
1209 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 1204 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
1210 HCheckMaps* check_cow_map = HCheckMaps::New( | 1205 HCheckMaps* check_cow_map = HCheckMaps::New( |
1211 elements, isolate()->factory()->fixed_array_map(), zone, top_info()); | 1206 elements, isolate()->factory()->fixed_array_map(), zone, top_info()); |
1212 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 1207 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
1213 AddInstruction(check_cow_map); | 1208 AddInstruction(check_cow_map); |
1214 } | 1209 } |
1215 HInstruction* length = NULL; | 1210 HInstruction* length = NULL; |
1216 if (is_js_array) { | 1211 if (is_js_array) { |
1217 length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck, | 1212 length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind), |
1218 Representation::Smi()); | 1213 mapcheck); |
1219 } else { | 1214 } else { |
1220 length = AddLoadFixedArrayLength(elements); | 1215 length = AddLoadFixedArrayLength(elements); |
1221 } | 1216 } |
1222 length->set_type(HType::Smi()); | 1217 length->set_type(HType::Smi()); |
1223 HValue* checked_key = NULL; | 1218 HValue* checked_key = NULL; |
1224 if (IsExternalArrayElementsKind(elements_kind)) { | 1219 if (IsExternalArrayElementsKind(elements_kind)) { |
1225 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 1220 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
1226 NoObservableSideEffectsScope no_effects(this); | 1221 NoObservableSideEffectsScope no_effects(this); |
1227 HLoadExternalArrayPointer* external_elements = | 1222 HLoadExternalArrayPointer* external_elements = |
1228 Add<HLoadExternalArrayPointer>(elements); | 1223 Add<HLoadExternalArrayPointer>(elements); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 | 1319 |
1325 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 1320 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
1326 ElementsKind kind, | 1321 ElementsKind kind, |
1327 HValue* capacity) { | 1322 HValue* capacity) { |
1328 Factory* factory = isolate()->factory(); | 1323 Factory* factory = isolate()->factory(); |
1329 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1324 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1330 ? factory->fixed_double_array_map() | 1325 ? factory->fixed_double_array_map() |
1331 : factory->fixed_array_map(); | 1326 : factory->fixed_array_map(); |
1332 | 1327 |
1333 AddStoreMapConstant(elements, map); | 1328 AddStoreMapConstant(elements, map); |
1334 Representation representation = IsFastElementsKind(kind) | 1329 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); |
1335 ? Representation::Smi() : Representation::Tagged(); | |
1336 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity, | |
1337 representation); | |
1338 } | 1330 } |
1339 | 1331 |
1340 | 1332 |
1341 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 1333 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
1342 HValue* context, | 1334 HValue* context, |
1343 ElementsKind kind, | 1335 ElementsKind kind, |
1344 HValue* capacity) { | 1336 HValue* capacity) { |
1345 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1337 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1346 BuildInitializeElementsHeader(new_elements, kind, capacity); | 1338 BuildInitializeElementsHeader(new_elements, kind, capacity); |
1347 return new_elements; | 1339 return new_elements; |
1348 } | 1340 } |
1349 | 1341 |
1350 | 1342 |
1351 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1343 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
1352 HValue* array_map, | 1344 HValue* array_map, |
1353 AllocationSiteMode mode, | 1345 AllocationSiteMode mode, |
| 1346 ElementsKind elements_kind, |
1354 HValue* allocation_site_payload, | 1347 HValue* allocation_site_payload, |
1355 HValue* length_field) { | 1348 HValue* length_field) { |
1356 | 1349 |
1357 AddStore(array, HObjectAccess::ForMap(), array_map); | 1350 AddStore(array, HObjectAccess::ForMap(), array_map); |
1358 | 1351 |
1359 HConstant* empty_fixed_array = | 1352 HConstant* empty_fixed_array = |
1360 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 1353 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
1361 | 1354 |
1362 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); | 1355 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); |
1363 AddStore(array, access, empty_fixed_array); | 1356 AddStore(array, access, empty_fixed_array); |
1364 AddStore(array, HObjectAccess::ForArrayLength(), length_field); | 1357 AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field); |
1365 | 1358 |
1366 if (mode == TRACK_ALLOCATION_SITE) { | 1359 if (mode == TRACK_ALLOCATION_SITE) { |
1367 BuildCreateAllocationMemento(array, | 1360 BuildCreateAllocationMemento(array, |
1368 JSArray::kSize, | 1361 JSArray::kSize, |
1369 allocation_site_payload); | 1362 allocation_site_payload); |
1370 } | 1363 } |
1371 | 1364 |
1372 int elements_location = JSArray::kSize; | 1365 int elements_location = JSArray::kSize; |
1373 if (mode == TRACK_ALLOCATION_SITE) { | 1366 if (mode == TRACK_ALLOCATION_SITE) { |
1374 elements_location += AllocationMemento::kSize; | 1367 elements_location += AllocationMemento::kSize; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 } | 1454 } |
1462 | 1455 |
1463 | 1456 |
1464 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, | 1457 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, |
1465 HValue* typecheck) { | 1458 HValue* typecheck) { |
1466 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); | 1459 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); |
1467 } | 1460 } |
1468 | 1461 |
1469 | 1462 |
1470 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { | 1463 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { |
1471 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(), | 1464 return AddLoad(object, HObjectAccess::ForFixedArrayLength()); |
1472 NULL, Representation::Smi()); | |
1473 instr->set_type(HType::Smi()); | |
1474 return instr; | |
1475 } | 1465 } |
1476 | 1466 |
1477 | 1467 |
1478 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1468 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
1479 HValue* old_capacity) { | 1469 HValue* old_capacity) { |
1480 Zone* zone = this->zone(); | 1470 Zone* zone = this->zone(); |
1481 HValue* half_old_capacity = | 1471 HValue* half_old_capacity = |
1482 AddInstruction(HShr::New(zone, context, old_capacity, | 1472 AddInstruction(HShr::New(zone, context, old_capacity, |
1483 graph_->GetConstant1())); | 1473 graph_->GetConstant1())); |
1484 half_old_capacity->ClearFlag(HValue::kCanOverflow); | 1474 half_old_capacity->ClearFlag(HValue::kCanOverflow); |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 allocation_site_payload_(NULL), | 1825 allocation_site_payload_(NULL), |
1836 constructor_function_(constructor_function) { | 1826 constructor_function_(constructor_function) { |
1837 } | 1827 } |
1838 | 1828 |
1839 | 1829 |
1840 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { | 1830 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) { |
1841 if (kind_ == GetInitialFastElementsKind()) { | 1831 if (kind_ == GetInitialFastElementsKind()) { |
1842 // No need for a context lookup if the kind_ matches the initial | 1832 // No need for a context lookup if the kind_ matches the initial |
1843 // map, because we can just load the map in that case. | 1833 // map, because we can just load the map in that case. |
1844 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1834 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
1845 HInstruction* load = | 1835 return builder()->AddInstruction( |
1846 builder()->BuildLoadNamedField(constructor_function_, | 1836 builder()->BuildLoadNamedField(constructor_function_, access)); |
1847 access, | |
1848 Representation::Tagged()); | |
1849 return builder()->AddInstruction(load); | |
1850 } | 1837 } |
1851 | 1838 |
1852 HInstruction* native_context = builder()->BuildGetNativeContext(context); | 1839 HInstruction* native_context = builder()->BuildGetNativeContext(context); |
1853 HInstruction* index = builder()->Add<HConstant>( | 1840 HInstruction* index = builder()->Add<HConstant>( |
1854 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 1841 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
1855 | 1842 |
1856 HInstruction* map_array = builder()->Add<HLoadKeyed>( | 1843 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
1857 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1844 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1858 | 1845 |
1859 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 1846 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
1860 | 1847 |
1861 return builder()->Add<HLoadKeyed>( | 1848 return builder()->Add<HLoadKeyed>( |
1862 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1849 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
1863 } | 1850 } |
1864 | 1851 |
1865 | 1852 |
1866 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 1853 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
1867 // Find the map near the constructor function | 1854 // Find the map near the constructor function |
1868 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1855 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
1869 return builder()->AddInstruction( | 1856 return builder()->AddInstruction( |
1870 builder()->BuildLoadNamedField(constructor_function_, | 1857 builder()->BuildLoadNamedField(constructor_function_, access)); |
1871 access, | |
1872 Representation::Tagged())); | |
1873 } | 1858 } |
1874 | 1859 |
1875 | 1860 |
1876 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1861 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
1877 HValue* length_node) { | 1862 HValue* length_node) { |
1878 HValue* context = builder()->environment()->LookupContext(); | 1863 HValue* context = builder()->environment()->LookupContext(); |
1879 ASSERT(length_node != NULL); | 1864 ASSERT(length_node != NULL); |
1880 | 1865 |
1881 int base_size = JSArray::kSize; | 1866 int base_size = JSArray::kSize; |
1882 if (mode_ == TRACK_ALLOCATION_SITE) { | 1867 if (mode_ == TRACK_ALLOCATION_SITE) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1950 // Fill in the fields: map, properties, length | 1935 // Fill in the fields: map, properties, length |
1951 HValue* map; | 1936 HValue* map; |
1952 if (allocation_site_payload_ == NULL) { | 1937 if (allocation_site_payload_ == NULL) { |
1953 map = EmitInternalMapCode(); | 1938 map = EmitInternalMapCode(); |
1954 } else { | 1939 } else { |
1955 map = EmitMapCode(context); | 1940 map = EmitMapCode(context); |
1956 } | 1941 } |
1957 elements_location_ = builder()->BuildJSArrayHeader(new_object, | 1942 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
1958 map, | 1943 map, |
1959 mode_, | 1944 mode_, |
| 1945 kind_, |
1960 allocation_site_payload_, | 1946 allocation_site_payload_, |
1961 length_field); | 1947 length_field); |
1962 | 1948 |
1963 // Initialize the elements | 1949 // Initialize the elements |
1964 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); | 1950 builder()->BuildInitializeElementsHeader(elements_location_, kind_, capacity); |
1965 | 1951 |
1966 if (fill_with_hole) { | 1952 if (fill_with_hole) { |
1967 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, | 1953 builder()->BuildFillElementsWithHole(context, elements_location_, kind_, |
1968 graph()->GetConstant0(), capacity); | 1954 graph()->GetConstant0(), capacity); |
1969 } | 1955 } |
1970 | 1956 |
1971 return new_object; | 1957 return new_object; |
1972 } | 1958 } |
1973 | 1959 |
1974 | 1960 |
1975 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, | 1961 HStoreNamedField* HGraphBuilder::AddStore(HValue *object, |
1976 HObjectAccess access, | 1962 HObjectAccess access, |
1977 HValue *val, | 1963 HValue *val) { |
1978 Representation representation) { | 1964 return Add<HStoreNamedField>(object, access, val); |
1979 return Add<HStoreNamedField>(object, access, val, representation); | |
1980 } | 1965 } |
1981 | 1966 |
1982 | 1967 |
1983 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, | 1968 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object, |
1984 HObjectAccess access, | 1969 HObjectAccess access, |
1985 HValue *typecheck, | 1970 HValue *typecheck) { |
1986 Representation representation) { | 1971 return Add<HLoadNamedField>(object, access, typecheck); |
1987 return Add<HLoadNamedField>(object, access, typecheck, representation); | |
1988 } | 1972 } |
1989 | 1973 |
1990 | 1974 |
1991 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | 1975 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, |
1992 Handle<Map> map) { | 1976 Handle<Map> map) { |
1993 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), | 1977 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), |
1994 Add<HConstant>(map)); | 1978 Add<HConstant>(map)); |
1995 } | 1979 } |
1996 | 1980 |
1997 | 1981 |
(...skipping 2521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4519 if (!is_store) return false; | 4503 if (!is_store) return false; |
4520 | 4504 |
4521 // 2nd chance: A store into a non-existent field can still be inlined if we | 4505 // 2nd chance: A store into a non-existent field can still be inlined if we |
4522 // have a matching transition and some room left in the object. | 4506 // have a matching transition and some room left in the object. |
4523 type->LookupTransition(NULL, *name, lookup); | 4507 type->LookupTransition(NULL, *name, lookup); |
4524 return lookup->IsTransitionToField(*type) && | 4508 return lookup->IsTransitionToField(*type) && |
4525 (type->unused_property_fields() > 0); | 4509 (type->unused_property_fields() > 0); |
4526 } | 4510 } |
4527 | 4511 |
4528 | 4512 |
4529 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, | |
4530 LookupResult* lookup) { | |
4531 if (lookup->IsField()) { | |
4532 return lookup->representation(); | |
4533 } else { | |
4534 Map* transition = lookup->GetTransitionMapFromMap(*type); | |
4535 int descriptor = transition->LastAdded(); | |
4536 PropertyDetails details = | |
4537 transition->instance_descriptors()->GetDetails(descriptor); | |
4538 return details.representation(); | |
4539 } | |
4540 } | |
4541 | |
4542 | |
4543 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 4513 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
4544 BuildCheckHeapObject(object); | 4514 BuildCheckHeapObject(object); |
4545 AddInstruction(HCheckMaps::New(object, map, zone(), top_info())); | 4515 AddInstruction(HCheckMaps::New(object, map, zone(), top_info())); |
4546 } | 4516 } |
4547 | 4517 |
4548 | 4518 |
4549 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 4519 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
4550 Handle<Map> map) { | 4520 Handle<Map> map) { |
4551 BuildCheckHeapObject(object); | 4521 BuildCheckHeapObject(object); |
4552 AddInstruction(HCheckMaps::NewWithTransitions( | 4522 AddInstruction(HCheckMaps::NewWithTransitions( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4584 } | 4554 } |
4585 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 4555 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
4586 } | 4556 } |
4587 ASSERT(proto->IsJSObject()); | 4557 ASSERT(proto->IsJSObject()); |
4588 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), | 4558 Add<HCheckPrototypeMaps>(Handle<JSObject>(JSObject::cast(map->prototype())), |
4589 Handle<JSObject>(JSObject::cast(proto)), | 4559 Handle<JSObject>(JSObject::cast(proto)), |
4590 zone(), top_info()); | 4560 zone(), top_info()); |
4591 } | 4561 } |
4592 | 4562 |
4593 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); | 4563 HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name); |
4594 Representation representation = ComputeLoadStoreRepresentation(map, lookup); | |
4595 bool transition_to_field = lookup->IsTransitionToField(*map); | 4564 bool transition_to_field = lookup->IsTransitionToField(*map); |
4596 | 4565 |
4597 HStoreNamedField *instr; | 4566 HStoreNamedField *instr; |
4598 if (FLAG_track_double_fields && representation.IsDouble()) { | 4567 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { |
| 4568 HObjectAccess heap_number_access = |
| 4569 field_access.WithRepresentation(Representation::Tagged()); |
4599 if (transition_to_field) { | 4570 if (transition_to_field) { |
4600 // The store requires a mutable HeapNumber to be allocated. | 4571 // The store requires a mutable HeapNumber to be allocated. |
4601 NoObservableSideEffectsScope no_side_effects(this); | 4572 NoObservableSideEffectsScope no_side_effects(this); |
4602 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 4573 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
4603 HInstruction* double_box = Add<HAllocate>( | 4574 HInstruction* heap_number = Add<HAllocate>( |
4604 environment()->LookupContext(), heap_number_size, | 4575 environment()->LookupContext(), heap_number_size, |
4605 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); | 4576 HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE); |
4606 AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map()); | 4577 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); |
4607 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 4578 AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value); |
4608 value, Representation::Double()); | 4579 instr = new(zone()) HStoreNamedField( |
4609 instr = new(zone()) HStoreNamedField(object, field_access, double_box); | 4580 object, heap_number_access, heap_number); |
4610 } else { | 4581 } else { |
4611 // Already holds a HeapNumber; load the box and write its value field. | 4582 // Already holds a HeapNumber; load the box and write its value field. |
4612 HInstruction* double_box = AddLoad(object, field_access); | 4583 HInstruction* heap_number = AddLoad(object, heap_number_access); |
4613 double_box->set_type(HType::HeapNumber()); | 4584 heap_number->set_type(HType::HeapNumber()); |
4614 instr = new(zone()) HStoreNamedField(double_box, | 4585 instr = new(zone()) HStoreNamedField(heap_number, |
4615 HObjectAccess::ForHeapNumberValue(), value, Representation::Double()); | 4586 HObjectAccess::ForHeapNumberValue(), value); |
4616 } | 4587 } |
4617 } else { | 4588 } else { |
4618 // This is a non-double store. | 4589 // This is a normal store. |
4619 instr = new(zone()) HStoreNamedField( | 4590 instr = new(zone()) HStoreNamedField(object, field_access, value); |
4620 object, field_access, value, representation); | |
4621 } | 4591 } |
4622 | 4592 |
4623 if (transition_to_field) { | 4593 if (transition_to_field) { |
4624 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 4594 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
4625 instr->SetTransition(transition, top_info()); | 4595 instr->SetTransition(transition, top_info()); |
4626 // TODO(fschneider): Record the new map type of the object in the IR to | 4596 // TODO(fschneider): Record the new map type of the object in the IR to |
4627 // enable elimination of redundant checks after the transition store. | 4597 // enable elimination of redundant checks after the transition store. |
4628 instr->SetGVNFlag(kChangesMaps); | 4598 instr->SetGVNFlag(kChangesMaps); |
4629 } | 4599 } |
4630 return instr; | 4600 return instr; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4677 Property* expr, | 4647 Property* expr, |
4678 HValue* object, | 4648 HValue* object, |
4679 SmallMapList* types, | 4649 SmallMapList* types, |
4680 Handle<String> name) { | 4650 Handle<String> name) { |
4681 // Use monomorphic load if property lookup results in the same field index | 4651 // Use monomorphic load if property lookup results in the same field index |
4682 // for all maps. Requires special map check on the set of all handled maps. | 4652 // for all maps. Requires special map check on the set of all handled maps. |
4683 if (types->length() > kMaxLoadPolymorphism) return NULL; | 4653 if (types->length() > kMaxLoadPolymorphism) return NULL; |
4684 | 4654 |
4685 LookupResult lookup(isolate()); | 4655 LookupResult lookup(isolate()); |
4686 int count; | 4656 int count; |
4687 Representation representation = Representation::None(); | |
4688 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. | 4657 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
4689 for (count = 0; count < types->length(); ++count) { | 4658 for (count = 0; count < types->length(); ++count) { |
4690 Handle<Map> map = types->at(count); | 4659 Handle<Map> map = types->at(count); |
4691 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 4660 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
4692 | 4661 |
4693 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); | 4662 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); |
4694 Representation new_representation = | |
4695 ComputeLoadStoreRepresentation(map, &lookup); | |
4696 | 4663 |
4697 if (count == 0) { | 4664 if (count == 0) { |
4698 // First time through the loop; set access and representation. | 4665 // First time through the loop; set access and representation. |
4699 access = new_access; | 4666 access = new_access; |
4700 } else if (!representation.IsCompatibleForLoad(new_representation)) { | 4667 } else if (!access.representation().IsCompatibleForLoad( |
| 4668 new_access.representation())) { |
4701 // Representations did not match. | 4669 // Representations did not match. |
4702 break; | 4670 break; |
4703 } else if (access.offset() != new_access.offset()) { | 4671 } else if (access.offset() != new_access.offset()) { |
4704 // Offsets did not match. | 4672 // Offsets did not match. |
4705 break; | 4673 break; |
4706 } else if (access.IsInobject() != new_access.IsInobject()) { | 4674 } else if (access.IsInobject() != new_access.IsInobject()) { |
4707 // In-objectness did not match. | 4675 // In-objectness did not match. |
4708 break; | 4676 break; |
4709 } | 4677 } |
4710 representation = representation.generalize(new_representation); | 4678 access = access.WithRepresentation( |
| 4679 access.representation().generalize(new_access.representation())); |
4711 } | 4680 } |
4712 | 4681 |
4713 if (count == types->length()) { | 4682 if (count == types->length()) { |
4714 // Everything matched; can use monomorphic load. | 4683 // Everything matched; can use monomorphic load. |
4715 BuildCheckHeapObject(object); | 4684 BuildCheckHeapObject(object); |
4716 AddInstruction(HCheckMaps::New(object, types, zone())); | 4685 AddInstruction(HCheckMaps::New(object, types, zone())); |
4717 return BuildLoadNamedField(object, access, representation); | 4686 return BuildLoadNamedField(object, access); |
4718 } | 4687 } |
4719 | 4688 |
4720 if (count != 0) return NULL; | 4689 if (count != 0) return NULL; |
4721 | 4690 |
4722 // Second chance: the property is on the prototype and all maps have the | 4691 // Second chance: the property is on the prototype and all maps have the |
4723 // same prototype. | 4692 // same prototype. |
4724 Handle<Map> map(types->at(0)); | 4693 Handle<Map> map(types->at(0)); |
4725 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; | 4694 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; |
4726 | 4695 |
4727 Handle<Object> prototype(map->prototype(), isolate()); | 4696 Handle<Object> prototype(map->prototype(), isolate()); |
4728 for (count = 1; count < types->length(); ++count) { | 4697 for (count = 1; count < types->length(); ++count) { |
4729 Handle<Map> test_map(types->at(count)); | 4698 Handle<Map> test_map(types->at(count)); |
4730 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; | 4699 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; |
4731 if (test_map->prototype() != *prototype) return NULL; | 4700 if (test_map->prototype() != *prototype) return NULL; |
4732 } | 4701 } |
4733 | 4702 |
4734 LookupInPrototypes(map, name, &lookup); | 4703 LookupInPrototypes(map, name, &lookup); |
4735 if (!lookup.IsField()) return NULL; | 4704 if (!lookup.IsField()) return NULL; |
4736 | 4705 |
4737 BuildCheckHeapObject(object); | 4706 BuildCheckHeapObject(object); |
4738 AddInstruction(HCheckMaps::New(object, types, zone())); | 4707 AddInstruction(HCheckMaps::New(object, types, zone())); |
| 4708 |
4739 Handle<JSObject> holder(lookup.holder()); | 4709 Handle<JSObject> holder(lookup.holder()); |
4740 Handle<Map> holder_map(holder->map()); | 4710 Handle<Map> holder_map(holder->map()); |
4741 AddInstruction(new(zone()) HCheckPrototypeMaps( | 4711 AddInstruction(new(zone()) HCheckPrototypeMaps( |
4742 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); | 4712 Handle<JSObject>::cast(prototype), holder, zone(), top_info())); |
4743 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); | 4713 HValue* holder_value = AddInstruction(new(zone()) HConstant(holder)); |
4744 return BuildLoadNamedField(holder_value, | 4714 return BuildLoadNamedField(holder_value, |
4745 HObjectAccess::ForField(holder_map, &lookup, name), | 4715 HObjectAccess::ForField(holder_map, &lookup, name)); |
4746 ComputeLoadStoreRepresentation(map, &lookup)); | |
4747 } | 4716 } |
4748 | 4717 |
4749 | 4718 |
4750 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 4719 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
4751 Property* expr, | 4720 Property* expr, |
4752 HValue* object, | 4721 HValue* object, |
4753 SmallMapList* types, | 4722 SmallMapList* types, |
4754 Handle<String> name) { | 4723 Handle<String> name) { |
4755 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( | 4724 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
4756 expr, object, types, name); | 4725 expr, object, types, name); |
(...skipping 28 matching lines...) Expand all Loading... |
4785 int count; | 4754 int count; |
4786 Representation representation = Representation::None(); | 4755 Representation representation = Representation::None(); |
4787 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. | 4756 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
4788 for (count = 0; count < types->length(); ++count) { | 4757 for (count = 0; count < types->length(); ++count) { |
4789 Handle<Map> map = types->at(count); | 4758 Handle<Map> map = types->at(count); |
4790 // Pass false to ignore transitions. | 4759 // Pass false to ignore transitions. |
4791 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 4760 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
4792 ASSERT(!map->is_observed()); | 4761 ASSERT(!map->is_observed()); |
4793 | 4762 |
4794 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); | 4763 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); |
4795 Representation new_representation = | 4764 Representation new_representation = new_access.representation(); |
4796 ComputeLoadStoreRepresentation(map, &lookup); | |
4797 | 4765 |
4798 if (count == 0) { | 4766 if (count == 0) { |
4799 // First time through the loop; set access and representation. | 4767 // First time through the loop; set access and representation. |
4800 access = new_access; | 4768 access = new_access; |
4801 representation = new_representation; | 4769 representation = new_representation; |
4802 } else if (!representation.IsCompatibleForStore(new_representation)) { | 4770 } else if (!representation.IsCompatibleForStore(new_representation)) { |
4803 // Representations did not match. | 4771 // Representations did not match. |
4804 break; | 4772 break; |
4805 } else if (access.offset() != new_access.offset()) { | 4773 } else if (access.offset() != new_access.offset()) { |
4806 // Offsets did not match. | 4774 // Offsets did not match. |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5379 HValue* context = environment()->LookupContext(); | 5347 HValue* context = environment()->LookupContext(); |
5380 HValue* value = environment()->Pop(); | 5348 HValue* value = environment()->Pop(); |
5381 HThrow* instr = Add<HThrow>(context, value); | 5349 HThrow* instr = Add<HThrow>(context, value); |
5382 instr->set_position(expr->position()); | 5350 instr->set_position(expr->position()); |
5383 AddSimulate(expr->id()); | 5351 AddSimulate(expr->id()); |
5384 current_block()->FinishExit(new(zone()) HAbnormalExit); | 5352 current_block()->FinishExit(new(zone()) HAbnormalExit); |
5385 set_current_block(NULL); | 5353 set_current_block(NULL); |
5386 } | 5354 } |
5387 | 5355 |
5388 | 5356 |
5389 HLoadNamedField* HGraphBuilder::BuildLoadNamedField( | 5357 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
5390 HValue* object, | 5358 HObjectAccess access) { |
5391 HObjectAccess access, | 5359 if (FLAG_track_double_fields && access.representation().IsDouble()) { |
5392 Representation representation) { | 5360 // load the heap number |
5393 bool load_double = false; | 5361 HLoadNamedField* heap_number = |
5394 if (representation.IsDouble()) { | 5362 AddLoad(object, access.WithRepresentation(Representation::Tagged())); |
5395 representation = Representation::Tagged(); | 5363 heap_number->set_type(HType::HeapNumber()); |
5396 load_double = FLAG_track_double_fields; | 5364 // load the double value from it |
| 5365 return new(zone()) HLoadNamedField(heap_number, |
| 5366 HObjectAccess::ForHeapNumberValue(), NULL); |
5397 } | 5367 } |
5398 HLoadNamedField* field = | 5368 return new(zone()) HLoadNamedField(object, access, NULL); |
5399 new(zone()) HLoadNamedField(object, access, NULL, representation); | |
5400 if (load_double) { | |
5401 AddInstruction(field); | |
5402 field->set_type(HType::HeapNumber()); | |
5403 return new(zone()) HLoadNamedField(field, | |
5404 HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double()); | |
5405 } | |
5406 return field; | |
5407 } | 5369 } |
5408 | 5370 |
5409 | 5371 |
5410 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 5372 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
5411 HValue* object, | 5373 HValue* object, |
5412 Handle<String> name, | 5374 Handle<String> name, |
5413 Property* expr) { | 5375 Property* expr) { |
5414 if (expr->IsUninitialized()) { | 5376 if (expr->IsUninitialized()) { |
5415 AddSoftDeoptimize(); | 5377 AddSoftDeoptimize(); |
5416 } | 5378 } |
(...skipping 19 matching lines...) Expand all Loading... |
5436 Property* expr, | 5398 Property* expr, |
5437 Handle<Map> map) { | 5399 Handle<Map> map) { |
5438 // Handle a load from a known field. | 5400 // Handle a load from a known field. |
5439 ASSERT(!map->is_dictionary_map()); | 5401 ASSERT(!map->is_dictionary_map()); |
5440 | 5402 |
5441 // Handle access to various length properties | 5403 // Handle access to various length properties |
5442 if (name->Equals(isolate()->heap()->length_string())) { | 5404 if (name->Equals(isolate()->heap()->length_string())) { |
5443 if (map->instance_type() == JS_ARRAY_TYPE) { | 5405 if (map->instance_type() == JS_ARRAY_TYPE) { |
5444 AddCheckMapsWithTransitions(object, map); | 5406 AddCheckMapsWithTransitions(object, map); |
5445 return new(zone()) HLoadNamedField(object, | 5407 return new(zone()) HLoadNamedField(object, |
5446 HObjectAccess::ForArrayLength()); | 5408 HObjectAccess::ForArrayLength(map->elements_kind())); |
5447 } | 5409 } |
5448 } | 5410 } |
5449 | 5411 |
5450 LookupResult lookup(isolate()); | 5412 LookupResult lookup(isolate()); |
5451 map->LookupDescriptor(NULL, *name, &lookup); | 5413 map->LookupDescriptor(NULL, *name, &lookup); |
5452 if (lookup.IsField()) { | 5414 if (lookup.IsField()) { |
5453 AddCheckMap(object, map); | 5415 AddCheckMap(object, map); |
5454 return BuildLoadNamedField(object, | 5416 return BuildLoadNamedField(object, |
5455 HObjectAccess::ForField(map, &lookup, name), | 5417 HObjectAccess::ForField(map, &lookup, name)); |
5456 ComputeLoadStoreRepresentation(map, &lookup)); | |
5457 } | 5418 } |
5458 | 5419 |
5459 // Handle a load of a constant known function. | 5420 // Handle a load of a constant known function. |
5460 if (lookup.IsConstantFunction()) { | 5421 if (lookup.IsConstantFunction()) { |
5461 AddCheckMap(object, map); | 5422 AddCheckMap(object, map); |
5462 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 5423 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
5463 return new(zone()) HConstant(function); | 5424 return new(zone()) HConstant(function); |
5464 } | 5425 } |
5465 | 5426 |
5466 // Handle a load from a known field somewhere in the prototype chain. | 5427 // Handle a load from a known field somewhere in the prototype chain. |
5467 LookupInPrototypes(map, name, &lookup); | 5428 LookupInPrototypes(map, name, &lookup); |
5468 if (lookup.IsField()) { | 5429 if (lookup.IsField()) { |
5469 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 5430 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
5470 Handle<JSObject> holder(lookup.holder()); | 5431 Handle<JSObject> holder(lookup.holder()); |
5471 Handle<Map> holder_map(holder->map()); | 5432 Handle<Map> holder_map(holder->map()); |
5472 AddCheckMap(object, map); | 5433 AddCheckMap(object, map); |
5473 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); | 5434 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
5474 HValue* holder_value = Add<HConstant>(holder); | 5435 HValue* holder_value = Add<HConstant>(holder); |
5475 return BuildLoadNamedField(holder_value, | 5436 return BuildLoadNamedField(holder_value, |
5476 HObjectAccess::ForField(holder_map, &lookup, name), | 5437 HObjectAccess::ForField(holder_map, &lookup, name)); |
5477 ComputeLoadStoreRepresentation(map, &lookup)); | |
5478 } | 5438 } |
5479 | 5439 |
5480 // Handle a load of a constant function somewhere in the prototype chain. | 5440 // Handle a load of a constant function somewhere in the prototype chain. |
5481 if (lookup.IsConstantFunction()) { | 5441 if (lookup.IsConstantFunction()) { |
5482 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 5442 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
5483 Handle<JSObject> holder(lookup.holder()); | 5443 Handle<JSObject> holder(lookup.holder()); |
5484 Handle<Map> holder_map(holder->map()); | 5444 Handle<Map> holder_map(holder->map()); |
5485 AddCheckMap(object, map); | 5445 AddCheckMap(object, map); |
5486 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); | 5446 Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info()); |
5487 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); | 5447 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*holder_map)); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5689 set_current_block(this_map); | 5649 set_current_block(this_map); |
5690 HInstruction* checked_key = NULL; | 5650 HInstruction* checked_key = NULL; |
5691 HInstruction* access = NULL; | 5651 HInstruction* access = NULL; |
5692 if (IsFastElementsKind(elements_kind)) { | 5652 if (IsFastElementsKind(elements_kind)) { |
5693 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { | 5653 if (is_store && !IsFastDoubleElementsKind(elements_kind)) { |
5694 AddInstruction(HCheckMaps::New( | 5654 AddInstruction(HCheckMaps::New( |
5695 elements, isolate()->factory()->fixed_array_map(), | 5655 elements, isolate()->factory()->fixed_array_map(), |
5696 zone(), top_info(), mapcompare)); | 5656 zone(), top_info(), mapcompare)); |
5697 } | 5657 } |
5698 if (map->IsJSArray()) { | 5658 if (map->IsJSArray()) { |
5699 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), | 5659 HInstruction* length = AddLoad( |
5700 mapcompare, Representation::Smi()); | 5660 object, HObjectAccess::ForArrayLength(elements_kind), mapcompare); |
5701 length->set_type(HType::Smi()); | |
5702 checked_key = Add<HBoundsCheck>(key, length); | 5661 checked_key = Add<HBoundsCheck>(key, length); |
5703 } else { | 5662 } else { |
5704 HInstruction* length = AddLoadFixedArrayLength(elements); | 5663 HInstruction* length = AddLoadFixedArrayLength(elements); |
5705 checked_key = Add<HBoundsCheck>(key, length); | 5664 checked_key = Add<HBoundsCheck>(key, length); |
5706 } | 5665 } |
5707 access = AddFastElementAccess( | 5666 access = AddFastElementAccess( |
5708 elements, checked_key, val, mapcompare, | 5667 elements, checked_key, val, mapcompare, |
5709 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); | 5668 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE); |
5710 } else if (IsDictionaryElementsKind(elements_kind)) { | 5669 } else if (IsDictionaryElementsKind(elements_kind)) { |
5711 if (is_store) { | 5670 if (is_store) { |
(...skipping 2771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8483 AddStore(object_header, access, properties); | 8442 AddStore(object_header, access, properties); |
8484 | 8443 |
8485 if (boilerplate_object->IsJSArray()) { | 8444 if (boilerplate_object->IsJSArray()) { |
8486 Handle<JSArray> boilerplate_array = | 8445 Handle<JSArray> boilerplate_array = |
8487 Handle<JSArray>::cast(boilerplate_object); | 8446 Handle<JSArray>::cast(boilerplate_object); |
8488 Handle<Object> length_field = | 8447 Handle<Object> length_field = |
8489 Handle<Object>(boilerplate_array->length(), isolate()); | 8448 Handle<Object>(boilerplate_array->length(), isolate()); |
8490 HInstruction* length = Add<HConstant>(length_field); | 8449 HInstruction* length = Add<HConstant>(length_field); |
8491 | 8450 |
8492 ASSERT(boilerplate_array->length()->IsSmi()); | 8451 ASSERT(boilerplate_array->length()->IsSmi()); |
8493 Representation representation = | 8452 AddStore(object_header, HObjectAccess::ForArrayLength( |
8494 IsFastElementsKind(boilerplate_array->GetElementsKind()) | 8453 boilerplate_array->GetElementsKind()), length); |
8495 ? Representation::Smi() : Representation::Tagged(); | |
8496 AddStore(object_header, HObjectAccess::ForArrayLength(), | |
8497 length, representation); | |
8498 } | 8454 } |
8499 | 8455 |
8500 return result; | 8456 return result; |
8501 } | 8457 } |
8502 | 8458 |
8503 | 8459 |
8504 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( | 8460 void HOptimizedGraphBuilder::BuildEmitInObjectProperties( |
8505 Handle<JSObject> boilerplate_object, | 8461 Handle<JSObject> boilerplate_object, |
8506 Handle<JSObject> original_boilerplate_object, | 8462 Handle<JSObject> original_boilerplate_object, |
8507 HValue* object_properties, | 8463 HValue* object_properties, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8553 if (data_target != NULL) { | 8509 if (data_target != NULL) { |
8554 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); | 8510 double_box = Add<HInnerAllocatedObject>(data_target, *data_offset); |
8555 *data_offset += HeapNumber::kSize; | 8511 *data_offset += HeapNumber::kSize; |
8556 } else { | 8512 } else { |
8557 double_box = Add<HInnerAllocatedObject>(target, *offset); | 8513 double_box = Add<HInnerAllocatedObject>(target, *offset); |
8558 *offset += HeapNumber::kSize; | 8514 *offset += HeapNumber::kSize; |
8559 } | 8515 } |
8560 AddStoreMapConstant(double_box, | 8516 AddStoreMapConstant(double_box, |
8561 isolate()->factory()->heap_number_map()); | 8517 isolate()->factory()->heap_number_map()); |
8562 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), | 8518 AddStore(double_box, HObjectAccess::ForHeapNumberValue(), |
8563 value_instruction, Representation::Double()); | 8519 value_instruction); |
8564 value_instruction = double_box; | 8520 value_instruction = double_box; |
8565 } | 8521 } |
8566 | 8522 |
8567 AddStore(object_properties, access, value_instruction); | 8523 AddStore(object_properties, access, value_instruction); |
8568 } | 8524 } |
8569 } | 8525 } |
8570 | 8526 |
8571 int inobject_properties = boilerplate_object->map()->inobject_properties(); | 8527 int inobject_properties = boilerplate_object->map()->inobject_properties(); |
8572 HInstruction* value_instruction = | 8528 HInstruction* value_instruction = |
8573 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); | 8529 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9949 if (ShouldProduceTraceOutput()) { | 9905 if (ShouldProduceTraceOutput()) { |
9950 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9906 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9951 } | 9907 } |
9952 | 9908 |
9953 #ifdef DEBUG | 9909 #ifdef DEBUG |
9954 graph_->Verify(false); // No full verify. | 9910 graph_->Verify(false); // No full verify. |
9955 #endif | 9911 #endif |
9956 } | 9912 } |
9957 | 9913 |
9958 } } // namespace v8::internal | 9914 } } // namespace v8::internal |
OLD | NEW |