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 5511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5522 return false; | 5522 return false; |
5523 } | 5523 } |
5524 | 5524 |
5525 DCHECK(max_depth >= 0 && *max_properties >= 0); | 5525 DCHECK(max_depth >= 0 && *max_properties >= 0); |
5526 if (max_depth == 0) return false; | 5526 if (max_depth == 0) return false; |
5527 | 5527 |
5528 Isolate* isolate = boilerplate->GetIsolate(); | 5528 Isolate* isolate = boilerplate->GetIsolate(); |
5529 Handle<FixedArrayBase> elements(boilerplate->elements()); | 5529 Handle<FixedArrayBase> elements(boilerplate->elements()); |
5530 if (elements->length() > 0 && | 5530 if (elements->length() > 0 && |
5531 elements->map() != isolate->heap()->fixed_cow_array_map()) { | 5531 elements->map() != isolate->heap()->fixed_cow_array_map()) { |
5532 if (boilerplate->HasFastObjectElements()) { | 5532 if (boilerplate->HasFastSmiOrObjectElements()) { |
5533 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 5533 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
5534 int length = elements->length(); | 5534 int length = elements->length(); |
5535 for (int i = 0; i < length; i++) { | 5535 for (int i = 0; i < length; i++) { |
5536 if ((*max_properties)-- == 0) return false; | 5536 if ((*max_properties)-- == 0) return false; |
5537 Handle<Object> value(fast_elements->get(i), isolate); | 5537 Handle<Object> value(fast_elements->get(i), isolate); |
5538 if (value->IsJSObject()) { | 5538 if (value->IsJSObject()) { |
5539 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 5539 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
5540 if (!IsFastLiteral(value_object, | 5540 if (!IsFastLiteral(value_object, |
5541 max_depth - 1, | 5541 max_depth - 1, |
5542 max_properties)) { | 5542 max_properties)) { |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5783 int flags = expr->depth() == 1 | 5783 int flags = expr->depth() == 1 |
5784 ? ArrayLiteral::kShallowElements | 5784 ? ArrayLiteral::kShallowElements |
5785 : ArrayLiteral::kNoFlags; | 5785 : ArrayLiteral::kNoFlags; |
5786 flags |= ArrayLiteral::kDisableMementos; | 5786 flags |= ArrayLiteral::kDisableMementos; |
5787 | 5787 |
5788 Add<HPushArguments>(Add<HConstant>(literals), | 5788 Add<HPushArguments>(Add<HConstant>(literals), |
5789 Add<HConstant>(literal_index), | 5789 Add<HConstant>(literal_index), |
5790 Add<HConstant>(constants), | 5790 Add<HConstant>(constants), |
5791 Add<HConstant>(flags)); | 5791 Add<HConstant>(flags)); |
5792 | 5792 |
5793 // TODO(mvstanton): Consider a flag to turn off creation of any | |
5794 // AllocationMementos for this call: we are in crankshaft and should have | |
5795 // learned enough about transition behavior to stop emitting mementos. | |
5796 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; | 5793 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; |
5797 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5794 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
5798 Runtime::FunctionForId(function_id), | 5795 Runtime::FunctionForId(function_id), |
5799 4); | 5796 4); |
5800 | 5797 |
5801 // De-opt if elements kind changed from boilerplate_elements_kind. | 5798 // Register to deopt if the boilerplate ElementsKind changes. |
5802 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); | 5799 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); |
5803 literal = Add<HCheckMaps>(literal, map); | |
5804 } | 5800 } |
5805 | 5801 |
5806 // The array is expected in the bailout environment during computation | 5802 // The array is expected in the bailout environment during computation |
5807 // of the property values and is the value of the entire expression. | 5803 // of the property values and is the value of the entire expression. |
5808 Push(literal); | 5804 Push(literal); |
5809 // The literal index is on the stack, too. | 5805 // The literal index is on the stack, too. |
5810 Push(Add<HConstant>(expr->literal_index())); | 5806 Push(Add<HConstant>(expr->literal_index())); |
5811 | 5807 |
5812 HInstruction* elements = NULL; | 5808 HInstruction* elements = NULL; |
5813 | 5809 |
(...skipping 3528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9342 int argument_count, | 9338 int argument_count, |
9343 Handle<AllocationSite> site) { | 9339 Handle<AllocationSite> site) { |
9344 DCHECK(!site.is_null()); | 9340 DCHECK(!site.is_null()); |
9345 DCHECK(argument_count >= 0 && argument_count <= 1); | 9341 DCHECK(argument_count >= 0 && argument_count <= 1); |
9346 NoObservableSideEffectsScope no_effects(this); | 9342 NoObservableSideEffectsScope no_effects(this); |
9347 | 9343 |
9348 // We should at least have the constructor on the expression stack. | 9344 // We should at least have the constructor on the expression stack. |
9349 HValue* constructor = environment()->ExpressionStackAt(argument_count); | 9345 HValue* constructor = environment()->ExpressionStackAt(argument_count); |
9350 | 9346 |
9351 // Register on the site for deoptimization if the transition feedback changes. | 9347 // Register on the site for deoptimization if the transition feedback changes. |
9352 AllocationSite::AddDependentCompilationInfo( | 9348 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); |
9353 site, AllocationSite::TRANSITIONS, top_info()); | |
9354 ElementsKind kind = site->GetElementsKind(); | 9349 ElementsKind kind = site->GetElementsKind(); |
9355 HInstruction* site_instruction = Add<HConstant>(site); | 9350 HInstruction* site_instruction = Add<HConstant>(site); |
9356 | 9351 |
9357 // In the single constant argument case, we may have to adjust elements kind | 9352 // In the single constant argument case, we may have to adjust elements kind |
9358 // to avoid creating a packed non-empty array. | 9353 // to avoid creating a packed non-empty array. |
9359 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { | 9354 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { |
9360 HValue* argument = environment()->Top(); | 9355 HValue* argument = environment()->Top(); |
9361 if (argument->IsConstant()) { | 9356 if (argument->IsConstant()) { |
9362 HConstant* constant_argument = HConstant::cast(argument); | 9357 HConstant* constant_argument = HConstant::cast(argument); |
9363 DCHECK(constant_argument->HasSmiValue()); | 9358 DCHECK(constant_argument->HasSmiValue()); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9473 | 9468 |
9474 // Allocate an instance of the implicit receiver object. | 9469 // Allocate an instance of the implicit receiver object. |
9475 HValue* size_in_bytes = Add<HConstant>(instance_size); | 9470 HValue* size_in_bytes = Add<HConstant>(instance_size); |
9476 HAllocationMode allocation_mode; | 9471 HAllocationMode allocation_mode; |
9477 if (FLAG_pretenuring_call_new) { | 9472 if (FLAG_pretenuring_call_new) { |
9478 if (FLAG_allocation_site_pretenuring) { | 9473 if (FLAG_allocation_site_pretenuring) { |
9479 // Try to use pretenuring feedback. | 9474 // Try to use pretenuring feedback. |
9480 Handle<AllocationSite> allocation_site = expr->allocation_site(); | 9475 Handle<AllocationSite> allocation_site = expr->allocation_site(); |
9481 allocation_mode = HAllocationMode(allocation_site); | 9476 allocation_mode = HAllocationMode(allocation_site); |
9482 // Take a dependency on allocation site. | 9477 // Take a dependency on allocation site. |
9483 AllocationSite::AddDependentCompilationInfo(allocation_site, | 9478 AllocationSite::RegisterForDeoptOnTenureChange(allocation_site, |
9484 AllocationSite::TENURING, | 9479 top_info()); |
9485 top_info()); | |
9486 } | 9480 } |
9487 } | 9481 } |
9488 | 9482 |
9489 HAllocate* receiver = BuildAllocate( | 9483 HAllocate* receiver = BuildAllocate( |
9490 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); | 9484 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); |
9491 receiver->set_known_initial_map(initial_map); | 9485 receiver->set_known_initial_map(initial_map); |
9492 | 9486 |
9493 // Initialize map and fields of the newly allocated object. | 9487 // Initialize map and fields of the newly allocated object. |
9494 { NoObservableSideEffectsScope no_effects(this); | 9488 { NoObservableSideEffectsScope no_effects(this); |
9495 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); | 9489 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE); |
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10518 if (right->IsConstant() && | 10512 if (right->IsConstant() && |
10519 HConstant::cast(right)->HasStringValue() && | 10513 HConstant::cast(right)->HasStringValue() && |
10520 HConstant::cast(right)->StringValue()->length() == 0) { | 10514 HConstant::cast(right)->StringValue()->length() == 0) { |
10521 return left; | 10515 return left; |
10522 } | 10516 } |
10523 | 10517 |
10524 // Register the dependent code with the allocation site. | 10518 // Register the dependent code with the allocation site. |
10525 if (!allocation_mode.feedback_site().is_null()) { | 10519 if (!allocation_mode.feedback_site().is_null()) { |
10526 DCHECK(!graph()->info()->IsStub()); | 10520 DCHECK(!graph()->info()->IsStub()); |
10527 Handle<AllocationSite> site(allocation_mode.feedback_site()); | 10521 Handle<AllocationSite> site(allocation_mode.feedback_site()); |
10528 AllocationSite::AddDependentCompilationInfo( | 10522 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); |
10529 site, AllocationSite::TENURING, top_info()); | |
10530 } | 10523 } |
10531 | 10524 |
10532 // Inline the string addition into the stub when creating allocation | 10525 // Inline the string addition into the stub when creating allocation |
10533 // mementos to gather allocation site feedback, or if we can statically | 10526 // mementos to gather allocation site feedback, or if we can statically |
10534 // infer that we're going to create a cons string. | 10527 // infer that we're going to create a cons string. |
10535 if ((graph()->info()->IsStub() && | 10528 if ((graph()->info()->IsStub() && |
10536 allocation_mode.CreateAllocationMementos()) || | 10529 allocation_mode.CreateAllocationMementos()) || |
10537 (left->IsConstant() && | 10530 (left->IsConstant() && |
10538 HConstant::cast(left)->HasStringValue() && | 10531 HConstant::cast(left)->HasStringValue() && |
10539 HConstant::cast(left)->StringValue()->length() + 1 >= | 10532 HConstant::cast(left)->StringValue()->length() + 1 >= |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11114 NoObservableSideEffectsScope no_effects(this); | 11107 NoObservableSideEffectsScope no_effects(this); |
11115 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 11108 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
11116 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 11109 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
11117 | 11110 |
11118 HType type = instance_type == JS_ARRAY_TYPE | 11111 HType type = instance_type == JS_ARRAY_TYPE |
11119 ? HType::JSArray() : HType::JSObject(); | 11112 ? HType::JSArray() : HType::JSObject(); |
11120 HValue* object_size_constant = Add<HConstant>( | 11113 HValue* object_size_constant = Add<HConstant>( |
11121 boilerplate_object->map()->instance_size()); | 11114 boilerplate_object->map()->instance_size()); |
11122 | 11115 |
11123 PretenureFlag pretenure_flag = NOT_TENURED; | 11116 PretenureFlag pretenure_flag = NOT_TENURED; |
| 11117 Handle<AllocationSite> site(site_context->current()); |
11124 if (FLAG_allocation_site_pretenuring) { | 11118 if (FLAG_allocation_site_pretenuring) { |
11125 pretenure_flag = site_context->current()->GetPretenureMode(); | 11119 pretenure_flag = site_context->current()->GetPretenureMode(); |
11126 Handle<AllocationSite> site(site_context->current()); | 11120 AllocationSite::RegisterForDeoptOnTenureChange(site, top_info()); |
11127 AllocationSite::AddDependentCompilationInfo( | |
11128 site, AllocationSite::TENURING, top_info()); | |
11129 } | 11121 } |
11130 | 11122 |
| 11123 AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info()); |
| 11124 |
11131 HInstruction* object = Add<HAllocate>(object_size_constant, type, | 11125 HInstruction* object = Add<HAllocate>(object_size_constant, type, |
11132 pretenure_flag, instance_type, site_context->current()); | 11126 pretenure_flag, instance_type, site_context->current()); |
11133 | 11127 |
11134 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the | 11128 // If allocation folding reaches Page::kMaxRegularHeapObjectSize the |
11135 // elements array may not get folded into the object. Hence, we set the | 11129 // elements array may not get folded into the object. Hence, we set the |
11136 // elements pointer to empty fixed array and let store elimination remove | 11130 // elements pointer to empty fixed array and let store elimination remove |
11137 // this store in the folding case. | 11131 // this store in the folding case. |
11138 HConstant* empty_fixed_array = Add<HConstant>( | 11132 HConstant* empty_fixed_array = Add<HConstant>( |
11139 isolate()->factory()->empty_fixed_array()); | 11133 isolate()->factory()->empty_fixed_array()); |
11140 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 11134 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12739 if (ShouldProduceTraceOutput()) { | 12733 if (ShouldProduceTraceOutput()) { |
12740 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12734 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12741 } | 12735 } |
12742 | 12736 |
12743 #ifdef DEBUG | 12737 #ifdef DEBUG |
12744 graph_->Verify(false); // No full verify. | 12738 graph_->Verify(false); // No full verify. |
12745 #endif | 12739 #endif |
12746 } | 12740 } |
12747 | 12741 |
12748 } } // namespace v8::internal | 12742 } } // namespace v8::internal |
OLD | NEW |