• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 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/debug/debug-frames.h"
6 
7 #include "src/frames-inl.h"
8 
9 namespace v8 {
10 namespace internal {
11 
FrameInspector(JavaScriptFrame * frame,int inlined_jsframe_index,Isolate * isolate)12 FrameInspector::FrameInspector(JavaScriptFrame* frame,
13                                int inlined_jsframe_index, Isolate* isolate)
14     : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
15   has_adapted_arguments_ = frame_->has_adapted_arguments();
16   is_bottommost_ = inlined_jsframe_index == 0;
17   is_optimized_ = frame_->is_optimized();
18   // Calculate the deoptimized frame.
19   if (frame->is_optimized()) {
20     // TODO(turbofan): Revisit once we support deoptimization.
21     if (frame->LookupCode()->is_turbofanned() &&
22         frame->function()->shared()->asm_function() &&
23         !FLAG_turbo_asm_deoptimization) {
24       is_optimized_ = false;
25       return;
26     }
27 
28     deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
29         frame, inlined_jsframe_index, isolate);
30   }
31 }
32 
33 
~FrameInspector()34 FrameInspector::~FrameInspector() {
35   // Get rid of the calculated deoptimized frame if any.
36   if (deoptimized_frame_ != NULL) {
37     Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_);
38   }
39 }
40 
41 
GetParametersCount()42 int FrameInspector::GetParametersCount() {
43   return is_optimized_ ? deoptimized_frame_->parameters_count()
44                        : frame_->ComputeParametersCount();
45 }
46 
47 
GetFunction()48 Object* FrameInspector::GetFunction() {
49   return is_optimized_ ? deoptimized_frame_->GetFunction() : frame_->function();
50 }
51 
52 
GetParameter(int index)53 Object* FrameInspector::GetParameter(int index) {
54   return is_optimized_ ? deoptimized_frame_->GetParameter(index)
55                        : frame_->GetParameter(index);
56 }
57 
58 
GetExpression(int index)59 Object* FrameInspector::GetExpression(int index) {
60   // TODO(turbofan): Revisit once we support deoptimization.
61   if (frame_->LookupCode()->is_turbofanned() &&
62       frame_->function()->shared()->asm_function() &&
63       !FLAG_turbo_asm_deoptimization) {
64     return isolate_->heap()->undefined_value();
65   }
66   return is_optimized_ ? deoptimized_frame_->GetExpression(index)
67                        : frame_->GetExpression(index);
68 }
69 
70 
GetSourcePosition()71 int FrameInspector::GetSourcePosition() {
72   return is_optimized_ ? deoptimized_frame_->GetSourcePosition()
73                        : frame_->LookupCode()->SourcePosition(frame_->pc());
74 }
75 
76 
IsConstructor()77 bool FrameInspector::IsConstructor() {
78   return is_optimized_ && !is_bottommost_
79              ? deoptimized_frame_->HasConstructStub()
80              : frame_->IsConstructor();
81 }
82 
83 
GetContext()84 Object* FrameInspector::GetContext() {
85   return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
86 }
87 
88 
89 // To inspect all the provided arguments the frame might need to be
90 // replaced with the arguments frame.
SetArgumentsFrame(JavaScriptFrame * frame)91 void FrameInspector::SetArgumentsFrame(JavaScriptFrame* frame) {
92   DCHECK(has_adapted_arguments_);
93   frame_ = frame;
94   is_optimized_ = frame_->is_optimized();
95   DCHECK(!is_optimized_);
96 }
97 
98 
99 // Create a plain JSObject which materializes the local scope for the specified
100 // frame.
MaterializeStackLocals(Handle<JSObject> target,Handle<ScopeInfo> scope_info)101 void FrameInspector::MaterializeStackLocals(Handle<JSObject> target,
102                                             Handle<ScopeInfo> scope_info) {
103   HandleScope scope(isolate_);
104   // First fill all parameters.
105   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
106     // Do not materialize the parameter if it is shadowed by a context local.
107     // TODO(yangguo): check whether this is necessary, now that we materialize
108     //                context locals as well.
109     Handle<String> name(scope_info->ParameterName(i));
110     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
111 
112     Handle<Object> value(i < GetParametersCount()
113                              ? GetParameter(i)
114                              : isolate_->heap()->undefined_value(),
115                          isolate_);
116     DCHECK(!value->IsTheHole());
117 
118     JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
119   }
120 
121   // Second fill all stack locals.
122   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
123     if (scope_info->LocalIsSynthetic(i)) continue;
124     Handle<String> name(scope_info->StackLocalName(i));
125     Handle<Object> value(GetExpression(scope_info->StackLocalIndex(i)),
126                          isolate_);
127     if (value->IsTheHole()) value = isolate_->factory()->undefined_value();
128 
129     JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
130   }
131 }
132 
133 
MaterializeStackLocals(Handle<JSObject> target,Handle<JSFunction> function)134 void FrameInspector::MaterializeStackLocals(Handle<JSObject> target,
135                                             Handle<JSFunction> function) {
136   Handle<SharedFunctionInfo> shared(function->shared());
137   Handle<ScopeInfo> scope_info(shared->scope_info());
138   MaterializeStackLocals(target, scope_info);
139 }
140 
141 
UpdateStackLocalsFromMaterializedObject(Handle<JSObject> target,Handle<ScopeInfo> scope_info)142 void FrameInspector::UpdateStackLocalsFromMaterializedObject(
143     Handle<JSObject> target, Handle<ScopeInfo> scope_info) {
144   if (is_optimized_) {
145     // Optimized frames are not supported. Simply give up.
146     return;
147   }
148 
149   HandleScope scope(isolate_);
150 
151   // Parameters.
152   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
153     // Shadowed parameters were not materialized.
154     Handle<String> name(scope_info->ParameterName(i));
155     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
156 
157     DCHECK(!frame_->GetParameter(i)->IsTheHole());
158     Handle<Object> value =
159         Object::GetPropertyOrElement(target, name).ToHandleChecked();
160     frame_->SetParameterValue(i, *value);
161   }
162 
163   // Stack locals.
164   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
165     if (scope_info->LocalIsSynthetic(i)) continue;
166     int index = scope_info->StackLocalIndex(i);
167     if (frame_->GetExpression(index)->IsTheHole()) continue;
168     Handle<Object> value =
169         Object::GetPropertyOrElement(
170             target, handle(scope_info->StackLocalName(i), isolate_))
171             .ToHandleChecked();
172     frame_->SetExpression(index, *value);
173   }
174 }
175 
176 
ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,Handle<String> parameter_name)177 bool FrameInspector::ParameterIsShadowedByContextLocal(
178     Handle<ScopeInfo> info, Handle<String> parameter_name) {
179   VariableMode mode;
180   InitializationFlag init_flag;
181   MaybeAssignedFlag maybe_assigned_flag;
182   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
183                                      &maybe_assigned_flag) != -1;
184 }
185 
186 
FindSavedContextForFrame(Isolate * isolate,JavaScriptFrame * frame)187 SaveContext* DebugFrameHelper::FindSavedContextForFrame(
188     Isolate* isolate, JavaScriptFrame* frame) {
189   SaveContext* save = isolate->save_context();
190   while (save != NULL && !save->IsBelowFrame(frame)) {
191     save = save->prev();
192   }
193   DCHECK(save != NULL);
194   return save;
195 }
196 
197 
FindIndexedNonNativeFrame(JavaScriptFrameIterator * it,int index)198 int DebugFrameHelper::FindIndexedNonNativeFrame(JavaScriptFrameIterator* it,
199                                                 int index) {
200   int count = -1;
201   for (; !it->done(); it->Advance()) {
202     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
203     it->frame()->Summarize(&frames);
204     for (int i = frames.length() - 1; i >= 0; i--) {
205       // Omit functions from native and extension scripts.
206       if (!frames[i].function()->shared()->IsSubjectToDebugging()) continue;
207       if (++count == index) return i;
208     }
209   }
210   return -1;
211 }
212 
213 
214 }  // namespace internal
215 }  // namespace v8
216