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 1297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 } | 1308 } |
1309 } | 1309 } |
1310 } | 1310 } |
1311 return AddFastElementAccess(elements, checked_key, val, mapcheck, | 1311 return AddFastElementAccess(elements, checked_key, val, mapcheck, |
1312 elements_kind, is_store, load_mode, store_mode); | 1312 elements_kind, is_store, load_mode, store_mode); |
1313 } | 1313 } |
1314 | 1314 |
1315 | 1315 |
1316 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, | 1316 HValue* HGraphBuilder::BuildAllocateElements(ElementsKind kind, |
1317 HValue* capacity) { | 1317 HValue* capacity) { |
1318 int elements_size = IsFastDoubleElementsKind(kind) | 1318 int elements_size; |
1319 ? kDoubleSize : kPointerSize; | 1319 InstanceType instance_type; |
| 1320 |
| 1321 if (IsFastDoubleElementsKind(kind)) { |
| 1322 elements_size = kDoubleSize; |
| 1323 instance_type = FIXED_DOUBLE_ARRAY_TYPE; |
| 1324 } else { |
| 1325 elements_size = kPointerSize; |
| 1326 instance_type = FIXED_ARRAY_TYPE; |
| 1327 } |
| 1328 |
1320 HConstant* elements_size_value = Add<HConstant>(elements_size); | 1329 HConstant* elements_size_value = Add<HConstant>(elements_size); |
1321 HValue* mul = Add<HMul>(capacity, elements_size_value); | 1330 HValue* mul = Add<HMul>(capacity, elements_size_value); |
1322 mul->ClearFlag(HValue::kCanOverflow); | 1331 mul->ClearFlag(HValue::kCanOverflow); |
1323 | 1332 |
1324 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); | 1333 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); |
1325 HValue* total_size = Add<HAdd>(mul, header_size); | 1334 HValue* total_size = Add<HAdd>(mul, header_size); |
1326 total_size->ClearFlag(HValue::kCanOverflow); | 1335 total_size->ClearFlag(HValue::kCanOverflow); |
1327 | 1336 |
1328 return Add<HAllocate>(total_size, HType::JSArray(), | 1337 return Add<HAllocate>(total_size, HType::JSArray(), |
1329 isolate()->heap()->ShouldGloballyPretenure(), kind); | 1338 isolate()->heap()->GetPretenureMode(), instance_type); |
1330 } | 1339 } |
1331 | 1340 |
1332 | 1341 |
1333 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 1342 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
1334 ElementsKind kind, | 1343 ElementsKind kind, |
1335 HValue* capacity) { | 1344 HValue* capacity) { |
1336 Factory* factory = isolate()->factory(); | 1345 Factory* factory = isolate()->factory(); |
1337 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1346 Handle<Map> map = IsFastDoubleElementsKind(kind) |
1338 ? factory->fixed_double_array_map() | 1347 ? factory->fixed_double_array_map() |
1339 : factory->fixed_array_map(); | 1348 : factory->fixed_array_map(); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 ElementsKind kind, | 1648 ElementsKind kind, |
1640 int length) { | 1649 int length) { |
1641 NoObservableSideEffectsScope no_effects(this); | 1650 NoObservableSideEffectsScope no_effects(this); |
1642 | 1651 |
1643 // All sizes here are multiples of kPointerSize. | 1652 // All sizes here are multiples of kPointerSize. |
1644 int size = JSArray::kSize; | 1653 int size = JSArray::kSize; |
1645 if (mode == TRACK_ALLOCATION_SITE) { | 1654 if (mode == TRACK_ALLOCATION_SITE) { |
1646 size += AllocationMemento::kSize; | 1655 size += AllocationMemento::kSize; |
1647 } | 1656 } |
1648 int elems_offset = size; | 1657 int elems_offset = size; |
| 1658 InstanceType instance_type = IsFastDoubleElementsKind(kind) ? |
| 1659 FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE; |
1649 if (length > 0) { | 1660 if (length > 0) { |
1650 size += IsFastDoubleElementsKind(kind) | 1661 size += IsFastDoubleElementsKind(kind) |
1651 ? FixedDoubleArray::SizeFor(length) | 1662 ? FixedDoubleArray::SizeFor(length) |
1652 : FixedArray::SizeFor(length); | 1663 : FixedArray::SizeFor(length); |
1653 } | 1664 } |
1654 | 1665 |
1655 // Allocate both the JS array and the elements array in one big | 1666 // Allocate both the JS array and the elements array in one big |
1656 // allocation. This avoids multiple limit checks. | 1667 // allocation. This avoids multiple limit checks. |
1657 HValue* size_in_bytes = Add<HConstant>(size); | 1668 HValue* size_in_bytes = Add<HConstant>(size); |
1658 HInstruction* object = Add<HAllocate>(size_in_bytes, | 1669 HInstruction* object = Add<HAllocate>(size_in_bytes, |
1659 HType::JSObject(), | 1670 HType::JSObject(), |
1660 false, | 1671 NOT_TENURED, |
1661 kind); | 1672 instance_type); |
1662 | 1673 |
1663 // Copy the JS array part. | 1674 // Copy the JS array part. |
1664 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1675 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
1665 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1676 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
1666 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); | 1677 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); |
1667 Add<HStoreNamedField>(object, access, | 1678 Add<HStoreNamedField>(object, access, |
1668 Add<HLoadNamedField>(boilerplate, access)); | 1679 Add<HLoadNamedField>(boilerplate, access)); |
1669 } | 1680 } |
1670 } | 1681 } |
1671 | 1682 |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 bool fill_with_hole) { | 1940 bool fill_with_hole) { |
1930 // These HForceRepresentations are because we store these as fields in the | 1941 // These HForceRepresentations are because we store these as fields in the |
1931 // objects we construct, and an int32-to-smi HChange could deopt. Accept | 1942 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
1932 // the deopt possibility now, before allocation occurs. | 1943 // the deopt possibility now, before allocation occurs. |
1933 capacity = builder()->Add<HForceRepresentation>(capacity, | 1944 capacity = builder()->Add<HForceRepresentation>(capacity, |
1934 Representation::Smi()); | 1945 Representation::Smi()); |
1935 length_field = builder()->Add<HForceRepresentation>(length_field, | 1946 length_field = builder()->Add<HForceRepresentation>(length_field, |
1936 Representation::Smi()); | 1947 Representation::Smi()); |
1937 // Allocate (dealing with failure appropriately) | 1948 // Allocate (dealing with failure appropriately) |
1938 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, | 1949 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, |
1939 HType::JSArray(), false, kind_); | 1950 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); |
1940 | 1951 |
1941 // Fill in the fields: map, properties, length | 1952 // Fill in the fields: map, properties, length |
1942 HValue* map; | 1953 HValue* map; |
1943 if (allocation_site_payload_ == NULL) { | 1954 if (allocation_site_payload_ == NULL) { |
1944 map = EmitInternalMapCode(); | 1955 map = EmitInternalMapCode(); |
1945 } else { | 1956 } else { |
1946 map = EmitMapCode(); | 1957 map = EmitMapCode(); |
1947 } | 1958 } |
1948 elements_location_ = builder()->BuildJSArrayHeader(new_object, | 1959 elements_location_ = builder()->BuildJSArrayHeader(new_object, |
1949 map, | 1960 map, |
(...skipping 2563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4513 | 4524 |
4514 HStoreNamedField *instr; | 4525 HStoreNamedField *instr; |
4515 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { | 4526 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { |
4516 HObjectAccess heap_number_access = | 4527 HObjectAccess heap_number_access = |
4517 field_access.WithRepresentation(Representation::Tagged()); | 4528 field_access.WithRepresentation(Representation::Tagged()); |
4518 if (transition_to_field) { | 4529 if (transition_to_field) { |
4519 // The store requires a mutable HeapNumber to be allocated. | 4530 // The store requires a mutable HeapNumber to be allocated. |
4520 NoObservableSideEffectsScope no_side_effects(this); | 4531 NoObservableSideEffectsScope no_side_effects(this); |
4521 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 4532 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
4522 HInstruction* heap_number = Add<HAllocate>(heap_number_size, | 4533 HInstruction* heap_number = Add<HAllocate>(heap_number_size, |
4523 HType::HeapNumber(), false); | 4534 HType::HeapNumber(), NOT_TENURED, HEAP_NUMBER_TYPE); |
4524 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); | 4535 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); |
4525 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 4536 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
4526 value); | 4537 value); |
4527 instr = New<HStoreNamedField>(object, heap_number_access, | 4538 instr = New<HStoreNamedField>(object, heap_number_access, |
4528 heap_number); | 4539 heap_number); |
4529 } else { | 4540 } else { |
4530 // Already holds a HeapNumber; load the box and write its value field. | 4541 // Already holds a HeapNumber; load the box and write its value field. |
4531 HInstruction* heap_number = Add<HLoadNamedField>(object, | 4542 HInstruction* heap_number = Add<HLoadNamedField>(object, |
4532 heap_number_access); | 4543 heap_number_access); |
4533 heap_number->set_type(HType::HeapNumber()); | 4544 heap_number->set_type(HType::HeapNumber()); |
(...skipping 2549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7083 } | 7094 } |
7084 | 7095 |
7085 // Calculate instance size from initial map of constructor. | 7096 // Calculate instance size from initial map of constructor. |
7086 ASSERT(constructor->has_initial_map()); | 7097 ASSERT(constructor->has_initial_map()); |
7087 Handle<Map> initial_map(constructor->initial_map()); | 7098 Handle<Map> initial_map(constructor->initial_map()); |
7088 int instance_size = initial_map->instance_size(); | 7099 int instance_size = initial_map->instance_size(); |
7089 ASSERT(initial_map->InitialPropertiesLength() == 0); | 7100 ASSERT(initial_map->InitialPropertiesLength() == 0); |
7090 | 7101 |
7091 // Allocate an instance of the implicit receiver object. | 7102 // Allocate an instance of the implicit receiver object. |
7092 HValue* size_in_bytes = Add<HConstant>(instance_size); | 7103 HValue* size_in_bytes = Add<HConstant>(instance_size); |
7093 bool pretenure = FLAG_pretenuring_call_new && | 7104 PretenureFlag pretenure_flag = |
7094 isolate()->heap()->ShouldGloballyPretenure(); | 7105 (FLAG_pretenuring_call_new && |
| 7106 isolate()->heap()->GetPretenureMode() == TENURED) |
| 7107 ? TENURED : NOT_TENURED; |
7095 HAllocate* receiver = | 7108 HAllocate* receiver = |
7096 Add<HAllocate>(size_in_bytes, HType::JSObject(), pretenure); | 7109 Add<HAllocate>(size_in_bytes, HType::JSObject(), pretenure_flag, |
| 7110 JS_OBJECT_TYPE); |
7097 receiver->set_known_initial_map(initial_map); | 7111 receiver->set_known_initial_map(initial_map); |
7098 | 7112 |
7099 // Load the initial map from the constructor. | 7113 // Load the initial map from the constructor. |
7100 HValue* constructor_value = Add<HConstant>(constructor); | 7114 HValue* constructor_value = Add<HConstant>(constructor); |
7101 HValue* initial_map_value = | 7115 HValue* initial_map_value = |
7102 Add<HLoadNamedField>(constructor_value, HObjectAccess::ForJSObjectOffset( | 7116 Add<HLoadNamedField>(constructor_value, HObjectAccess::ForJSObjectOffset( |
7103 JSFunction::kPrototypeOrInitialMapOffset)); | 7117 JSFunction::kPrototypeOrInitialMapOffset)); |
7104 | 7118 |
7105 // Initialize map and fields of the newly allocated object. | 7119 // Initialize map and fields of the newly allocated object. |
7106 { NoObservableSideEffectsScope no_effects(this); | 7120 { NoObservableSideEffectsScope no_effects(this); |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8158 Handle<JSObject> original_boilerplate_object, | 8172 Handle<JSObject> original_boilerplate_object, |
8159 Handle<Object> allocation_site, | 8173 Handle<Object> allocation_site, |
8160 int data_size, | 8174 int data_size, |
8161 int pointer_size, | 8175 int pointer_size, |
8162 AllocationSiteMode mode) { | 8176 AllocationSiteMode mode) { |
8163 NoObservableSideEffectsScope no_effects(this); | 8177 NoObservableSideEffectsScope no_effects(this); |
8164 | 8178 |
8165 HInstruction* target = NULL; | 8179 HInstruction* target = NULL; |
8166 HInstruction* data_target = NULL; | 8180 HInstruction* data_target = NULL; |
8167 | 8181 |
8168 ElementsKind kind = boilerplate_object->map()->elements_kind(); | 8182 if (isolate()->heap()->GetPretenureMode() == TENURED) { |
8169 | |
8170 if (isolate()->heap()->ShouldGloballyPretenure()) { | |
8171 if (data_size != 0) { | 8183 if (data_size != 0) { |
8172 HValue* size_in_bytes = Add<HConstant>(data_size); | 8184 HValue* size_in_bytes = Add<HConstant>(data_size); |
8173 data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(), | 8185 data_target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED, |
8174 true, FAST_DOUBLE_ELEMENTS); | 8186 FIXED_DOUBLE_ARRAY_TYPE); |
8175 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); | 8187 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); |
8176 AddStoreMapConstant(data_target, free_space_map); | 8188 AddStoreMapConstant(data_target, free_space_map); |
8177 HObjectAccess access = | 8189 HObjectAccess access = |
8178 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); | 8190 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); |
8179 Add<HStoreNamedField>(data_target, access, size_in_bytes); | 8191 Add<HStoreNamedField>(data_target, access, size_in_bytes); |
8180 } | 8192 } |
8181 if (pointer_size != 0) { | 8193 if (pointer_size != 0) { |
8182 HValue* size_in_bytes = Add<HConstant>(pointer_size); | 8194 HValue* size_in_bytes = Add<HConstant>(pointer_size); |
8183 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), true); | 8195 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), TENURED, |
| 8196 JS_OBJECT_TYPE); |
8184 } | 8197 } |
8185 } else { | 8198 } else { |
| 8199 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
8186 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); | 8200 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); |
8187 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), false, kind); | 8201 target = Add<HAllocate>(size_in_bytes, HType::JSObject(), NOT_TENURED, |
| 8202 instance_type); |
8188 } | 8203 } |
8189 | 8204 |
8190 int offset = 0; | 8205 int offset = 0; |
8191 int data_offset = 0; | 8206 int data_offset = 0; |
8192 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, | 8207 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, |
8193 allocation_site, target, &offset, data_target, | 8208 allocation_site, target, &offset, data_target, |
8194 &data_offset, mode); | 8209 &data_offset, mode); |
8195 return target; | 8210 return target; |
8196 } | 8211 } |
8197 | 8212 |
(...skipping 1567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9765 if (ShouldProduceTraceOutput()) { | 9780 if (ShouldProduceTraceOutput()) { |
9766 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9781 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9767 } | 9782 } |
9768 | 9783 |
9769 #ifdef DEBUG | 9784 #ifdef DEBUG |
9770 graph_->Verify(false); // No full verify. | 9785 graph_->Verify(false); // No full verify. |
9771 #endif | 9786 #endif |
9772 } | 9787 } |
9773 | 9788 |
9774 } } // namespace v8::internal | 9789 } } // namespace v8::internal |
OLD | NEW |