| 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 |