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 |