Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: src/deoptimizer.cc

Issue 2646433002: [deoptimizer] Materialize array iterators in the deoptimizer. (Closed)
Patch Set: Formatting Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/deoptimizer.h ('k') | test/mjsunit/regress/regress-681383.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3596 matching lines...) Expand 10 before | Expand all | Expand 10 after
3607 void TranslatedState::Prepare(bool has_adapted_arguments, 3607 void TranslatedState::Prepare(bool has_adapted_arguments,
3608 Address stack_frame_pointer) { 3608 Address stack_frame_pointer) {
3609 for (auto& frame : frames_) frame.Handlify(); 3609 for (auto& frame : frames_) frame.Handlify();
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 class TranslatedState::CapturedObjectMaterializer {
3618 public:
3619 CapturedObjectMaterializer(TranslatedState* state, int frame_index,
3620 int field_count)
3621 : state_(state), frame_index_(frame_index), field_count_(field_count) {}
3622
3623 Handle<Object> FieldAt(int* value_index) {
3624 CHECK(field_count_ > 0);
3625 --field_count_;
3626 return state_->MaterializeAt(frame_index_, value_index);
3627 }
3628
3629 ~CapturedObjectMaterializer() { CHECK_EQ(0, field_count_); }
3630
3631 private:
3632 TranslatedState* state_;
3633 int frame_index_;
3634 int field_count_;
3635 };
3636
3637 Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
3638 TranslatedValue* slot, int frame_index, int* value_index) {
3639 int length = slot->GetChildrenCount();
3640
3641 CapturedObjectMaterializer materializer(this, frame_index, length);
3642
3643 Handle<Object> result;
3644 if (slot->value_.ToHandle(&result)) {
3645 // This has been previously materialized, return the previous value.
3646 // We still need to skip all the nested objects.
3647 for (int i = 0; i < length; i++) {
3648 materializer.FieldAt(value_index);
3649 }
3650
3651 return result;
3652 }
3653
3654 Handle<Object> map_object = materializer.FieldAt(value_index);
3655 Handle<Map> map = Map::GeneralizeAllFields(Handle<Map>::cast(map_object));
3656 switch (map->instance_type()) {
3657 case MUTABLE_HEAP_NUMBER_TYPE:
3658 case HEAP_NUMBER_TYPE: {
3659 // Reuse the HeapNumber value directly as it is already properly
3660 // tagged and skip materializing the HeapNumber explicitly.
3661 Handle<Object> object = materializer.FieldAt(value_index);
3662 slot->value_ = object;
3663 // On 32-bit architectures, there is an extra slot there because
3664 // the escape analysis calculates the number of slots as
3665 // object-size/pointer-size. To account for this, we read out
3666 // any extra slots.
3667 for (int i = 0; i < length - 2; i++) {
3668 materializer.FieldAt(value_index);
3669 }
3670 return object;
3671 }
3672 case JS_OBJECT_TYPE:
3673 case JS_ERROR_TYPE:
3674 case JS_ARGUMENTS_TYPE: {
3675 Handle<JSObject> object =
3676 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
3677 slot->value_ = object;
3678 Handle<Object> properties = materializer.FieldAt(value_index);
3679 Handle<Object> elements = materializer.FieldAt(value_index);
3680 object->set_properties(FixedArray::cast(*properties));
3681 object->set_elements(FixedArrayBase::cast(*elements));
3682 for (int i = 0; i < length - 3; ++i) {
3683 Handle<Object> value = materializer.FieldAt(value_index);
3684 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
3685 object->FastPropertyAtPut(index, *value);
3686 }
3687 return object;
3688 }
3689 case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
3690 case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
3691 case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
3692 case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3693 case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3694 case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3695 case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3696 case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3697 case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3698 case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3699 case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3700 case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3701 case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3702 case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3703 case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3704 case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3705 case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3706 case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3707 case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
3708 case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
3709 case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
3710 case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
3711 case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
3712 case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
3713 case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
3714 case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
3715 case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
3716 case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
3717 case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
3718 case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
3719 case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
3720 case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
3721 case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
3722 case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
3723 case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE: {
3724 Handle<JSArrayIterator> object = Handle<JSArrayIterator>::cast(
3725 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
3726 slot->value_ = object;
3727 Handle<Object> properties = materializer.FieldAt(value_index);
3728 Handle<Object> elements = materializer.FieldAt(value_index);
3729 Handle<Object> iterated_object = materializer.FieldAt(value_index);
3730 Handle<Object> next_index = materializer.FieldAt(value_index);
3731 Handle<Object> iterated_object_map = materializer.FieldAt(value_index);
3732 object->set_properties(FixedArray::cast(*properties));
3733 object->set_elements(FixedArrayBase::cast(*elements));
3734 object->set_object(*iterated_object);
3735 object->set_index(*next_index);
3736 object->set_object_map(*iterated_object_map);
3737 return object;
3738 }
3739 case JS_ARRAY_TYPE: {
3740 Handle<JSArray> object = Handle<JSArray>::cast(
3741 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
3742 slot->value_ = object;
3743 Handle<Object> properties = materializer.FieldAt(value_index);
3744 Handle<Object> elements = materializer.FieldAt(value_index);
3745 Handle<Object> length = materializer.FieldAt(value_index);
3746 object->set_properties(FixedArray::cast(*properties));
3747 object->set_elements(FixedArrayBase::cast(*elements));
3748 object->set_length(*length);
3749 return object;
3750 }
3751 case JS_FUNCTION_TYPE: {
3752 Handle<SharedFunctionInfo> temporary_shared =
3753 isolate_->factory()->NewSharedFunctionInfo(
3754 isolate_->factory()->empty_string(), MaybeHandle<Code>(), false);
3755 Handle<JSFunction> object =
3756 isolate_->factory()->NewFunctionFromSharedFunctionInfo(
3757 map, temporary_shared, isolate_->factory()->undefined_value(),
3758 NOT_TENURED);
3759 slot->value_ = object;
3760 Handle<Object> properties = materializer.FieldAt(value_index);
3761 Handle<Object> elements = materializer.FieldAt(value_index);
3762 Handle<Object> prototype = materializer.FieldAt(value_index);
3763 Handle<Object> shared = materializer.FieldAt(value_index);
3764 Handle<Object> context = materializer.FieldAt(value_index);
3765 Handle<Object> literals = materializer.FieldAt(value_index);
3766 Handle<Object> entry = materializer.FieldAt(value_index);
3767 Handle<Object> next_link = materializer.FieldAt(value_index);
3768 object->ReplaceCode(*isolate_->builtins()->CompileLazy());
3769 object->set_map(*map);
3770 object->set_properties(FixedArray::cast(*properties));
3771 object->set_elements(FixedArrayBase::cast(*elements));
3772 object->set_prototype_or_initial_map(*prototype);
3773 object->set_shared(SharedFunctionInfo::cast(*shared));
3774 object->set_context(Context::cast(*context));
3775 object->set_literals(LiteralsArray::cast(*literals));
3776 CHECK(entry->IsNumber()); // Entry to compile lazy stub.
3777 CHECK(next_link->IsUndefined(isolate_));
3778 return object;
3779 }
3780 case CONS_STRING_TYPE: {
3781 Handle<ConsString> object = Handle<ConsString>::cast(
3782 isolate_->factory()
3783 ->NewConsString(isolate_->factory()->undefined_string(),
3784 isolate_->factory()->undefined_string())
3785 .ToHandleChecked());
3786 slot->value_ = object;
3787 Handle<Object> hash = materializer.FieldAt(value_index);
3788 Handle<Object> length = materializer.FieldAt(value_index);
3789 Handle<Object> first = materializer.FieldAt(value_index);
3790 Handle<Object> second = materializer.FieldAt(value_index);
3791 object->set_map(*map);
3792 object->set_length(Smi::cast(*length)->value());
3793 object->set_first(String::cast(*first));
3794 object->set_second(String::cast(*second));
3795 CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value.
3796 return object;
3797 }
3798 case CONTEXT_EXTENSION_TYPE: {
3799 Handle<ContextExtension> object =
3800 isolate_->factory()->NewContextExtension(
3801 isolate_->factory()->NewScopeInfo(1),
3802 isolate_->factory()->undefined_value());
3803 slot->value_ = object;
3804 Handle<Object> scope_info = materializer.FieldAt(value_index);
3805 Handle<Object> extension = materializer.FieldAt(value_index);
3806 object->set_scope_info(ScopeInfo::cast(*scope_info));
3807 object->set_extension(*extension);
3808 return object;
3809 }
3810 case FIXED_ARRAY_TYPE: {
3811 Handle<Object> lengthObject = materializer.FieldAt(value_index);
3812 int32_t length = 0;
3813 CHECK(lengthObject->ToInt32(&length));
3814 Handle<FixedArray> object = isolate_->factory()->NewFixedArray(length);
3815 // We need to set the map, because the fixed array we are
3816 // materializing could be a context or an arguments object,
3817 // in which case we must retain that information.
3818 object->set_map(*map);
3819 slot->value_ = object;
3820 for (int i = 0; i < length; ++i) {
3821 Handle<Object> value = materializer.FieldAt(value_index);
3822 object->set(i, *value);
3823 }
3824 return object;
3825 }
3826 case FIXED_DOUBLE_ARRAY_TYPE: {
3827 DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
3828 Handle<Object> lengthObject = materializer.FieldAt(value_index);
3829 int32_t length = 0;
3830 CHECK(lengthObject->ToInt32(&length));
3831 Handle<FixedArrayBase> object =
3832 isolate_->factory()->NewFixedDoubleArray(length);
3833 slot->value_ = object;
3834 if (length > 0) {
3835 Handle<FixedDoubleArray> double_array =
3836 Handle<FixedDoubleArray>::cast(object);
3837 for (int i = 0; i < length; ++i) {
3838 Handle<Object> value = materializer.FieldAt(value_index);
3839 CHECK(value->IsNumber());
3840 double_array->set(i, value->Number());
3841 }
3842 }
3843 return object;
3844 }
3845 case STRING_TYPE:
3846 case ONE_BYTE_STRING_TYPE:
3847 case CONS_ONE_BYTE_STRING_TYPE:
3848 case SLICED_STRING_TYPE:
3849 case SLICED_ONE_BYTE_STRING_TYPE:
3850 case EXTERNAL_STRING_TYPE:
3851 case EXTERNAL_ONE_BYTE_STRING_TYPE:
3852 case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
3853 case SHORT_EXTERNAL_STRING_TYPE:
3854 case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE:
3855 case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
3856 case INTERNALIZED_STRING_TYPE:
3857 case ONE_BYTE_INTERNALIZED_STRING_TYPE:
3858 case EXTERNAL_INTERNALIZED_STRING_TYPE:
3859 case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
3860 case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
3861 case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
3862 case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE:
3863 case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
3864 case SYMBOL_TYPE:
3865 case ODDBALL_TYPE:
3866 case SIMD128_VALUE_TYPE:
3867 case JS_GLOBAL_OBJECT_TYPE:
3868 case JS_GLOBAL_PROXY_TYPE:
3869 case JS_API_OBJECT_TYPE:
3870 case JS_SPECIAL_API_OBJECT_TYPE:
3871 case JS_VALUE_TYPE:
3872 case JS_MESSAGE_OBJECT_TYPE:
3873 case JS_DATE_TYPE:
3874 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
3875 case JS_GENERATOR_OBJECT_TYPE:
3876 case JS_MODULE_NAMESPACE_TYPE:
3877 case JS_ARRAY_BUFFER_TYPE:
3878 case JS_REGEXP_TYPE:
3879 case JS_TYPED_ARRAY_TYPE:
3880 case JS_DATA_VIEW_TYPE:
3881 case JS_SET_TYPE:
3882 case JS_MAP_TYPE:
3883 case JS_SET_ITERATOR_TYPE:
3884 case JS_MAP_ITERATOR_TYPE:
3885 case JS_STRING_ITERATOR_TYPE:
3886 case JS_WEAK_MAP_TYPE:
3887 case JS_WEAK_SET_TYPE:
3888 case JS_PROMISE_CAPABILITY_TYPE:
3889 case JS_PROMISE_TYPE:
3890 case JS_BOUND_FUNCTION_TYPE:
3891 case JS_PROXY_TYPE:
3892 case MAP_TYPE:
3893 case ALLOCATION_SITE_TYPE:
3894 case ACCESSOR_INFO_TYPE:
3895 case SHARED_FUNCTION_INFO_TYPE:
3896 case FUNCTION_TEMPLATE_INFO_TYPE:
3897 case ACCESSOR_PAIR_TYPE:
3898 case BYTE_ARRAY_TYPE:
3899 case BYTECODE_ARRAY_TYPE:
3900 case TRANSITION_ARRAY_TYPE:
3901 case FOREIGN_TYPE:
3902 case SCRIPT_TYPE:
3903 case CODE_TYPE:
3904 case PROPERTY_CELL_TYPE:
3905 case MODULE_TYPE:
3906 case MODULE_INFO_ENTRY_TYPE:
3907 case FREE_SPACE_TYPE:
3908 #define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
3909 case FIXED_##TYPE##_ARRAY_TYPE:
3910 TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE)
3911 #undef FIXED_TYPED_ARRAY_CASE
3912 case FILLER_TYPE:
3913 case ACCESS_CHECK_INFO_TYPE:
3914 case INTERCEPTOR_INFO_TYPE:
3915 case CALL_HANDLER_INFO_TYPE:
3916 case OBJECT_TEMPLATE_INFO_TYPE:
3917 case ALLOCATION_MEMENTO_TYPE:
3918 case TYPE_FEEDBACK_INFO_TYPE:
3919 case ALIASED_ARGUMENTS_ENTRY_TYPE:
3920 case BOX_TYPE:
3921 case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE:
3922 case PROMISE_REACTION_JOB_INFO_TYPE:
3923 case DEBUG_INFO_TYPE:
3924 case BREAK_POINT_INFO_TYPE:
3925 case CELL_TYPE:
3926 case WEAK_CELL_TYPE:
3927 case PROTOTYPE_INFO_TYPE:
3928 case TUPLE2_TYPE:
3929 case TUPLE3_TYPE:
3930 case CONSTANT_ELEMENTS_PAIR_TYPE:
3931 OFStream os(stderr);
3932 os << "[couldn't handle instance type " << map->instance_type() << "]"
3933 << std::endl;
3934 UNREACHABLE();
3935 break;
3936 }
3937 UNREACHABLE();
3938 return Handle<Object>::null();
3939 }
3617 3940
3618 Handle<Object> TranslatedState::MaterializeAt(int frame_index, 3941 Handle<Object> TranslatedState::MaterializeAt(int frame_index,
3619 int* value_index) { 3942 int* value_index) {
3620 CHECK_LT(static_cast<size_t>(frame_index), frames().size()); 3943 CHECK_LT(static_cast<size_t>(frame_index), frames().size());
3621 TranslatedFrame* frame = &(frames_[frame_index]); 3944 TranslatedFrame* frame = &(frames_[frame_index]);
3622 CHECK_LT(static_cast<size_t>(*value_index), frame->values_.size()); 3945 CHECK_LT(static_cast<size_t>(*value_index), frame->values_.size());
3623 3946
3624 TranslatedValue* slot = &(frame->values_[*value_index]); 3947 TranslatedValue* slot = &(frame->values_[*value_index]);
3625 (*value_index)++; 3948 (*value_index)++;
3626 3949
(...skipping 29 matching lines...) Expand all
3656 arguments->set_elements(*array); 3979 arguments->set_elements(*array);
3657 for (int i = 0; i < length; ++i) { 3980 for (int i = 0; i < length; ++i) {
3658 Handle<Object> value = MaterializeAt(frame_index, value_index); 3981 Handle<Object> value = MaterializeAt(frame_index, value_index);
3659 array->set(i, *value); 3982 array->set(i, *value);
3660 } 3983 }
3661 } 3984 }
3662 slot->value_ = arguments; 3985 slot->value_ = arguments;
3663 return arguments; 3986 return arguments;
3664 } 3987 }
3665 case TranslatedValue::kCapturedObject: { 3988 case TranslatedValue::kCapturedObject: {
3666 int length = slot->GetChildrenCount();
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
3691 // The map must be a tagged object. 3989 // The map must be a tagged object.
3692 CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged); 3990 CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged);
3693 3991 CHECK(frame->values_[*value_index].GetValue()->IsMap());
3694 Handle<Object> result; 3992 return MaterializeCapturedObjectAt(slot, frame_index, value_index);
3695 if (slot->value_.ToHandle(&result)) {
3696 // This has been previously materialized, return the previous value.
3697 // We still need to skip all the nested objects.
3698 for (int i = 0; i < length; i++) {
3699 materializer.At(value_index);
3700 }
3701
3702 return result;
3703 }
3704
3705 Handle<Object> map_object = materializer.At(value_index);
3706 Handle<Map> map = Map::GeneralizeAllFields(Handle<Map>::cast(map_object));
3707 switch (map->instance_type()) {
3708 case MUTABLE_HEAP_NUMBER_TYPE:
3709 case HEAP_NUMBER_TYPE: {
3710 // Reuse the HeapNumber value directly as it is already properly
3711 // tagged and skip materializing the HeapNumber explicitly.
3712 Handle<Object> object = materializer.At(value_index);
3713 slot->value_ = object;
3714 // On 32-bit architectures, there is an extra slot there because
3715 // the escape analysis calculates the number of slots as
3716 // object-size/pointer-size. To account for this, we read out
3717 // any extra slots.
3718 for (int i = 0; i < length - 2; i++) {
3719 materializer.At(value_index);
3720 }
3721 return object;
3722 }
3723 case JS_OBJECT_TYPE:
3724 case JS_ERROR_TYPE:
3725 case JS_ARGUMENTS_TYPE: {
3726 Handle<JSObject> object =
3727 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED);
3728 slot->value_ = object;
3729 Handle<Object> properties = materializer.At(value_index);
3730 Handle<Object> elements = materializer.At(value_index);
3731 object->set_properties(FixedArray::cast(*properties));
3732 object->set_elements(FixedArrayBase::cast(*elements));
3733 for (int i = 0; i < length - 3; ++i) {
3734 Handle<Object> value = materializer.At(value_index);
3735 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i);
3736 object->FastPropertyAtPut(index, *value);
3737 }
3738 return object;
3739 }
3740 case JS_ARRAY_TYPE: {
3741 Handle<JSArray> object = Handle<JSArray>::cast(
3742 isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
3743 slot->value_ = object;
3744 Handle<Object> properties = materializer.At(value_index);
3745 Handle<Object> elements = materializer.At(value_index);
3746 Handle<Object> length = materializer.At(value_index);
3747 object->set_properties(FixedArray::cast(*properties));
3748 object->set_elements(FixedArrayBase::cast(*elements));
3749 object->set_length(*length);
3750 return object;
3751 }
3752 case JS_FUNCTION_TYPE: {
3753 Handle<SharedFunctionInfo> temporary_shared =
3754 isolate_->factory()->NewSharedFunctionInfo(
3755 isolate_->factory()->empty_string(), MaybeHandle<Code>(),
3756 false);
3757 Handle<JSFunction> object =
3758 isolate_->factory()->NewFunctionFromSharedFunctionInfo(
3759 map, temporary_shared, isolate_->factory()->undefined_value(),
3760 NOT_TENURED);
3761 slot->value_ = object;
3762 Handle<Object> properties = materializer.At(value_index);
3763 Handle<Object> elements = materializer.At(value_index);
3764 Handle<Object> prototype = materializer.At(value_index);
3765 Handle<Object> shared = materializer.At(value_index);
3766 Handle<Object> context = materializer.At(value_index);
3767 Handle<Object> literals = materializer.At(value_index);
3768 Handle<Object> entry = materializer.At(value_index);
3769 Handle<Object> next_link = materializer.At(value_index);
3770 object->ReplaceCode(*isolate_->builtins()->CompileLazy());
3771 object->set_map(*map);
3772 object->set_properties(FixedArray::cast(*properties));
3773 object->set_elements(FixedArrayBase::cast(*elements));
3774 object->set_prototype_or_initial_map(*prototype);
3775 object->set_shared(SharedFunctionInfo::cast(*shared));
3776 object->set_context(Context::cast(*context));
3777 object->set_literals(LiteralsArray::cast(*literals));
3778 CHECK(entry->IsNumber()); // Entry to compile lazy stub.
3779 CHECK(next_link->IsUndefined(isolate_));
3780 return object;
3781 }
3782 case CONS_STRING_TYPE: {
3783 Handle<ConsString> object = Handle<ConsString>::cast(
3784 isolate_->factory()
3785 ->NewConsString(isolate_->factory()->undefined_string(),
3786 isolate_->factory()->undefined_string())
3787 .ToHandleChecked());
3788 slot->value_ = object;
3789 Handle<Object> hash = materializer.At(value_index);
3790 Handle<Object> length = materializer.At(value_index);
3791 Handle<Object> first = materializer.At(value_index);
3792 Handle<Object> second = materializer.At(value_index);
3793 object->set_map(*map);
3794 object->set_length(Smi::cast(*length)->value());
3795 object->set_first(String::cast(*first));
3796 object->set_second(String::cast(*second));
3797 CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value.
3798 return object;
3799 }
3800 case CONTEXT_EXTENSION_TYPE: {
3801 Handle<ContextExtension> object =
3802 isolate_->factory()->NewContextExtension(
3803 isolate_->factory()->NewScopeInfo(1),
3804 isolate_->factory()->undefined_value());
3805 slot->value_ = object;
3806 Handle<Object> scope_info = materializer.At(value_index);
3807 Handle<Object> extension = materializer.At(value_index);
3808 object->set_scope_info(ScopeInfo::cast(*scope_info));
3809 object->set_extension(*extension);
3810 return object;
3811 }
3812 case FIXED_ARRAY_TYPE: {
3813 Handle<Object> lengthObject = materializer.At(value_index);
3814 int32_t length = 0;
3815 CHECK(lengthObject->ToInt32(&length));
3816 Handle<FixedArray> object =
3817 isolate_->factory()->NewFixedArray(length);
3818 // We need to set the map, because the fixed array we are
3819 // materializing could be a context or an arguments object,
3820 // in which case we must retain that information.
3821 object->set_map(*map);
3822 slot->value_ = object;
3823 for (int i = 0; i < length; ++i) {
3824 Handle<Object> value = materializer.At(value_index);
3825 object->set(i, *value);
3826 }
3827 return object;
3828 }
3829 case FIXED_DOUBLE_ARRAY_TYPE: {
3830 DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map());
3831 Handle<Object> lengthObject = materializer.At(value_index);
3832 int32_t length = 0;
3833 CHECK(lengthObject->ToInt32(&length));
3834 Handle<FixedArrayBase> object =
3835 isolate_->factory()->NewFixedDoubleArray(length);
3836 slot->value_ = object;
3837 if (length > 0) {
3838 Handle<FixedDoubleArray> double_array =
3839 Handle<FixedDoubleArray>::cast(object);
3840 for (int i = 0; i < length; ++i) {
3841 Handle<Object> value = materializer.At(value_index);
3842 CHECK(value->IsNumber());
3843 double_array->set(i, value->Number());
3844 }
3845 }
3846 return object;
3847 }
3848 default:
3849 PrintF(stderr, "[couldn't handle instance type %d]\n",
3850 map->instance_type());
3851 FATAL("unreachable");
3852 return Handle<Object>::null();
3853 }
3854 UNREACHABLE();
3855 break;
3856 } 3993 }
3857
3858 case TranslatedValue::kDuplicatedObject: { 3994 case TranslatedValue::kDuplicatedObject: {
3859 int object_index = slot->object_index(); 3995 int object_index = slot->object_index();
3860 TranslatedState::ObjectPosition pos = object_positions_[object_index]; 3996 TranslatedState::ObjectPosition pos = object_positions_[object_index];
3861 3997
3862 // Make sure the duplicate is refering to a previous object. 3998 // Make sure the duplicate is refering to a previous object.
3863 CHECK(pos.frame_index_ < frame_index || 3999 CHECK(pos.frame_index_ < frame_index ||
3864 (pos.frame_index_ == frame_index && 4000 (pos.frame_index_ == frame_index &&
3865 pos.value_index_ < *value_index - 1)); 4001 pos.value_index_ < *value_index - 1));
3866 4002
3867 Handle<Object> object = 4003 Handle<Object> object =
3868 frames_[pos.frame_index_].values_[pos.value_index_].GetValue(); 4004 frames_[pos.frame_index_].values_[pos.value_index_].GetValue();
3869 4005
3870 // The object should have a (non-sentinel) value. 4006 // The object should have a (non-sentinel) value.
3871 CHECK(!object.is_null() && 4007 CHECK(!object.is_null() &&
3872 !object.is_identical_to(isolate_->factory()->arguments_marker())); 4008 !object.is_identical_to(isolate_->factory()->arguments_marker()));
3873 4009
3874 slot->value_ = object; 4010 slot->value_ = object;
3875 return object; 4011 return object;
3876 } 4012 }
3877 4013
3878 case TranslatedValue::kInvalid: 4014 case TranslatedValue::kInvalid:
3879 UNREACHABLE(); 4015 UNREACHABLE();
3880 break; 4016 break;
3881 } 4017 }
3882 4018
3883 FATAL("We should never get here - unexpected deopt slot kind."); 4019 FATAL("We should never get here - unexpected deopt slot kind.");
3884 return Handle<Object>::null(); 4020 return Handle<Object>::null();
3885 } 4021 }
3886 4022
3887
3888 Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) { 4023 Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) {
3889 CHECK_LT(static_cast<size_t>(object_index), object_positions_.size()); 4024 CHECK_LT(static_cast<size_t>(object_index), object_positions_.size());
3890 TranslatedState::ObjectPosition pos = object_positions_[object_index]; 4025 TranslatedState::ObjectPosition pos = object_positions_[object_index];
3891 return MaterializeAt(pos.frame_index_, &(pos.value_index_)); 4026 return MaterializeAt(pos.frame_index_, &(pos.value_index_));
3892 } 4027 }
3893 4028
3894
3895 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, 4029 bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result,
3896 int frame_index) { 4030 int frame_index) {
3897 if (frame_index == 0) { 4031 if (frame_index == 0) {
3898 // Top level frame -> we need to go to the parent frame on the stack. 4032 // Top level frame -> we need to go to the parent frame on the stack.
3899 if (!has_adapted_arguments_) return false; 4033 if (!has_adapted_arguments_) return false;
3900 4034
3901 // This is top level frame, so we need to go to the stack to get 4035 // This is top level frame, so we need to go to the stack to get
3902 // this function's argument. (Note that this relies on not inlining 4036 // this function's argument. (Note that this relies on not inlining
3903 // recursive functions!) 4037 // recursive functions!)
3904 Handle<JSFunction> function = 4038 Handle<JSFunction> function =
(...skipping 19 matching lines...) Expand all
3924 Handle<Object> value = arg_iterator->GetValue(); 4058 Handle<Object> value = arg_iterator->GetValue();
3925 array->set(i, *value); 4059 array->set(i, *value);
3926 arg_iterator++; 4060 arg_iterator++;
3927 } 4061 }
3928 CHECK(arg_iterator == previous_frame->end()); 4062 CHECK(arg_iterator == previous_frame->end());
3929 *result = arguments; 4063 *result = arguments;
3930 return true; 4064 return true;
3931 } 4065 }
3932 } 4066 }
3933 4067
3934
3935 TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex( 4068 TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex(
3936 int jsframe_index, int* args_count) { 4069 int jsframe_index, int* args_count) {
3937 for (size_t i = 0; i < frames_.size(); i++) { 4070 for (size_t i = 0; i < frames_.size(); i++) {
3938 if (frames_[i].kind() == TranslatedFrame::kFunction || 4071 if (frames_[i].kind() == TranslatedFrame::kFunction ||
3939 frames_[i].kind() == TranslatedFrame::kInterpretedFunction) { 4072 frames_[i].kind() == TranslatedFrame::kInterpretedFunction) {
3940 if (jsframe_index > 0) { 4073 if (jsframe_index > 0) {
3941 jsframe_index--; 4074 jsframe_index--;
3942 } else { 4075 } else {
3943 // We have the JS function frame, now check if it has arguments adaptor. 4076 // We have the JS function frame, now check if it has arguments
4077 // adaptor.
3944 if (i > 0 && 4078 if (i > 0 &&
3945 frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) { 4079 frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) {
3946 *args_count = frames_[i - 1].height(); 4080 *args_count = frames_[i - 1].height();
3947 return &(frames_[i - 1]); 4081 return &(frames_[i - 1]);
3948 } 4082 }
3949 *args_count = 4083 *args_count =
3950 frames_[i].shared_info()->internal_formal_parameter_count() + 1; 4084 frames_[i].shared_info()->internal_formal_parameter_count() + 1;
3951 return &(frames_[i]); 4085 return &(frames_[i]);
3952 } 4086 }
3953 } 4087 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3999 materialized_store->Set(stack_frame_pointer_, 4133 materialized_store->Set(stack_frame_pointer_,
4000 previously_materialized_objects); 4134 previously_materialized_objects);
4001 CHECK(frames_[0].kind() == TranslatedFrame::kFunction || 4135 CHECK(frames_[0].kind() == TranslatedFrame::kFunction ||
4002 frames_[0].kind() == TranslatedFrame::kInterpretedFunction || 4136 frames_[0].kind() == TranslatedFrame::kInterpretedFunction ||
4003 frames_[0].kind() == TranslatedFrame::kTailCallerFunction); 4137 frames_[0].kind() == TranslatedFrame::kTailCallerFunction);
4004 CHECK_EQ(frame->function(), frames_[0].front().GetRawValue()); 4138 CHECK_EQ(frame->function(), frames_[0].front().GetRawValue());
4005 Deoptimizer::DeoptimizeFunction(frame->function(), frame->LookupCode()); 4139 Deoptimizer::DeoptimizeFunction(frame->function(), frame->LookupCode());
4006 } 4140 }
4007 } 4141 }
4008 4142
4009
4010 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { 4143 void TranslatedState::UpdateFromPreviouslyMaterializedObjects() {
4011 MaterializedObjectStore* materialized_store = 4144 MaterializedObjectStore* materialized_store =
4012 isolate_->materialized_object_store(); 4145 isolate_->materialized_object_store();
4013 Handle<FixedArray> previously_materialized_objects = 4146 Handle<FixedArray> previously_materialized_objects =
4014 materialized_store->Get(stack_frame_pointer_); 4147 materialized_store->Get(stack_frame_pointer_);
4015 4148
4016 // If we have no previously materialized objects, there is nothing to do. 4149 // If we have no previously materialized objects, there is nothing to do.
4017 if (previously_materialized_objects.is_null()) return; 4150 if (previously_materialized_objects.is_null()) return;
4018 4151
4019 Handle<Object> marker = isolate_->factory()->arguments_marker(); 4152 Handle<Object> marker = isolate_->factory()->arguments_marker();
(...skipping 11 matching lines...) Expand all
4031 CHECK(value_info->IsMaterializedObject()); 4164 CHECK(value_info->IsMaterializedObject());
4032 4165
4033 value_info->value_ = 4166 value_info->value_ =
4034 Handle<Object>(previously_materialized_objects->get(i), isolate_); 4167 Handle<Object>(previously_materialized_objects->get(i), isolate_);
4035 } 4168 }
4036 } 4169 }
4037 } 4170 }
4038 4171
4039 } // namespace internal 4172 } // namespace internal
4040 } // namespace v8 4173 } // namespace v8
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | test/mjsunit/regress/regress-681383.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698