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/deoptimizer.h" | 5 #include "src/deoptimizer.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
(...skipping 3599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3610 | 3610 |
3611 stack_frame_pointer_ = stack_frame_pointer; | 3611 stack_frame_pointer_ = stack_frame_pointer; |
3612 has_adapted_arguments_ = has_adapted_arguments; | 3612 has_adapted_arguments_ = has_adapted_arguments; |
3613 | 3613 |
3614 UpdateFromPreviouslyMaterializedObjects(); | 3614 UpdateFromPreviouslyMaterializedObjects(); |
3615 } | 3615 } |
3616 | 3616 |
3617 | 3617 |
3618 Handle<Object> TranslatedState::MaterializeAt(int frame_index, | 3618 Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
3619 int* value_index) { | 3619 int* value_index) { |
| 3620 CHECK_LT(static_cast<size_t>(frame_index), frames().size()); |
3620 TranslatedFrame* frame = &(frames_[frame_index]); | 3621 TranslatedFrame* frame = &(frames_[frame_index]); |
3621 CHECK(static_cast<size_t>(*value_index) < frame->values_.size()); | 3622 CHECK_LT(static_cast<size_t>(*value_index), frame->values_.size()); |
3622 | 3623 |
3623 TranslatedValue* slot = &(frame->values_[*value_index]); | 3624 TranslatedValue* slot = &(frame->values_[*value_index]); |
3624 (*value_index)++; | 3625 (*value_index)++; |
3625 | 3626 |
3626 switch (slot->kind()) { | 3627 switch (slot->kind()) { |
3627 case TranslatedValue::kTagged: | 3628 case TranslatedValue::kTagged: |
3628 case TranslatedValue::kInt32: | 3629 case TranslatedValue::kInt32: |
3629 case TranslatedValue::kUInt32: | 3630 case TranslatedValue::kUInt32: |
3630 case TranslatedValue::kBoolBit: | 3631 case TranslatedValue::kBoolBit: |
3631 case TranslatedValue::kFloat: | 3632 case TranslatedValue::kFloat: |
(...skipping 25 matching lines...) Expand all Loading... |
3657 Handle<Object> value = MaterializeAt(frame_index, value_index); | 3658 Handle<Object> value = MaterializeAt(frame_index, value_index); |
3658 array->set(i, *value); | 3659 array->set(i, *value); |
3659 } | 3660 } |
3660 } | 3661 } |
3661 slot->value_ = arguments; | 3662 slot->value_ = arguments; |
3662 return arguments; | 3663 return arguments; |
3663 } | 3664 } |
3664 case TranslatedValue::kCapturedObject: { | 3665 case TranslatedValue::kCapturedObject: { |
3665 int length = slot->GetChildrenCount(); | 3666 int length = slot->GetChildrenCount(); |
3666 | 3667 |
| 3668 class FieldMaterializer { |
| 3669 public: |
| 3670 FieldMaterializer(TranslatedState* state, int frame_index, |
| 3671 int field_count) |
| 3672 : state_(state), |
| 3673 frame_index_(frame_index), |
| 3674 field_count_(field_count) {} |
| 3675 |
| 3676 Handle<Object> At(int* value_index) { |
| 3677 CHECK(field_count_ > 0); |
| 3678 --field_count_; |
| 3679 return state_->MaterializeAt(frame_index_, value_index); |
| 3680 } |
| 3681 |
| 3682 ~FieldMaterializer() { CHECK_EQ(0, field_count_); } |
| 3683 |
| 3684 private: |
| 3685 TranslatedState* state_; |
| 3686 int frame_index_; |
| 3687 int field_count_; |
| 3688 }; |
| 3689 FieldMaterializer materializer(this, frame_index, length); |
| 3690 |
3667 // The map must be a tagged object. | 3691 // The map must be a tagged object. |
3668 CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged); | 3692 CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged); |
3669 | 3693 |
3670 Handle<Object> result; | 3694 Handle<Object> result; |
3671 if (slot->value_.ToHandle(&result)) { | 3695 if (slot->value_.ToHandle(&result)) { |
3672 // This has been previously materialized, return the previous value. | 3696 // This has been previously materialized, return the previous value. |
3673 // We still need to skip all the nested objects. | 3697 // We still need to skip all the nested objects. |
3674 for (int i = 0; i < length; i++) { | 3698 for (int i = 0; i < length; i++) { |
3675 MaterializeAt(frame_index, value_index); | 3699 materializer.At(value_index); |
3676 } | 3700 } |
3677 | 3701 |
3678 return result; | 3702 return result; |
3679 } | 3703 } |
3680 | 3704 |
3681 Handle<Object> map_object = MaterializeAt(frame_index, value_index); | 3705 Handle<Object> map_object = materializer.At(value_index); |
3682 Handle<Map> map = | 3706 Handle<Map> map = |
3683 Map::GeneralizeAllFieldRepresentations(Handle<Map>::cast(map_object)); | 3707 Map::GeneralizeAllFieldRepresentations(Handle<Map>::cast(map_object)); |
3684 switch (map->instance_type()) { | 3708 switch (map->instance_type()) { |
3685 case MUTABLE_HEAP_NUMBER_TYPE: | 3709 case MUTABLE_HEAP_NUMBER_TYPE: |
3686 case HEAP_NUMBER_TYPE: { | 3710 case HEAP_NUMBER_TYPE: { |
3687 // Reuse the HeapNumber value directly as it is already properly | 3711 // Reuse the HeapNumber value directly as it is already properly |
3688 // tagged and skip materializing the HeapNumber explicitly. | 3712 // tagged and skip materializing the HeapNumber explicitly. |
3689 Handle<Object> object = MaterializeAt(frame_index, value_index); | 3713 Handle<Object> object = materializer.At(value_index); |
3690 slot->value_ = object; | 3714 slot->value_ = object; |
3691 // On 32-bit architectures, there is an extra slot there because | 3715 // On 32-bit architectures, there is an extra slot there because |
3692 // the escape analysis calculates the number of slots as | 3716 // the escape analysis calculates the number of slots as |
3693 // object-size/pointer-size. To account for this, we read out | 3717 // object-size/pointer-size. To account for this, we read out |
3694 // any extra slots. | 3718 // any extra slots. |
3695 for (int i = 0; i < length - 2; i++) { | 3719 for (int i = 0; i < length - 2; i++) { |
3696 MaterializeAt(frame_index, value_index); | 3720 materializer.At(value_index); |
3697 } | 3721 } |
3698 return object; | 3722 return object; |
3699 } | 3723 } |
3700 case JS_OBJECT_TYPE: | 3724 case JS_OBJECT_TYPE: |
3701 case JS_ERROR_TYPE: | 3725 case JS_ERROR_TYPE: |
3702 case JS_ARGUMENTS_TYPE: { | 3726 case JS_ARGUMENTS_TYPE: { |
3703 Handle<JSObject> object = | 3727 Handle<JSObject> object = |
3704 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED); | 3728 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED); |
3705 slot->value_ = object; | 3729 slot->value_ = object; |
3706 Handle<Object> properties = MaterializeAt(frame_index, value_index); | 3730 Handle<Object> properties = materializer.At(value_index); |
3707 Handle<Object> elements = MaterializeAt(frame_index, value_index); | 3731 Handle<Object> elements = materializer.At(value_index); |
3708 object->set_properties(FixedArray::cast(*properties)); | 3732 object->set_properties(FixedArray::cast(*properties)); |
3709 object->set_elements(FixedArrayBase::cast(*elements)); | 3733 object->set_elements(FixedArrayBase::cast(*elements)); |
3710 for (int i = 0; i < length - 3; ++i) { | 3734 for (int i = 0; i < length - 3; ++i) { |
3711 Handle<Object> value = MaterializeAt(frame_index, value_index); | 3735 Handle<Object> value = materializer.At(value_index); |
3712 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i); | 3736 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i); |
3713 object->FastPropertyAtPut(index, *value); | 3737 object->FastPropertyAtPut(index, *value); |
3714 } | 3738 } |
3715 return object; | 3739 return object; |
3716 } | 3740 } |
3717 case JS_ARRAY_TYPE: { | 3741 case JS_ARRAY_TYPE: { |
3718 Handle<JSArray> object = Handle<JSArray>::cast( | 3742 Handle<JSArray> object = Handle<JSArray>::cast( |
3719 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED)); | 3743 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED)); |
3720 slot->value_ = object; | 3744 slot->value_ = object; |
3721 Handle<Object> properties = MaterializeAt(frame_index, value_index); | 3745 Handle<Object> properties = materializer.At(value_index); |
3722 Handle<Object> elements = MaterializeAt(frame_index, value_index); | 3746 Handle<Object> elements = materializer.At(value_index); |
3723 Handle<Object> length = MaterializeAt(frame_index, value_index); | 3747 Handle<Object> length = materializer.At(value_index); |
3724 object->set_properties(FixedArray::cast(*properties)); | 3748 object->set_properties(FixedArray::cast(*properties)); |
3725 object->set_elements(FixedArrayBase::cast(*elements)); | 3749 object->set_elements(FixedArrayBase::cast(*elements)); |
3726 object->set_length(*length); | 3750 object->set_length(*length); |
3727 return object; | 3751 return object; |
3728 } | 3752 } |
3729 case JS_FUNCTION_TYPE: { | 3753 case JS_FUNCTION_TYPE: { |
3730 Handle<SharedFunctionInfo> temporary_shared = | 3754 Handle<SharedFunctionInfo> temporary_shared = |
3731 isolate_->factory()->NewSharedFunctionInfo( | 3755 isolate_->factory()->NewSharedFunctionInfo( |
3732 isolate_->factory()->empty_string(), MaybeHandle<Code>(), | 3756 isolate_->factory()->empty_string(), MaybeHandle<Code>(), |
3733 false); | 3757 false); |
3734 Handle<JSFunction> object = | 3758 Handle<JSFunction> object = |
3735 isolate_->factory()->NewFunctionFromSharedFunctionInfo( | 3759 isolate_->factory()->NewFunctionFromSharedFunctionInfo( |
3736 map, temporary_shared, isolate_->factory()->undefined_value(), | 3760 map, temporary_shared, isolate_->factory()->undefined_value(), |
3737 NOT_TENURED); | 3761 NOT_TENURED); |
3738 slot->value_ = object; | 3762 slot->value_ = object; |
3739 Handle<Object> properties = MaterializeAt(frame_index, value_index); | 3763 Handle<Object> properties = materializer.At(value_index); |
3740 Handle<Object> elements = MaterializeAt(frame_index, value_index); | 3764 Handle<Object> elements = materializer.At(value_index); |
3741 Handle<Object> prototype = MaterializeAt(frame_index, value_index); | 3765 Handle<Object> prototype = materializer.At(value_index); |
3742 Handle<Object> shared = MaterializeAt(frame_index, value_index); | 3766 Handle<Object> shared = materializer.At(value_index); |
3743 Handle<Object> context = MaterializeAt(frame_index, value_index); | 3767 Handle<Object> context = materializer.At(value_index); |
3744 Handle<Object> literals = MaterializeAt(frame_index, value_index); | 3768 Handle<Object> literals = materializer.At(value_index); |
3745 Handle<Object> entry = MaterializeAt(frame_index, value_index); | 3769 Handle<Object> entry = materializer.At(value_index); |
3746 Handle<Object> next_link = MaterializeAt(frame_index, value_index); | 3770 Handle<Object> next_link = materializer.At(value_index); |
3747 object->ReplaceCode(*isolate_->builtins()->CompileLazy()); | 3771 object->ReplaceCode(*isolate_->builtins()->CompileLazy()); |
3748 object->set_map(*map); | 3772 object->set_map(*map); |
3749 object->set_properties(FixedArray::cast(*properties)); | 3773 object->set_properties(FixedArray::cast(*properties)); |
3750 object->set_elements(FixedArrayBase::cast(*elements)); | 3774 object->set_elements(FixedArrayBase::cast(*elements)); |
3751 object->set_prototype_or_initial_map(*prototype); | 3775 object->set_prototype_or_initial_map(*prototype); |
3752 object->set_shared(SharedFunctionInfo::cast(*shared)); | 3776 object->set_shared(SharedFunctionInfo::cast(*shared)); |
3753 object->set_context(Context::cast(*context)); | 3777 object->set_context(Context::cast(*context)); |
3754 object->set_literals(LiteralsArray::cast(*literals)); | 3778 object->set_literals(LiteralsArray::cast(*literals)); |
3755 CHECK(entry->IsNumber()); // Entry to compile lazy stub. | 3779 CHECK(entry->IsNumber()); // Entry to compile lazy stub. |
3756 CHECK(next_link->IsUndefined(isolate_)); | 3780 CHECK(next_link->IsUndefined(isolate_)); |
3757 return object; | 3781 return object; |
3758 } | 3782 } |
3759 case CONS_STRING_TYPE: { | 3783 case CONS_STRING_TYPE: { |
3760 Handle<ConsString> object = Handle<ConsString>::cast( | 3784 Handle<ConsString> object = Handle<ConsString>::cast( |
3761 isolate_->factory() | 3785 isolate_->factory() |
3762 ->NewConsString(isolate_->factory()->undefined_string(), | 3786 ->NewConsString(isolate_->factory()->undefined_string(), |
3763 isolate_->factory()->undefined_string()) | 3787 isolate_->factory()->undefined_string()) |
3764 .ToHandleChecked()); | 3788 .ToHandleChecked()); |
3765 slot->value_ = object; | 3789 slot->value_ = object; |
3766 Handle<Object> hash = MaterializeAt(frame_index, value_index); | 3790 Handle<Object> hash = materializer.At(value_index); |
3767 Handle<Object> length = MaterializeAt(frame_index, value_index); | 3791 Handle<Object> length = materializer.At(value_index); |
3768 Handle<Object> first = MaterializeAt(frame_index, value_index); | 3792 Handle<Object> first = materializer.At(value_index); |
3769 Handle<Object> second = MaterializeAt(frame_index, value_index); | 3793 Handle<Object> second = materializer.At(value_index); |
3770 object->set_map(*map); | 3794 object->set_map(*map); |
3771 object->set_length(Smi::cast(*length)->value()); | 3795 object->set_length(Smi::cast(*length)->value()); |
3772 object->set_first(String::cast(*first)); | 3796 object->set_first(String::cast(*first)); |
3773 object->set_second(String::cast(*second)); | 3797 object->set_second(String::cast(*second)); |
3774 CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value. | 3798 CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value. |
3775 return object; | 3799 return object; |
3776 } | 3800 } |
3777 case CONTEXT_EXTENSION_TYPE: { | 3801 case CONTEXT_EXTENSION_TYPE: { |
3778 Handle<ContextExtension> object = | 3802 Handle<ContextExtension> object = |
3779 isolate_->factory()->NewContextExtension( | 3803 isolate_->factory()->NewContextExtension( |
3780 isolate_->factory()->NewScopeInfo(1), | 3804 isolate_->factory()->NewScopeInfo(1), |
3781 isolate_->factory()->undefined_value()); | 3805 isolate_->factory()->undefined_value()); |
3782 slot->value_ = object; | 3806 slot->value_ = object; |
3783 Handle<Object> scope_info = MaterializeAt(frame_index, value_index); | 3807 Handle<Object> scope_info = materializer.At(value_index); |
3784 Handle<Object> extension = MaterializeAt(frame_index, value_index); | 3808 Handle<Object> extension = materializer.At(value_index); |
3785 object->set_scope_info(ScopeInfo::cast(*scope_info)); | 3809 object->set_scope_info(ScopeInfo::cast(*scope_info)); |
3786 object->set_extension(*extension); | 3810 object->set_extension(*extension); |
3787 return object; | 3811 return object; |
3788 } | 3812 } |
3789 case FIXED_ARRAY_TYPE: { | 3813 case FIXED_ARRAY_TYPE: { |
3790 Handle<Object> lengthObject = MaterializeAt(frame_index, value_index); | 3814 Handle<Object> lengthObject = materializer.At(value_index); |
3791 int32_t length = 0; | 3815 int32_t length = 0; |
3792 CHECK(lengthObject->ToInt32(&length)); | 3816 CHECK(lengthObject->ToInt32(&length)); |
3793 Handle<FixedArray> object = | 3817 Handle<FixedArray> object = |
3794 isolate_->factory()->NewFixedArray(length); | 3818 isolate_->factory()->NewFixedArray(length); |
3795 // We need to set the map, because the fixed array we are | 3819 // We need to set the map, because the fixed array we are |
3796 // materializing could be a context or an arguments object, | 3820 // materializing could be a context or an arguments object, |
3797 // in which case we must retain that information. | 3821 // in which case we must retain that information. |
3798 object->set_map(*map); | 3822 object->set_map(*map); |
3799 slot->value_ = object; | 3823 slot->value_ = object; |
3800 for (int i = 0; i < length; ++i) { | 3824 for (int i = 0; i < length; ++i) { |
3801 Handle<Object> value = MaterializeAt(frame_index, value_index); | 3825 Handle<Object> value = materializer.At(value_index); |
3802 object->set(i, *value); | 3826 object->set(i, *value); |
3803 } | 3827 } |
3804 return object; | 3828 return object; |
3805 } | 3829 } |
3806 case FIXED_DOUBLE_ARRAY_TYPE: { | 3830 case FIXED_DOUBLE_ARRAY_TYPE: { |
3807 DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map()); | 3831 DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map()); |
3808 Handle<Object> lengthObject = MaterializeAt(frame_index, value_index); | 3832 Handle<Object> lengthObject = materializer.At(value_index); |
3809 int32_t length = 0; | 3833 int32_t length = 0; |
3810 CHECK(lengthObject->ToInt32(&length)); | 3834 CHECK(lengthObject->ToInt32(&length)); |
3811 Handle<FixedArrayBase> object = | 3835 Handle<FixedArrayBase> object = |
3812 isolate_->factory()->NewFixedDoubleArray(length); | 3836 isolate_->factory()->NewFixedDoubleArray(length); |
3813 slot->value_ = object; | 3837 slot->value_ = object; |
3814 if (length > 0) { | 3838 if (length > 0) { |
3815 Handle<FixedDoubleArray> double_array = | 3839 Handle<FixedDoubleArray> double_array = |
3816 Handle<FixedDoubleArray>::cast(object); | 3840 Handle<FixedDoubleArray>::cast(object); |
3817 for (int i = 0; i < length; ++i) { | 3841 for (int i = 0; i < length; ++i) { |
3818 Handle<Object> value = MaterializeAt(frame_index, value_index); | 3842 Handle<Object> value = materializer.At(value_index); |
3819 CHECK(value->IsNumber()); | 3843 CHECK(value->IsNumber()); |
3820 double_array->set(i, value->Number()); | 3844 double_array->set(i, value->Number()); |
3821 } | 3845 } |
3822 } | 3846 } |
3823 return object; | 3847 return object; |
3824 } | 3848 } |
3825 default: | 3849 default: |
3826 PrintF(stderr, "[couldn't handle instance type %d]\n", | 3850 PrintF(stderr, "[couldn't handle instance type %d]\n", |
3827 map->instance_type()); | 3851 map->instance_type()); |
3828 FATAL("unreachable"); | 3852 FATAL("unreachable"); |
(...skipping 27 matching lines...) Expand all Loading... |
3856 UNREACHABLE(); | 3880 UNREACHABLE(); |
3857 break; | 3881 break; |
3858 } | 3882 } |
3859 | 3883 |
3860 FATAL("We should never get here - unexpected deopt slot kind."); | 3884 FATAL("We should never get here - unexpected deopt slot kind."); |
3861 return Handle<Object>::null(); | 3885 return Handle<Object>::null(); |
3862 } | 3886 } |
3863 | 3887 |
3864 | 3888 |
3865 Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) { | 3889 Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) { |
| 3890 CHECK_LT(static_cast<size_t>(object_index), object_positions_.size()); |
3866 TranslatedState::ObjectPosition pos = object_positions_[object_index]; | 3891 TranslatedState::ObjectPosition pos = object_positions_[object_index]; |
3867 return MaterializeAt(pos.frame_index_, &(pos.value_index_)); | 3892 return MaterializeAt(pos.frame_index_, &(pos.value_index_)); |
3868 } | 3893 } |
3869 | 3894 |
3870 | 3895 |
3871 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, | 3896 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, |
3872 int frame_index) { | 3897 int frame_index) { |
3873 if (frame_index == 0) { | 3898 if (frame_index == 0) { |
3874 // Top level frame -> we need to go to the parent frame on the stack. | 3899 // Top level frame -> we need to go to the parent frame on the stack. |
3875 if (!has_adapted_arguments_) return false; | 3900 if (!has_adapted_arguments_) return false; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4007 CHECK(value_info->IsMaterializedObject()); | 4032 CHECK(value_info->IsMaterializedObject()); |
4008 | 4033 |
4009 value_info->value_ = | 4034 value_info->value_ = |
4010 Handle<Object>(previously_materialized_objects->get(i), isolate_); | 4035 Handle<Object>(previously_materialized_objects->get(i), isolate_); |
4011 } | 4036 } |
4012 } | 4037 } |
4013 } | 4038 } |
4014 | 4039 |
4015 } // namespace internal | 4040 } // namespace internal |
4016 } // namespace v8 | 4041 } // namespace v8 |
OLD | NEW |