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
11 namespace v8 {
12 namespace internal {
13 namespace {
14
GetValueForDebugger(TranslatedFrame::iterator it,Isolate * isolate)15 Handle<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
DeoptimizedFrameInfo(TranslatedState * state,TranslatedState::iterator frame_it,Isolate * isolate)26 DeoptimizedFrameInfo::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