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