1// Copyright 2021 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/deoptimizer/deoptimized-frame-info.h"
6
7#include "src/execution/isolate.h"
8#include "src/objects/js-function-inl.h"
9#include "src/objects/oddball.h"
10
11namespace v8 {
12namespace internal {
13namespace {
14
15Handle<Object> GetValueForDebugger(TranslatedFrame::iterator it,
16                                   Isolate* isolate) {
17  if (it->GetRawValue() == ReadOnlyRoots(isolate).arguments_marker() &&
18      !it->IsMaterializableByDebugger()) {
19    return isolate->factory()->optimized_out();
20  }
21  return it->GetValue();
22}
23
24}  // namespace
25
26DeoptimizedFrameInfo::DeoptimizedFrameInfo(TranslatedState* state,
27                                           TranslatedState::iterator frame_it,
28                                           Isolate* isolate) {
29  int parameter_count =
30      frame_it->shared_info()
31          ->internal_formal_parameter_count_without_receiver();
32  TranslatedFrame::iterator stack_it = frame_it->begin();
33
34  // Get the function. Note that this might materialize the function.
35  // In case the debugger mutates this value, we should deoptimize
36  // the function and remember the value in the materialized value store.
37  DCHECK_EQ(parameter_count,
38            Handle<JSFunction>::cast(stack_it->GetValue())
39                ->shared()
40                .internal_formal_parameter_count_without_receiver());
41
42  stack_it++;  // Skip the function.
43  stack_it++;  // Skip the receiver.
44
45  DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind());
46
47  parameters_.resize(static_cast<size_t>(parameter_count));
48  for (int i = 0; i < parameter_count; i++) {
49    Handle<Object> parameter = GetValueForDebugger(stack_it, isolate);
50    SetParameter(i, parameter);
51    stack_it++;
52  }
53
54  // Get the context.
55  context_ = GetValueForDebugger(stack_it, isolate);
56  stack_it++;
57
58  // Get the expression stack.
59  DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind());
60  const int stack_height = frame_it->height();  // Accumulator *not* included.
61
62  expression_stack_.resize(static_cast<size_t>(stack_height));
63  for (int i = 0; i < stack_height; i++) {
64    Handle<Object> expression = GetValueForDebugger(stack_it, isolate);
65    SetExpression(i, expression);
66    stack_it++;
67  }
68
69  DCHECK_EQ(TranslatedFrame::kUnoptimizedFunction, frame_it->kind());
70  stack_it++;  // Skip the accumulator.
71
72  CHECK(stack_it == frame_it->end());
73}
74
75}  // namespace internal
76}  // namespace v8
77