1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
// Copyright 2015 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/debug/debug-frames.h"
#include "src/builtins/accessors.h"
#include "src/execution/frames-inl.h"
#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-objects-inl.h"
namespace v8 {
namespace internal {
FrameInspector::FrameInspector(StandardFrame* frame, int inlined_frame_index,
Isolate* isolate)
: frame_(frame),
inlined_frame_index_(inlined_frame_index),
isolate_(isolate) {
// Extract the relevant information from the frame summary and discard it.
FrameSummary summary = FrameSummary::Get(frame, inlined_frame_index);
summary.EnsureSourcePositionsAvailable();
is_constructor_ = summary.is_constructor();
source_position_ = summary.SourcePosition();
function_name_ = summary.FunctionName();
script_ = Handle<Script>::cast(summary.script());
receiver_ = summary.receiver();
if (summary.IsJavaScript()) {
function_ = summary.AsJavaScript().function();
}
JavaScriptFrame* js_frame =
frame->is_java_script() ? javascript_frame() : nullptr;
DCHECK(js_frame || frame->is_wasm());
has_adapted_arguments_ = js_frame && js_frame->has_adapted_arguments();
is_optimized_ = frame_->is_optimized();
is_interpreted_ = frame_->is_interpreted();
// Calculate the deoptimized frame.
if (is_optimized_) {
DCHECK_NOT_NULL(js_frame);
deoptimized_frame_.reset(Deoptimizer::DebuggerInspectableFrame(
js_frame, inlined_frame_index, isolate));
} else if (frame_->is_wasm_interpreter_entry()) {
wasm_interpreted_frame_ =
WasmInterpreterEntryFrame::cast(frame_)
->debug_info()
.GetInterpretedFrame(frame_->fp(), inlined_frame_index);
DCHECK(wasm_interpreted_frame_);
}
}
// Destructor needs to be defined in the .cc file, because it instantiates
// std::unique_ptr destructors but the types are not known in the header.
FrameInspector::~FrameInspector() = default;
JavaScriptFrame* FrameInspector::javascript_frame() {
return frame_->is_arguments_adaptor() ? ArgumentsAdaptorFrame::cast(frame_)
: JavaScriptFrame::cast(frame_);
}
int FrameInspector::GetParametersCount() {
if (is_optimized_) return deoptimized_frame_->parameters_count();
if (wasm_interpreted_frame_)
return wasm_interpreted_frame_->GetParameterCount();
return frame_->ComputeParametersCount();
}
Handle<Object> FrameInspector::GetParameter(int index) {
if (is_optimized_) return deoptimized_frame_->GetParameter(index);
// TODO(clemensb): Handle wasm_interpreted_frame_.
return handle(frame_->GetParameter(index), isolate_);
}
Handle<Object> FrameInspector::GetExpression(int index) {
return is_optimized_ ? deoptimized_frame_->GetExpression(index)
: handle(frame_->GetExpression(index), isolate_);
}
Handle<Object> FrameInspector::GetContext() {
return deoptimized_frame_ ? deoptimized_frame_->GetContext()
: handle(frame_->context(), isolate_);
}
bool FrameInspector::IsWasm() { return frame_->is_wasm(); }
bool FrameInspector::IsJavaScript() { return frame_->is_java_script(); }
bool FrameInspector::ParameterIsShadowedByContextLocal(
Handle<ScopeInfo> info, Handle<String> parameter_name) {
VariableMode mode;
InitializationFlag init_flag;
MaybeAssignedFlag maybe_assigned_flag;
IsStaticFlag is_static_flag;
return ScopeInfo::ContextSlotIndex(*info, *parameter_name, &mode, &init_flag,
&maybe_assigned_flag,
&is_static_flag) != -1;
}
RedirectActiveFunctions::RedirectActiveFunctions(SharedFunctionInfo shared,
Mode mode)
: shared_(shared), mode_(mode) {
DCHECK(shared.HasBytecodeArray());
if (mode == Mode::kUseDebugBytecode) {
DCHECK(shared.HasDebugInfo());
}
}
void RedirectActiveFunctions::VisitThread(Isolate* isolate,
ThreadLocalTop* top) {
for (JavaScriptFrameIterator it(isolate, top); !it.done(); it.Advance()) {
JavaScriptFrame* frame = it.frame();
JSFunction function = frame->function();
if (!frame->is_interpreted()) continue;
if (function.shared() != shared_) continue;
InterpretedFrame* interpreted_frame =
reinterpret_cast<InterpretedFrame*>(frame);
BytecodeArray bytecode = mode_ == Mode::kUseDebugBytecode
? shared_.GetDebugInfo().DebugBytecodeArray()
: shared_.GetBytecodeArray();
interpreted_frame->PatchBytecodeArray(bytecode);
}
}
} // namespace internal
} // namespace v8
|