Index: src/deoptimizer.cc |
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc |
index 91ab4513a329e2f0190e04af9210ba0951c85fdd..97f82cb3e12950ffc3a04acc1c9879c97f5f849e 100644 |
--- a/src/deoptimizer.cc |
+++ b/src/deoptimizer.cc |
@@ -3614,6 +3614,329 @@ void TranslatedState::Prepare(bool has_adapted_arguments, |
UpdateFromPreviouslyMaterializedObjects(); |
} |
+class TranslatedState::CapturedObjectMaterializer { |
+ public: |
+ CapturedObjectMaterializer(TranslatedState* state, int frame_index, |
+ int field_count) |
+ : state_(state), frame_index_(frame_index), field_count_(field_count) {} |
+ |
+ Handle<Object> FieldAt(int* value_index) { |
+ CHECK(field_count_ > 0); |
+ --field_count_; |
+ return state_->MaterializeAt(frame_index_, value_index); |
+ } |
+ |
+ ~CapturedObjectMaterializer() { CHECK_EQ(0, field_count_); } |
+ |
+ private: |
+ TranslatedState* state_; |
+ int frame_index_; |
+ int field_count_; |
+}; |
+ |
+Handle<Object> TranslatedState::MaterializeCapturedObjectAt( |
+ TranslatedValue* slot, int frame_index, int* value_index) { |
+ int length = slot->GetChildrenCount(); |
+ |
+ CapturedObjectMaterializer materializer(this, frame_index, length); |
+ |
+ Handle<Object> result; |
+ if (slot->value_.ToHandle(&result)) { |
+ // This has been previously materialized, return the previous value. |
+ // We still need to skip all the nested objects. |
+ for (int i = 0; i < length; i++) { |
+ materializer.FieldAt(value_index); |
+ } |
+ |
+ return result; |
+ } |
+ |
+ Handle<Object> map_object = materializer.FieldAt(value_index); |
+ Handle<Map> map = Map::GeneralizeAllFields(Handle<Map>::cast(map_object)); |
+ switch (map->instance_type()) { |
+ case MUTABLE_HEAP_NUMBER_TYPE: |
+ case HEAP_NUMBER_TYPE: { |
+ // Reuse the HeapNumber value directly as it is already properly |
+ // tagged and skip materializing the HeapNumber explicitly. |
+ Handle<Object> object = materializer.FieldAt(value_index); |
+ slot->value_ = object; |
+ // On 32-bit architectures, there is an extra slot there because |
+ // the escape analysis calculates the number of slots as |
+ // object-size/pointer-size. To account for this, we read out |
+ // any extra slots. |
+ for (int i = 0; i < length - 2; i++) { |
+ materializer.FieldAt(value_index); |
+ } |
+ return object; |
+ } |
+ case JS_OBJECT_TYPE: |
+ case JS_ERROR_TYPE: |
+ case JS_ARGUMENTS_TYPE: { |
+ Handle<JSObject> object = |
+ isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED); |
+ slot->value_ = object; |
+ Handle<Object> properties = materializer.FieldAt(value_index); |
+ Handle<Object> elements = materializer.FieldAt(value_index); |
+ object->set_properties(FixedArray::cast(*properties)); |
+ object->set_elements(FixedArrayBase::cast(*elements)); |
+ for (int i = 0; i < length - 3; ++i) { |
+ Handle<Object> value = materializer.FieldAt(value_index); |
+ FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i); |
+ object->FastPropertyAtPut(index, *value); |
+ } |
+ return object; |
+ } |
+ case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE: |
+ case JS_FAST_ARRAY_KEY_ITERATOR_TYPE: |
+ case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE: |
+ case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE: |
+ case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE: { |
+ Handle<JSArrayIterator> object = Handle<JSArrayIterator>::cast( |
+ isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED)); |
+ slot->value_ = object; |
+ Handle<Object> properties = materializer.FieldAt(value_index); |
+ Handle<Object> elements = materializer.FieldAt(value_index); |
+ Handle<Object> iterated_object = materializer.FieldAt(value_index); |
+ Handle<Object> next_index = materializer.FieldAt(value_index); |
+ Handle<Object> iterated_object_map = materializer.FieldAt(value_index); |
+ object->set_properties(FixedArray::cast(*properties)); |
+ object->set_elements(FixedArrayBase::cast(*elements)); |
+ object->set_object(*iterated_object); |
+ object->set_index(*next_index); |
+ object->set_object_map(*iterated_object_map); |
+ return object; |
+ } |
+ case JS_ARRAY_TYPE: { |
+ Handle<JSArray> object = Handle<JSArray>::cast( |
+ isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED)); |
+ slot->value_ = object; |
+ Handle<Object> properties = materializer.FieldAt(value_index); |
+ Handle<Object> elements = materializer.FieldAt(value_index); |
+ Handle<Object> length = materializer.FieldAt(value_index); |
+ object->set_properties(FixedArray::cast(*properties)); |
+ object->set_elements(FixedArrayBase::cast(*elements)); |
+ object->set_length(*length); |
+ return object; |
+ } |
+ case JS_FUNCTION_TYPE: { |
+ Handle<SharedFunctionInfo> temporary_shared = |
+ isolate_->factory()->NewSharedFunctionInfo( |
+ isolate_->factory()->empty_string(), MaybeHandle<Code>(), false); |
+ Handle<JSFunction> object = |
+ isolate_->factory()->NewFunctionFromSharedFunctionInfo( |
+ map, temporary_shared, isolate_->factory()->undefined_value(), |
+ NOT_TENURED); |
+ slot->value_ = object; |
+ Handle<Object> properties = materializer.FieldAt(value_index); |
+ Handle<Object> elements = materializer.FieldAt(value_index); |
+ Handle<Object> prototype = materializer.FieldAt(value_index); |
+ Handle<Object> shared = materializer.FieldAt(value_index); |
+ Handle<Object> context = materializer.FieldAt(value_index); |
+ Handle<Object> literals = materializer.FieldAt(value_index); |
+ Handle<Object> entry = materializer.FieldAt(value_index); |
+ Handle<Object> next_link = materializer.FieldAt(value_index); |
+ object->ReplaceCode(*isolate_->builtins()->CompileLazy()); |
+ object->set_map(*map); |
+ object->set_properties(FixedArray::cast(*properties)); |
+ object->set_elements(FixedArrayBase::cast(*elements)); |
+ object->set_prototype_or_initial_map(*prototype); |
+ object->set_shared(SharedFunctionInfo::cast(*shared)); |
+ object->set_context(Context::cast(*context)); |
+ object->set_literals(LiteralsArray::cast(*literals)); |
+ CHECK(entry->IsNumber()); // Entry to compile lazy stub. |
+ CHECK(next_link->IsUndefined(isolate_)); |
+ return object; |
+ } |
+ case CONS_STRING_TYPE: { |
+ Handle<ConsString> object = Handle<ConsString>::cast( |
+ isolate_->factory() |
+ ->NewConsString(isolate_->factory()->undefined_string(), |
+ isolate_->factory()->undefined_string()) |
+ .ToHandleChecked()); |
+ slot->value_ = object; |
+ Handle<Object> hash = materializer.FieldAt(value_index); |
+ Handle<Object> length = materializer.FieldAt(value_index); |
+ Handle<Object> first = materializer.FieldAt(value_index); |
+ Handle<Object> second = materializer.FieldAt(value_index); |
+ object->set_map(*map); |
+ object->set_length(Smi::cast(*length)->value()); |
+ object->set_first(String::cast(*first)); |
+ object->set_second(String::cast(*second)); |
+ CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value. |
+ return object; |
+ } |
+ case CONTEXT_EXTENSION_TYPE: { |
+ Handle<ContextExtension> object = |
+ isolate_->factory()->NewContextExtension( |
+ isolate_->factory()->NewScopeInfo(1), |
+ isolate_->factory()->undefined_value()); |
+ slot->value_ = object; |
+ Handle<Object> scope_info = materializer.FieldAt(value_index); |
+ Handle<Object> extension = materializer.FieldAt(value_index); |
+ object->set_scope_info(ScopeInfo::cast(*scope_info)); |
+ object->set_extension(*extension); |
+ return object; |
+ } |
+ case FIXED_ARRAY_TYPE: { |
+ Handle<Object> lengthObject = materializer.FieldAt(value_index); |
+ int32_t length = 0; |
+ CHECK(lengthObject->ToInt32(&length)); |
+ Handle<FixedArray> object = isolate_->factory()->NewFixedArray(length); |
+ // We need to set the map, because the fixed array we are |
+ // materializing could be a context or an arguments object, |
+ // in which case we must retain that information. |
+ object->set_map(*map); |
+ slot->value_ = object; |
+ for (int i = 0; i < length; ++i) { |
+ Handle<Object> value = materializer.FieldAt(value_index); |
+ object->set(i, *value); |
+ } |
+ return object; |
+ } |
+ case FIXED_DOUBLE_ARRAY_TYPE: { |
+ DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map()); |
+ Handle<Object> lengthObject = materializer.FieldAt(value_index); |
+ int32_t length = 0; |
+ CHECK(lengthObject->ToInt32(&length)); |
+ Handle<FixedArrayBase> object = |
+ isolate_->factory()->NewFixedDoubleArray(length); |
+ slot->value_ = object; |
+ if (length > 0) { |
+ Handle<FixedDoubleArray> double_array = |
+ Handle<FixedDoubleArray>::cast(object); |
+ for (int i = 0; i < length; ++i) { |
+ Handle<Object> value = materializer.FieldAt(value_index); |
+ CHECK(value->IsNumber()); |
+ double_array->set(i, value->Number()); |
+ } |
+ } |
+ return object; |
+ } |
+ case STRING_TYPE: |
+ case ONE_BYTE_STRING_TYPE: |
+ case CONS_ONE_BYTE_STRING_TYPE: |
+ case SLICED_STRING_TYPE: |
+ case SLICED_ONE_BYTE_STRING_TYPE: |
+ case EXTERNAL_STRING_TYPE: |
+ case EXTERNAL_ONE_BYTE_STRING_TYPE: |
+ case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
+ case SHORT_EXTERNAL_STRING_TYPE: |
+ case SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE: |
+ case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE: |
+ case INTERNALIZED_STRING_TYPE: |
+ case ONE_BYTE_INTERNALIZED_STRING_TYPE: |
+ case EXTERNAL_INTERNALIZED_STRING_TYPE: |
+ case EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE: |
+ case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: |
+ case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE: |
+ case SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE: |
+ case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE: |
+ case SYMBOL_TYPE: |
+ case ODDBALL_TYPE: |
+ case SIMD128_VALUE_TYPE: |
+ case JS_GLOBAL_OBJECT_TYPE: |
+ case JS_GLOBAL_PROXY_TYPE: |
+ case JS_API_OBJECT_TYPE: |
+ case JS_SPECIAL_API_OBJECT_TYPE: |
+ case JS_VALUE_TYPE: |
+ case JS_MESSAGE_OBJECT_TYPE: |
+ case JS_DATE_TYPE: |
+ case JS_CONTEXT_EXTENSION_OBJECT_TYPE: |
+ case JS_GENERATOR_OBJECT_TYPE: |
+ case JS_MODULE_NAMESPACE_TYPE: |
+ case JS_ARRAY_BUFFER_TYPE: |
+ case JS_REGEXP_TYPE: |
+ case JS_TYPED_ARRAY_TYPE: |
+ case JS_DATA_VIEW_TYPE: |
+ case JS_SET_TYPE: |
+ case JS_MAP_TYPE: |
+ case JS_SET_ITERATOR_TYPE: |
+ case JS_MAP_ITERATOR_TYPE: |
+ case JS_STRING_ITERATOR_TYPE: |
+ case JS_WEAK_MAP_TYPE: |
+ case JS_WEAK_SET_TYPE: |
+ case JS_PROMISE_CAPABILITY_TYPE: |
+ case JS_PROMISE_TYPE: |
+ case JS_BOUND_FUNCTION_TYPE: |
+ case JS_PROXY_TYPE: |
+ case MAP_TYPE: |
+ case ALLOCATION_SITE_TYPE: |
+ case ACCESSOR_INFO_TYPE: |
+ case SHARED_FUNCTION_INFO_TYPE: |
+ case FUNCTION_TEMPLATE_INFO_TYPE: |
+ case ACCESSOR_PAIR_TYPE: |
+ case BYTE_ARRAY_TYPE: |
+ case BYTECODE_ARRAY_TYPE: |
+ case TRANSITION_ARRAY_TYPE: |
+ case FOREIGN_TYPE: |
+ case SCRIPT_TYPE: |
+ case CODE_TYPE: |
+ case PROPERTY_CELL_TYPE: |
+ case MODULE_TYPE: |
+ case MODULE_INFO_ENTRY_TYPE: |
+ case FREE_SPACE_TYPE: |
+#define FIXED_TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
+ case FIXED_##TYPE##_ARRAY_TYPE: |
+ TYPED_ARRAYS(FIXED_TYPED_ARRAY_CASE) |
+#undef FIXED_TYPED_ARRAY_CASE |
+ case FILLER_TYPE: |
+ case ACCESS_CHECK_INFO_TYPE: |
+ case INTERCEPTOR_INFO_TYPE: |
+ case CALL_HANDLER_INFO_TYPE: |
+ case OBJECT_TEMPLATE_INFO_TYPE: |
+ case ALLOCATION_MEMENTO_TYPE: |
+ case TYPE_FEEDBACK_INFO_TYPE: |
+ case ALIASED_ARGUMENTS_ENTRY_TYPE: |
+ case BOX_TYPE: |
+ case PROMISE_RESOLVE_THENABLE_JOB_INFO_TYPE: |
+ case PROMISE_REACTION_JOB_INFO_TYPE: |
+ case DEBUG_INFO_TYPE: |
+ case BREAK_POINT_INFO_TYPE: |
+ case CELL_TYPE: |
+ case WEAK_CELL_TYPE: |
+ case PROTOTYPE_INFO_TYPE: |
+ case TUPLE2_TYPE: |
+ case TUPLE3_TYPE: |
+ case CONSTANT_ELEMENTS_PAIR_TYPE: |
+ OFStream os(stderr); |
+ os << "[couldn't handle instance type " << map->instance_type() << "]" |
+ << std::endl; |
+ UNREACHABLE(); |
+ break; |
+ } |
+ UNREACHABLE(); |
+ return Handle<Object>::null(); |
+} |
Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
int* value_index) { |
@@ -3663,198 +3986,11 @@ Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
return arguments; |
} |
case TranslatedValue::kCapturedObject: { |
- int length = slot->GetChildrenCount(); |
- |
- class FieldMaterializer { |
- public: |
- FieldMaterializer(TranslatedState* state, int frame_index, |
- int field_count) |
- : state_(state), |
- frame_index_(frame_index), |
- field_count_(field_count) {} |
- |
- Handle<Object> At(int* value_index) { |
- CHECK(field_count_ > 0); |
- --field_count_; |
- return state_->MaterializeAt(frame_index_, value_index); |
- } |
- |
- ~FieldMaterializer() { CHECK_EQ(0, field_count_); } |
- |
- private: |
- TranslatedState* state_; |
- int frame_index_; |
- int field_count_; |
- }; |
- FieldMaterializer materializer(this, frame_index, length); |
- |
// The map must be a tagged object. |
CHECK(frame->values_[*value_index].kind() == TranslatedValue::kTagged); |
- |
- Handle<Object> result; |
- if (slot->value_.ToHandle(&result)) { |
- // This has been previously materialized, return the previous value. |
- // We still need to skip all the nested objects. |
- for (int i = 0; i < length; i++) { |
- materializer.At(value_index); |
- } |
- |
- return result; |
- } |
- |
- Handle<Object> map_object = materializer.At(value_index); |
- Handle<Map> map = Map::GeneralizeAllFields(Handle<Map>::cast(map_object)); |
- switch (map->instance_type()) { |
- case MUTABLE_HEAP_NUMBER_TYPE: |
- case HEAP_NUMBER_TYPE: { |
- // Reuse the HeapNumber value directly as it is already properly |
- // tagged and skip materializing the HeapNumber explicitly. |
- Handle<Object> object = materializer.At(value_index); |
- slot->value_ = object; |
- // On 32-bit architectures, there is an extra slot there because |
- // the escape analysis calculates the number of slots as |
- // object-size/pointer-size. To account for this, we read out |
- // any extra slots. |
- for (int i = 0; i < length - 2; i++) { |
- materializer.At(value_index); |
- } |
- return object; |
- } |
- case JS_OBJECT_TYPE: |
- case JS_ERROR_TYPE: |
- case JS_ARGUMENTS_TYPE: { |
- Handle<JSObject> object = |
- isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED); |
- slot->value_ = object; |
- Handle<Object> properties = materializer.At(value_index); |
- Handle<Object> elements = materializer.At(value_index); |
- object->set_properties(FixedArray::cast(*properties)); |
- object->set_elements(FixedArrayBase::cast(*elements)); |
- for (int i = 0; i < length - 3; ++i) { |
- Handle<Object> value = materializer.At(value_index); |
- FieldIndex index = FieldIndex::ForPropertyIndex(object->map(), i); |
- object->FastPropertyAtPut(index, *value); |
- } |
- return object; |
- } |
- case JS_ARRAY_TYPE: { |
- Handle<JSArray> object = Handle<JSArray>::cast( |
- isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED)); |
- slot->value_ = object; |
- Handle<Object> properties = materializer.At(value_index); |
- Handle<Object> elements = materializer.At(value_index); |
- Handle<Object> length = materializer.At(value_index); |
- object->set_properties(FixedArray::cast(*properties)); |
- object->set_elements(FixedArrayBase::cast(*elements)); |
- object->set_length(*length); |
- return object; |
- } |
- case JS_FUNCTION_TYPE: { |
- Handle<SharedFunctionInfo> temporary_shared = |
- isolate_->factory()->NewSharedFunctionInfo( |
- isolate_->factory()->empty_string(), MaybeHandle<Code>(), |
- false); |
- Handle<JSFunction> object = |
- isolate_->factory()->NewFunctionFromSharedFunctionInfo( |
- map, temporary_shared, isolate_->factory()->undefined_value(), |
- NOT_TENURED); |
- slot->value_ = object; |
- Handle<Object> properties = materializer.At(value_index); |
- Handle<Object> elements = materializer.At(value_index); |
- Handle<Object> prototype = materializer.At(value_index); |
- Handle<Object> shared = materializer.At(value_index); |
- Handle<Object> context = materializer.At(value_index); |
- Handle<Object> literals = materializer.At(value_index); |
- Handle<Object> entry = materializer.At(value_index); |
- Handle<Object> next_link = materializer.At(value_index); |
- object->ReplaceCode(*isolate_->builtins()->CompileLazy()); |
- object->set_map(*map); |
- object->set_properties(FixedArray::cast(*properties)); |
- object->set_elements(FixedArrayBase::cast(*elements)); |
- object->set_prototype_or_initial_map(*prototype); |
- object->set_shared(SharedFunctionInfo::cast(*shared)); |
- object->set_context(Context::cast(*context)); |
- object->set_literals(LiteralsArray::cast(*literals)); |
- CHECK(entry->IsNumber()); // Entry to compile lazy stub. |
- CHECK(next_link->IsUndefined(isolate_)); |
- return object; |
- } |
- case CONS_STRING_TYPE: { |
- Handle<ConsString> object = Handle<ConsString>::cast( |
- isolate_->factory() |
- ->NewConsString(isolate_->factory()->undefined_string(), |
- isolate_->factory()->undefined_string()) |
- .ToHandleChecked()); |
- slot->value_ = object; |
- Handle<Object> hash = materializer.At(value_index); |
- Handle<Object> length = materializer.At(value_index); |
- Handle<Object> first = materializer.At(value_index); |
- Handle<Object> second = materializer.At(value_index); |
- object->set_map(*map); |
- object->set_length(Smi::cast(*length)->value()); |
- object->set_first(String::cast(*first)); |
- object->set_second(String::cast(*second)); |
- CHECK(hash->IsNumber()); // The {Name::kEmptyHashField} value. |
- return object; |
- } |
- case CONTEXT_EXTENSION_TYPE: { |
- Handle<ContextExtension> object = |
- isolate_->factory()->NewContextExtension( |
- isolate_->factory()->NewScopeInfo(1), |
- isolate_->factory()->undefined_value()); |
- slot->value_ = object; |
- Handle<Object> scope_info = materializer.At(value_index); |
- Handle<Object> extension = materializer.At(value_index); |
- object->set_scope_info(ScopeInfo::cast(*scope_info)); |
- object->set_extension(*extension); |
- return object; |
- } |
- case FIXED_ARRAY_TYPE: { |
- Handle<Object> lengthObject = materializer.At(value_index); |
- int32_t length = 0; |
- CHECK(lengthObject->ToInt32(&length)); |
- Handle<FixedArray> object = |
- isolate_->factory()->NewFixedArray(length); |
- // We need to set the map, because the fixed array we are |
- // materializing could be a context or an arguments object, |
- // in which case we must retain that information. |
- object->set_map(*map); |
- slot->value_ = object; |
- for (int i = 0; i < length; ++i) { |
- Handle<Object> value = materializer.At(value_index); |
- object->set(i, *value); |
- } |
- return object; |
- } |
- case FIXED_DOUBLE_ARRAY_TYPE: { |
- DCHECK_EQ(*map, isolate_->heap()->fixed_double_array_map()); |
- Handle<Object> lengthObject = materializer.At(value_index); |
- int32_t length = 0; |
- CHECK(lengthObject->ToInt32(&length)); |
- Handle<FixedArrayBase> object = |
- isolate_->factory()->NewFixedDoubleArray(length); |
- slot->value_ = object; |
- if (length > 0) { |
- Handle<FixedDoubleArray> double_array = |
- Handle<FixedDoubleArray>::cast(object); |
- for (int i = 0; i < length; ++i) { |
- Handle<Object> value = materializer.At(value_index); |
- CHECK(value->IsNumber()); |
- double_array->set(i, value->Number()); |
- } |
- } |
- return object; |
- } |
- default: |
- PrintF(stderr, "[couldn't handle instance type %d]\n", |
- map->instance_type()); |
- FATAL("unreachable"); |
- return Handle<Object>::null(); |
- } |
- UNREACHABLE(); |
- break; |
+ CHECK(frame->values_[*value_index].GetValue()->IsMap()); |
+ return MaterializeCapturedObjectAt(slot, frame_index, value_index); |
} |
- |
case TranslatedValue::kDuplicatedObject: { |
int object_index = slot->object_index(); |
TranslatedState::ObjectPosition pos = object_positions_[object_index]; |
@@ -3884,14 +4020,12 @@ Handle<Object> TranslatedState::MaterializeAt(int frame_index, |
return Handle<Object>::null(); |
} |
- |
Handle<Object> TranslatedState::MaterializeObjectAt(int object_index) { |
CHECK_LT(static_cast<size_t>(object_index), object_positions_.size()); |
TranslatedState::ObjectPosition pos = object_positions_[object_index]; |
return MaterializeAt(pos.frame_index_, &(pos.value_index_)); |
} |
- |
bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, |
int frame_index) { |
if (frame_index == 0) { |
@@ -3931,7 +4065,6 @@ bool TranslatedState::GetAdaptedArguments(Handle<JSObject>* result, |
} |
} |
- |
TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex( |
int jsframe_index, int* args_count) { |
for (size_t i = 0; i < frames_.size(); i++) { |
@@ -3940,7 +4073,8 @@ TranslatedFrame* TranslatedState::GetArgumentsInfoFromJSFrameIndex( |
if (jsframe_index > 0) { |
jsframe_index--; |
} else { |
- // We have the JS function frame, now check if it has arguments adaptor. |
+ // We have the JS function frame, now check if it has arguments |
+ // adaptor. |
if (i > 0 && |
frames_[i - 1].kind() == TranslatedFrame::kArgumentsAdaptor) { |
*args_count = frames_[i - 1].height(); |
@@ -4006,7 +4140,6 @@ void TranslatedState::StoreMaterializedValuesAndDeopt(JavaScriptFrame* frame) { |
} |
} |
- |
void TranslatedState::UpdateFromPreviouslyMaterializedObjects() { |
MaterializedObjectStore* materialized_store = |
isolate_->materialized_object_store(); |