blob: 7e2709611c8e04d78aa08d38dcb0a7a135d7a872 [file] [log] [blame]
// 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_without_receiver();
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,
Cast<JSFunction>(stack_it->GetValue())
->shared()
->internal_formal_parameter_count_without_receiver());
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