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 9649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9660 Add<HConstant>(initial_map)); | 9660 Add<HConstant>(initial_map)); |
9661 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); | 9661 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); |
9662 Add<HStoreNamedField>(receiver, | 9662 Add<HStoreNamedField>(receiver, |
9663 HObjectAccess::ForMapAndOffset(initial_map, | 9663 HObjectAccess::ForMapAndOffset(initial_map, |
9664 JSObject::kPropertiesOffset), | 9664 JSObject::kPropertiesOffset), |
9665 empty_fixed_array); | 9665 empty_fixed_array); |
9666 Add<HStoreNamedField>(receiver, | 9666 Add<HStoreNamedField>(receiver, |
9667 HObjectAccess::ForMapAndOffset(initial_map, | 9667 HObjectAccess::ForMapAndOffset(initial_map, |
9668 JSObject::kElementsOffset), | 9668 JSObject::kElementsOffset), |
9669 empty_fixed_array); | 9669 empty_fixed_array); |
9670 if (initial_map->inobject_properties() != 0) { | 9670 BuildInitializeInobjectProperties(receiver, initial_map); |
9671 HConstant* undefined = graph()->GetConstantUndefined(); | |
9672 for (int i = 0; i < initial_map->inobject_properties(); i++) { | |
9673 int property_offset = initial_map->GetInObjectPropertyOffset(i); | |
9674 Add<HStoreNamedField>(receiver, | |
9675 HObjectAccess::ForMapAndOffset(initial_map, property_offset), | |
9676 undefined); | |
9677 } | |
9678 } | |
9679 } | 9671 } |
9680 | 9672 |
9681 // Replace the constructor function with a newly allocated receiver using | 9673 // Replace the constructor function with a newly allocated receiver using |
9682 // the index of the receiver from the top of the expression stack. | 9674 // the index of the receiver from the top of the expression stack. |
9683 const int receiver_index = argument_count - 1; | 9675 const int receiver_index = argument_count - 1; |
9684 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); | 9676 DCHECK(environment()->ExpressionStackAt(receiver_index) == function); |
9685 environment()->SetExpressionStackAt(receiver_index, receiver); | 9677 environment()->SetExpressionStackAt(receiver_index, receiver); |
9686 | 9678 |
9687 if (TryInlineConstruct(expr, receiver)) { | 9679 if (TryInlineConstruct(expr, receiver)) { |
9688 // Inlining worked, add a dependency on the initial map to make sure that | 9680 // Inlining worked, add a dependency on the initial map to make sure that |
(...skipping 22 matching lines...) Expand all Loading... |
9711 // argument to the construct call. | 9703 // argument to the construct call. |
9712 if (TryHandleArrayCallNew(expr, function)) return; | 9704 if (TryHandleArrayCallNew(expr, function)) return; |
9713 | 9705 |
9714 HInstruction* call = | 9706 HInstruction* call = |
9715 PreProcessCall(New<HCallNew>(function, argument_count)); | 9707 PreProcessCall(New<HCallNew>(function, argument_count)); |
9716 return ast_context()->ReturnInstruction(call, expr->id()); | 9708 return ast_context()->ReturnInstruction(call, expr->id()); |
9717 } | 9709 } |
9718 } | 9710 } |
9719 | 9711 |
9720 | 9712 |
| 9713 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties( |
| 9714 HValue* receiver, Handle<Map> initial_map) { |
| 9715 if (initial_map->inobject_properties() != 0) { |
| 9716 HConstant* undefined = graph()->GetConstantUndefined(); |
| 9717 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
| 9718 int property_offset = initial_map->GetInObjectPropertyOffset(i); |
| 9719 Add<HStoreNamedField>(receiver, HObjectAccess::ForMapAndOffset( |
| 9720 initial_map, property_offset), |
| 9721 undefined); |
| 9722 } |
| 9723 } |
| 9724 } |
| 9725 |
| 9726 |
9721 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { | 9727 HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { |
9722 HAllocate* result = | 9728 HAllocate* result = |
9723 BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields), | 9729 BuildAllocate(Add<HConstant>(JSArrayBuffer::kSizeWithInternalFields), |
9724 HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); | 9730 HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); |
9725 | 9731 |
9726 HValue* global_object = Add<HLoadNamedField>( | 9732 HValue* global_object = Add<HLoadNamedField>( |
9727 context(), nullptr, | 9733 context(), nullptr, |
9728 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 9734 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
9729 HValue* native_context = Add<HLoadNamedField>( | 9735 HValue* native_context = Add<HLoadNamedField>( |
9730 global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); | 9736 global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); |
(...skipping 1564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11295 } else { | 11301 } else { |
11296 return New<HThisFunction>(); | 11302 return New<HThisFunction>(); |
11297 } | 11303 } |
11298 } | 11304 } |
11299 | 11305 |
11300 | 11306 |
11301 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 11307 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
11302 Handle<JSObject> boilerplate_object, | 11308 Handle<JSObject> boilerplate_object, |
11303 AllocationSiteUsageContext* site_context) { | 11309 AllocationSiteUsageContext* site_context) { |
11304 NoObservableSideEffectsScope no_effects(this); | 11310 NoObservableSideEffectsScope no_effects(this); |
11305 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 11311 Handle<Map> initial_map(boilerplate_object->map()); |
| 11312 InstanceType instance_type = initial_map->instance_type(); |
11306 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 11313 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
11307 | 11314 |
11308 HType type = instance_type == JS_ARRAY_TYPE | 11315 HType type = instance_type == JS_ARRAY_TYPE |
11309 ? HType::JSArray() : HType::JSObject(); | 11316 ? HType::JSArray() : HType::JSObject(); |
11310 HValue* object_size_constant = Add<HConstant>( | 11317 HValue* object_size_constant = Add<HConstant>(initial_map->instance_size()); |
11311 boilerplate_object->map()->instance_size()); | |
11312 | 11318 |
11313 PretenureFlag pretenure_flag = NOT_TENURED; | 11319 PretenureFlag pretenure_flag = NOT_TENURED; |
11314 Handle<AllocationSite> current_site(*site_context->current(), isolate()); | 11320 Handle<AllocationSite> current_site(*site_context->current(), isolate()); |
11315 if (FLAG_allocation_site_pretenuring) { | 11321 if (FLAG_allocation_site_pretenuring) { |
11316 pretenure_flag = current_site->GetPretenureMode(); | 11322 pretenure_flag = current_site->GetPretenureMode(); |
11317 top_info()->dependencies()->AssumeTenuringDecision(current_site); | 11323 top_info()->dependencies()->AssumeTenuringDecision(current_site); |
11318 } | 11324 } |
11319 | 11325 |
11320 top_info()->dependencies()->AssumeTransitionStable(current_site); | 11326 top_info()->dependencies()->AssumeTransitionStable(current_site); |
11321 | 11327 |
11322 HInstruction* object = Add<HAllocate>( | 11328 HInstruction* object = Add<HAllocate>( |
11323 object_size_constant, type, pretenure_flag, instance_type, current_site); | 11329 object_size_constant, type, pretenure_flag, instance_type, current_site); |
11324 | 11330 |
11325 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the | 11331 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the |
11326 // elements array may not get folded into the object. Hence, we set the | 11332 // elements array may not get folded into the object. Hence, we set the |
11327 // elements pointer to empty fixed array and let store elimination remove | 11333 // elements pointer to empty fixed array and let store elimination remove |
11328 // this store in the folding case. | 11334 // this store in the folding case. |
11329 HConstant* empty_fixed_array = Add<HConstant>( | 11335 HConstant* empty_fixed_array = Add<HConstant>( |
11330 isolate()->factory()->empty_fixed_array()); | 11336 isolate()->factory()->empty_fixed_array()); |
11331 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 11337 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
11332 empty_fixed_array); | 11338 empty_fixed_array); |
11333 | 11339 |
11334 BuildEmitObjectHeader(boilerplate_object, object); | 11340 BuildEmitObjectHeader(boilerplate_object, object); |
11335 | 11341 |
| 11342 // Similarly to the elements pointer, there is no guarantee that all |
| 11343 // property allocations can get folded, so pre-initialize all in-object |
| 11344 // properties to a safe value. |
| 11345 BuildInitializeInobjectProperties(object, initial_map); |
| 11346 |
11336 Handle<FixedArrayBase> elements(boilerplate_object->elements()); | 11347 Handle<FixedArrayBase> elements(boilerplate_object->elements()); |
11337 int elements_size = (elements->length() > 0 && | 11348 int elements_size = (elements->length() > 0 && |
11338 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? | 11349 elements->map() != isolate()->heap()->fixed_cow_array_map()) ? |
11339 elements->Size() : 0; | 11350 elements->Size() : 0; |
11340 | 11351 |
11341 if (pretenure_flag == TENURED && | 11352 if (pretenure_flag == TENURED && |
11342 elements->map() == isolate()->heap()->fixed_cow_array_map() && | 11353 elements->map() == isolate()->heap()->fixed_cow_array_map() && |
11343 isolate()->heap()->InNewSpace(*elements)) { | 11354 isolate()->heap()->InNewSpace(*elements)) { |
11344 // If we would like to pretenure a fixed cow array, we must ensure that the | 11355 // If we would like to pretenure a fixed cow array, we must ensure that the |
11345 // array is already in old space, otherwise we'll create too many old-to- | 11356 // array is already in old space, otherwise we'll create too many old-to- |
(...skipping 18 matching lines...) Expand all Loading... |
11364 object_elements); | 11375 object_elements); |
11365 } else { | 11376 } else { |
11366 Handle<Object> elements_field = | 11377 Handle<Object> elements_field = |
11367 Handle<Object>(boilerplate_object->elements(), isolate()); | 11378 Handle<Object>(boilerplate_object->elements(), isolate()); |
11368 HInstruction* object_elements_cow = Add<HConstant>(elements_field); | 11379 HInstruction* object_elements_cow = Add<HConstant>(elements_field); |
11369 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 11380 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
11370 object_elements_cow); | 11381 object_elements_cow); |
11371 } | 11382 } |
11372 | 11383 |
11373 // Copy in-object properties. | 11384 // Copy in-object properties. |
11374 if (boilerplate_object->map()->NumberOfFields() != 0 || | 11385 if (initial_map->NumberOfFields() != 0 || |
11375 boilerplate_object->map()->unused_property_fields() > 0) { | 11386 initial_map->unused_property_fields() > 0) { |
11376 BuildEmitInObjectProperties(boilerplate_object, object, site_context, | 11387 BuildEmitInObjectProperties(boilerplate_object, object, site_context, |
11377 pretenure_flag); | 11388 pretenure_flag); |
11378 } | 11389 } |
11379 return object; | 11390 return object; |
11380 } | 11391 } |
11381 | 11392 |
11382 | 11393 |
11383 void HOptimizedGraphBuilder::BuildEmitObjectHeader( | 11394 void HOptimizedGraphBuilder::BuildEmitObjectHeader( |
11384 Handle<JSObject> boilerplate_object, | 11395 Handle<JSObject> boilerplate_object, |
11385 HInstruction* object) { | 11396 HInstruction* object) { |
(...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13189 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13200 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13190 } | 13201 } |
13191 | 13202 |
13192 #ifdef DEBUG | 13203 #ifdef DEBUG |
13193 graph_->Verify(false); // No full verify. | 13204 graph_->Verify(false); // No full verify. |
13194 #endif | 13205 #endif |
13195 } | 13206 } |
13196 | 13207 |
13197 } // namespace internal | 13208 } // namespace internal |
13198 } // namespace v8 | 13209 } // namespace v8 |
OLD | NEW |