| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 9644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9655 Add<HConstant>(initial_map)); | 9655 Add<HConstant>(initial_map)); |
| 9656 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); | 9656 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); |
| 9657 Add<HStoreNamedField>(receiver, | 9657 Add<HStoreNamedField>(receiver, |
| 9658 HObjectAccess::ForMapAndOffset(initial_map, | 9658 HObjectAccess::ForMapAndOffset(initial_map, |
| 9659 JSObject::kPropertiesOffset), | 9659 JSObject::kPropertiesOffset), |
| 9660 empty_fixed_array); | 9660 empty_fixed_array); |
| 9661 Add<HStoreNamedField>(receiver, | 9661 Add<HStoreNamedField>(receiver, |
| 9662 HObjectAccess::ForMapAndOffset(initial_map, | 9662 HObjectAccess::ForMapAndOffset(initial_map, |
| 9663 JSObject::kElementsOffset), | 9663 JSObject::kElementsOffset), |
| 9664 empty_fixed_array); | 9664 empty_fixed_array); |
| 9665 if (initial_map->inobject_properties() != 0) { | 9665 BuildInitializeInobjectProperties(receiver, initial_map); |
| 9666 HConstant* undefined = graph()->GetConstantUndefined(); | |
| 9667 for (int i = 0; i < initial_map->inobject_properties(); i++) { | |
| 9668 int property_offset = initial_map->GetInObjectPropertyOffset(i); | |
| 9669 Add<HStoreNamedField>(receiver, | |
| 9670 HObjectAccess::ForMapAndOffset(initial_map, property_offset), | |
| 9671 undefined); | |
| 9672 } | |
| 9673 } | |
| 9674 } | 9666 } |
| 9675 | 9667 |
| 9676 // Replace the constructor function with a newly allocated receiver using | 9668 // Replace the constructor function with a newly allocated receiver using |
| 9677 // the index of the receiver from the top of the expression stack. | 9669 // the index of the receiver from the top of the expression stack. |
| 9678 const int receiver_index = argument_count - 1; | 9670 const int receiver_index = argument_count - 1; |
| 9679 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); | 9671 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); |
| 9680 environment()->SetExpressionStackAt(receiver_index, receiver); | 9672 environment()->SetExpressionStackAt(receiver_index, receiver); |
| 9681 | 9673 |
| 9682 if (TryInlineConstruct(expr, receiver)) { | 9674 if (TryInlineConstruct(expr, receiver)) { |
| 9683 // Inlining worked, add a dependency on the initial map to make sure that | 9675 // Inlining worked, add a dependency on the initial map to make sure that |
| (...skipping 22 matching lines...) Expand all Loading... |
| 9706 // argument to the construct call. | 9698 // argument to the construct call. |
| 9707 if (TryHandleArrayCallNew(expr, function)) return; | 9699 if (TryHandleArrayCallNew(expr, function)) return; |
| 9708 | 9700 |
| 9709 HInstruction* call = | 9701 HInstruction* call = |
| 9710 PreProcessCall(New<HCallNew>(function, argument_count)); | 9702 PreProcessCall(New<HCallNew>(function, argument_count)); |
| 9711 return ast_context()->ReturnInstruction(call, expr->id()); | 9703 return ast_context()->ReturnInstruction(call, expr->id()); |
| 9712 } | 9704 } |
| 9713 } | 9705 } |
| 9714 | 9706 |
| 9715 | 9707 |
| 9708 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties( |
| 9709 HValue* receiver, Handle<Map> initial_map) { |
| 9710 if (initial_map->inobject_properties() != 0) { |
| 9711 HConstant* undefined = graph()->GetConstantUndefined(); |
| 9712 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
| 9713 int property_offset = initial_map->GetInObjectPropertyOffset(i); |
| 9714 Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset( |
| 9715 initial_map, property_offset), |
| 9716 undefined); |
| 9717 } |
| 9718 } |
| 9719 } |
| 9720 |
| 9721 |
| 9716 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { | 9722 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { |
| 9717 HAllocate* result = | 9723 HAllocate* result = |
| 9718 BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields), | 9724 BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields), |
| 9719 HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); | 9725 HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); |
| 9720 | 9726 |
| 9721 HValue* global_object = Add<HLoadNamedField>( | 9727 HValue* global_object = Add<HLoadNamedField>( |
| 9722 context(), nullptr, | 9728 context(), nullptr, |
| 9723 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 9729 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 9724 HValue* native_context = Add<HLoadNamedField>( | 9730 HValue* native_context = Add<HLoadNamedField>( |
| 9725 global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); | 9731 global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); |
| (...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11275 } else { | 11281 } else { |
| 11276 return New<HThisFunction>(); | 11282 return New<HThisFunction>(); |
| 11277 } | 11283 } |
| 11278 } | 11284 } |
| 11279 | 11285 |
| 11280 | 11286 |
| 11281 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 11287 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
| 11282 Handle<JSObject> boilerplate_object, | 11288 Handle<JSObject> boilerplate_object, |
| 11283 AllocationSiteUsageContext* site_context) { | 11289 AllocationSiteUsageContext* site_context) { |
| 11284 NoObservableSideEffectsScope no_effects(this); | 11290 NoObservableSideEffectsScope no_effects(this); |
| 11285 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 11291 Handle<Map> initial_map(boilerplate_object->map()); |
| 11292 InstanceType instance_type = initial_map->instance_type(); |
| 11286 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 11293 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
| 11287 | 11294 |
| 11288 HType type = instance_type == JS_ARRAY_TYPE | 11295 HType type = instance_type == JS_ARRAY_TYPE |
| 11289 ? HType::JSArray() : HType::JSObject(); | 11296 ? HType::JSArray() : HType::JSObject(); |
| 11290 HValue* object_size_constant = Add<HConstant>( | 11297 HValue* object_size_constant = Add<HConstant>(initial_map->instance_size()); |
| 11291 boilerplate_object->map()->instance_size()); | |
| 11292 | 11298 |
| 11293 PretenureFlag pretenure_flag = NOT_TENURED; | 11299 PretenureFlag pretenure_flag = NOT_TENURED; |
| 11294 Handle<AllocationSite> current_site(*site_context->current(), isolate()); | 11300 Handle<AllocationSite> current_site(*site_context->current(), isolate()); |
| 11295 if (FLAG_allocation_site_pretenuring) { | 11301 if (FLAG_allocation_site_pretenuring) { |
| 11296 pretenure_flag = current_site->GetPretenureMode(); | 11302 pretenure_flag = current_site->GetPretenureMode(); |
| 11297 top_info()->dependencies()->AssumeTenuringDecision(current_site); | 11303 top_info()->dependencies()->AssumeTenuringDecision(current_site); |
| 11298 } | 11304 } |
| 11299 | 11305 |
| 11300 top_info()->dependencies()->AssumeTransitionStable(current_site); | 11306 top_info()->dependencies()->AssumeTransitionStable(current_site); |
| 11301 | 11307 |
| 11302 HInstruction* object = Add<HAllocate>( | 11308 HInstruction* object = Add<HAllocate>( |
| 11303 object_size_constant, type, pretenure_flag, instance_type, current_site); | 11309 object_size_constant, type, pretenure_flag, instance_type, current_site); |
| 11304 | 11310 |
| 11305 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the | 11311 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the |
| 11306 // elements array may not get folded into the object. Hence, we set the | 11312 // elements array may not get folded into the object. Hence, we set the |
| 11307 // elements pointer to empty fixed array and let store elimination remove | 11313 // elements pointer to empty fixed array and let store elimination remove |
| 11308 // this store in the folding case. | 11314 // this store in the folding case. |
| 11309 HConstant* empty_fixed_array = Add<HConstant>( | 11315 HConstant* empty_fixed_array = Add<HConstant>( |
| 11310 isolate()->factory()->empty_fixed_array()); | 11316 isolate()->factory()->empty_fixed_array()); |
| 11311 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 11317 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 11312 empty_fixed_array); | 11318 empty_fixed_array); |
| 11313 | 11319 |
| 11314 BuildEmitObjectHeader(boilerplate_object, object); | 11320 BuildEmitObjectHeader(boilerplate_object, object); |
| 11315 | 11321 |
| 11322 // Similarly to the elements pointer, there is no guarantee that all |
| 11323 // property allocations can get folded, so pre-initialize all in-object |
| 11324 // properties to a safe value. |
| 11325 BuildInitializeInobjectProperties(object, initial_map); |
| 11326 |
| 11316 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 11327 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
| 11317 int elements_size = (elements->length() > 0 && | 11328 int elements_size = (elements->length() > 0 && |
| 11318 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 11329 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
| 11319 elements->Size() : 0; | 11330 elements->Size() : 0; |
| 11320 | 11331 |
| 11321 if (pretenure_flag == TENURED && | 11332 if (pretenure_flag == TENURED && |
| 11322 elements->map() == isolate()->heap()->fixed_cow_array_map() && | 11333 elements->map() == isolate()->heap()->fixed_cow_array_map() && |
| 11323 isolate()->heap()->InNewSpace(*elements)) { | 11334 isolate()->heap()->InNewSpace(*elements)) { |
| 11324 // If we would like to pretenure a fixed cow array, we must ensure that the | 11335 // If we would like to pretenure a fixed cow array, we must ensure that the |
| 11325 // array is already in old space, otherwise we'll create too many old-to- | 11336 // array is already in old space, otherwise we'll create too many old-to- |
| (...skipping 18 matching lines...) Expand all Loading... |
| 11344 object_elements); | 11355 object_elements); |
| 11345 } else { | 11356 } else { |
| 11346 Handle<Object> elements_field = | 11357 Handle<Object> elements_field = |
| 11347 Handle<Object>(boilerplate_object->elements(), isolate()); | 11358 Handle<Object>(boilerplate_object->elements(), isolate()); |
| 11348 HInstruction* object_elements_cow = Add<HConstant>(elements_field); | 11359 HInstruction* object_elements_cow = Add<HConstant>(elements_field); |
| 11349 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 11360 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 11350 object_elements_cow); | 11361 object_elements_cow); |
| 11351 } | 11362 } |
| 11352 | 11363 |
| 11353 // Copy in-object properties. | 11364 // Copy in-object properties. |
| 11354 if (boilerplate_object->map()->NumberOfFields() != 0 || | 11365 if (initial_map->NumberOfFields() != 0 || |
| 11355 boilerplate_object->map()->unused_property_fields() > 0) { | 11366 initial_map->unused_property_fields() > 0) { |
| 11356 BuildEmitInObjectProperties(boilerplate_object, object, site_context, | 11367 BuildEmitInObjectProperties(boilerplate_object, object, site_context, |
| 11357 pretenure_flag); | 11368 pretenure_flag); |
| 11358 } | 11369 } |
| 11359 return object; | 11370 return object; |
| 11360 } | 11371 } |
| 11361 | 11372 |
| 11362 | 11373 |
| 11363 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 11374 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
| 11364 Handle<JSObject> boilerplate_object, | 11375 Handle<JSObject> boilerplate_object, |
| 11365 HInstruction* object) { | 11376 HInstruction* object) { |
| (...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13138 if (ShouldProduceTraceOutput()) { | 13149 if (ShouldProduceTraceOutput()) { |
| 13139 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13150 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13140 } | 13151 } |
| 13141 | 13152 |
| 13142 #ifdef DEBUG | 13153 #ifdef DEBUG |
| 13143 graph_->Verify(false); // No full verify. | 13154 graph_->Verify(false); // No full verify. |
| 13144 #endif | 13155 #endif |
| 13145 } | 13156 } |
| 13146 | 13157 |
| 13147 } } // namespace v8::internal | 13158 } } // namespace v8::internal |
| OLD | NEW |