| 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 "hydrogen.h" | 5 #include "hydrogen.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "v8.h" | 9 #include "v8.h" |
| 10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
| (...skipping 8592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8603 // Take a dependency on allocation site. | 8603 // Take a dependency on allocation site. |
| 8604 AllocationSite::AddDependentCompilationInfo(allocation_site, | 8604 AllocationSite::AddDependentCompilationInfo(allocation_site, |
| 8605 AllocationSite::TENURING, | 8605 AllocationSite::TENURING, |
| 8606 top_info()); | 8606 top_info()); |
| 8607 } else { | 8607 } else { |
| 8608 allocation_mode = HAllocationMode( | 8608 allocation_mode = HAllocationMode( |
| 8609 isolate()->heap()->GetPretenureMode()); | 8609 isolate()->heap()->GetPretenureMode()); |
| 8610 } | 8610 } |
| 8611 } | 8611 } |
| 8612 | 8612 |
| 8613 HAllocate* receiver = | 8613 HAllocate* receiver = BuildAllocate( |
| 8614 BuildAllocate(size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, | 8614 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); |
| 8615 allocation_mode); | |
| 8616 receiver->set_known_initial_map(initial_map); | 8615 receiver->set_known_initial_map(initial_map); |
| 8617 | 8616 |
| 8618 // Load the initial map from the constructor. | |
| 8619 HValue* constructor_value = Add<HConstant>(constructor); | |
| 8620 HValue* initial_map_value = | |
| 8621 Add<HLoadNamedField>(constructor_value, static_cast<HValue*>(NULL), | |
| 8622 HObjectAccess::ForMapAndOffset( | |
| 8623 handle(constructor->map()), | |
| 8624 JSFunction::kPrototypeOrInitialMapOffset)); | |
| 8625 | |
| 8626 // Initialize map and fields of the newly allocated object. | 8617 // Initialize map and fields of the newly allocated object. |
| 8627 { NoObservableSideEffectsScope no_effects(this); | 8618 { NoObservableSideEffectsScope no_effects(this); |
| 8628 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); | 8619 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); |
| 8629 Add<HStoreNamedField>(receiver, | 8620 Add<HStoreNamedField>(receiver, |
| 8630 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), | 8621 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), |
| 8631 initial_map_value); | 8622 Add<HConstant>(initial_map)); |
| 8632 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); | 8623 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); |
| 8633 Add<HStoreNamedField>(receiver, | 8624 Add<HStoreNamedField>(receiver, |
| 8634 HObjectAccess::ForMapAndOffset(initial_map, | 8625 HObjectAccess::ForMapAndOffset(initial_map, |
| 8635 JSObject::kPropertiesOffset), | 8626 JSObject::kPropertiesOffset), |
| 8636 empty_fixed_array); | 8627 empty_fixed_array); |
| 8637 Add<HStoreNamedField>(receiver, | 8628 Add<HStoreNamedField>(receiver, |
| 8638 HObjectAccess::ForMapAndOffset(initial_map, | 8629 HObjectAccess::ForMapAndOffset(initial_map, |
| 8639 JSObject::kElementsOffset), | 8630 JSObject::kElementsOffset), |
| 8640 empty_fixed_array); | 8631 empty_fixed_array); |
| 8641 if (initial_map->inobject_properties() != 0) { | 8632 if (initial_map->inobject_properties() != 0) { |
| 8642 HConstant* undefined = graph()->GetConstantUndefined(); | 8633 HConstant* undefined = graph()->GetConstantUndefined(); |
| 8643 for (int i = 0; i < initial_map->inobject_properties(); i++) { | 8634 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
| 8644 int property_offset = initial_map->GetInObjectPropertyOffset(i); | 8635 int property_offset = initial_map->GetInObjectPropertyOffset(i); |
| 8645 Add<HStoreNamedField>(receiver, | 8636 Add<HStoreNamedField>(receiver, |
| 8646 HObjectAccess::ForMapAndOffset(initial_map, property_offset), | 8637 HObjectAccess::ForMapAndOffset(initial_map, property_offset), |
| 8647 undefined); | 8638 undefined); |
| 8648 } | 8639 } |
| 8649 } | 8640 } |
| 8650 } | 8641 } |
| 8651 | 8642 |
| 8652 // Replace the constructor function with a newly allocated receiver using | 8643 // Replace the constructor function with a newly allocated receiver using |
| 8653 // the index of the receiver from the top of the expression stack. | 8644 // the index of the receiver from the top of the expression stack. |
| 8654 const int receiver_index = argument_count - 1; | 8645 const int receiver_index = argument_count - 1; |
| 8655 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); | 8646 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); |
| 8656 environment()->SetExpressionStackAt(receiver_index, receiver); | 8647 environment()->SetExpressionStackAt(receiver_index, receiver); |
| 8657 | 8648 |
| 8658 if (TryInlineConstruct(expr, receiver)) return; | 8649 if (TryInlineConstruct(expr, receiver)) { |
| 8650 // Inlining worked, add a dependency on the initial map to make sure that |
| 8651 // this code is deoptimized whenever the initial map of the constructor |
| 8652 // changes. |
| 8653 Map::AddDependentCompilationInfo( |
| 8654 initial_map, DependentCode::kInitialMapChangedGroup, top_info()); |
| 8655 return; |
| 8656 } |
| 8659 | 8657 |
| 8660 // TODO(mstarzinger): For now we remove the previous HAllocate and all | 8658 // TODO(mstarzinger): For now we remove the previous HAllocate and all |
| 8661 // corresponding instructions and instead add HPushArgument for the | 8659 // corresponding instructions and instead add HPushArgument for the |
| 8662 // arguments in case inlining failed. What we actually should do is for | 8660 // arguments in case inlining failed. What we actually should do is for |
| 8663 // inlining to try to build a subgraph without mutating the parent graph. | 8661 // inlining to try to build a subgraph without mutating the parent graph. |
| 8664 HInstruction* instr = current_block()->last(); | 8662 HInstruction* instr = current_block()->last(); |
| 8665 while (instr != initial_map_value) { | 8663 do { |
| 8666 HInstruction* prev_instr = instr->previous(); | 8664 HInstruction* prev_instr = instr->previous(); |
| 8667 instr->DeleteAndReplaceWith(NULL); | 8665 instr->DeleteAndReplaceWith(NULL); |
| 8668 instr = prev_instr; | 8666 instr = prev_instr; |
| 8669 } | 8667 } while (instr != check); |
| 8670 initial_map_value->DeleteAndReplaceWith(NULL); | |
| 8671 receiver->DeleteAndReplaceWith(NULL); | |
| 8672 check->DeleteAndReplaceWith(NULL); | |
| 8673 environment()->SetExpressionStackAt(receiver_index, function); | 8668 environment()->SetExpressionStackAt(receiver_index, function); |
| 8674 HInstruction* call = | 8669 HInstruction* call = |
| 8675 PreProcessCall(New<HCallNew>(function, argument_count)); | 8670 PreProcessCall(New<HCallNew>(function, argument_count)); |
| 8676 return ast_context()->ReturnInstruction(call, expr->id()); | 8671 return ast_context()->ReturnInstruction(call, expr->id()); |
| 8677 } else { | 8672 } else { |
| 8678 // The constructor function is both an operand to the instruction and an | 8673 // The constructor function is both an operand to the instruction and an |
| 8679 // argument to the construct call. | 8674 // argument to the construct call. |
| 8680 if (TryHandleArrayCallNew(expr, function)) return; | 8675 if (TryHandleArrayCallNew(expr, function)) return; |
| 8681 | 8676 |
| 8682 HInstruction* call = | 8677 HInstruction* call = |
| (...skipping 3136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11819 if (ShouldProduceTraceOutput()) { | 11814 if (ShouldProduceTraceOutput()) { |
| 11820 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11815 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11821 } | 11816 } |
| 11822 | 11817 |
| 11823 #ifdef DEBUG | 11818 #ifdef DEBUG |
| 11824 graph_->Verify(false); // No full verify. | 11819 graph_->Verify(false); // No full verify. |
| 11825 #endif | 11820 #endif |
| 11826 } | 11821 } |
| 11827 | 11822 |
| 11828 } } // namespace v8::internal | 11823 } } // namespace v8::internal |
| OLD | NEW |