// Copyright 2021 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/deoptimizer/deoptimized-frame-info.h" #include "src/execution/isolate.h" #include "src/objects/js-function-inl.h" #include "src/objects/oddball.h" namespace v8 { namespace internal { namespace { Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it, Isolate* isolate) { if (it->GetRawValue() == ReadOnlyRoots(isolate).arguments_marker() && !it->IsMaterializableByDebugger()) { return isolate->factory()->optimized_out(); } return it->GetValue(); } } // namespace DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state, TranslatedState::iterator frame_it, Isolate* isolate) { int parameter_count = frame_it->shared_info()->internal_formal_parameter_count(); TranslatedFrame::iterator stack_it = frame_it->begin(); // Get the function. Note that this might materialize the function. // In case the debugger mutates this value, we should deoptimize // the function and remember the value in the materialized value store. DCHECK_EQ(parameter_count, Handle<JSFunction>::cast(stack_it->GetValue()) ->shared() .internal_formal_parameter_count()); stack_it++; // Skip the function. stack_it++; // Skip the receiver. DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind()); parameters_.resize(static_cast<size_t>(parameter_count)); for (int i = 0; i < parameter_count; i++) { Handle<Object> parameter = GetValueForDebugger(stack_it, isolate); SetParameter(i, parameter); stack_it++; } // Get the context. context_ = GetValueForDebugger(stack_it, isolate); stack_it++; // Get the expression stack. DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind()); const int stack_height = frame_it->height(); // Accumulator *not* included. expression_stack_.resize(static_cast<size_t>(stack_height)); for (int i = 0; i < stack_height; i++) { Handle<Object> expression = GetValueForDebugger(stack_it, isolate); SetExpression(i, expression); stack_it++; } DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind()); stack_it++; // Skip the accumulator. CHECK(stack_it == frame_it->end()); } } // namespace internal } // namespace v8