LCOV - code coverage report
Current view: top level - src/debug - debug-frames.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 94 96 97.9 %
Date: 2017-04-26 Functions: 16 17 94.1 %

          Line data    Source code
       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             : #include "src/wasm/wasm-interpreter.h"
       9             : #include "src/wasm/wasm-objects.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14      451502 : FrameInspector::FrameInspector(StandardFrame* frame, int inlined_frame_index,
      15             :                                Isolate* isolate)
      16             :     : frame_(frame),
      17             :       frame_summary_(FrameSummary::Get(frame, inlined_frame_index)),
      18      451502 :       isolate_(isolate) {
      19             :   JavaScriptFrame* js_frame =
      20      451502 :       frame->is_java_script() ? javascript_frame() : nullptr;
      21             :   DCHECK(js_frame || frame->is_wasm());
      22      902532 :   has_adapted_arguments_ = js_frame && js_frame->has_adapted_arguments();
      23      451502 :   is_bottommost_ = inlined_frame_index == 0;
      24      903280 :   is_optimized_ = frame_->is_optimized();
      25      903004 :   is_interpreted_ = frame_->is_interpreted();
      26             : 
      27             :   // Calculate the deoptimized frame.
      28      451502 :   if (is_optimized_) {
      29             :     DCHECK(js_frame != nullptr);
      30             :     // TODO(turbofan): Revisit once we support deoptimization.
      31       80067 :     if (js_frame->LookupCode()->is_turbofanned() &&
      32       31017 :         js_frame->function()->shared()->asm_function()) {
      33          56 :       is_optimized_ = false;
      34      451558 :       return;
      35             :     }
      36             : 
      37             :     deoptimized_frame_.reset(Deoptimizer::DebuggerInspectableFrame(
      38       48994 :         js_frame, inlined_frame_index, isolate));
      39      804904 :   } else if (frame_->is_wasm_interpreter_entry()) {
      40         828 :     wasm_interpreted_frame_ =
      41             :         frame_summary_.AsWasm()
      42             :             .wasm_instance()
      43             :             ->debug_info()
      44             :             ->GetInterpretedFrame(frame_->fp(), inlined_frame_index);
      45             :     DCHECK(wasm_interpreted_frame_);
      46             :   }
      47             : }
      48             : 
      49      903004 : FrameInspector::~FrameInspector() {
      50             :   // Destructor needs to be defined in the .cc file, because it instantiates
      51             :   // std::unique_ptr destructors but the types are not known in the header.
      52      451502 : }
      53             : 
      54      344589 : int FrameInspector::GetParametersCount() {
      55      392216 :   if (is_optimized_) return deoptimized_frame_->parameters_count();
      56      296962 :   if (wasm_interpreted_frame_)
      57           0 :     return wasm_interpreted_frame_->GetParameterCount();
      58      296962 :   return frame_->ComputeParametersCount();
      59             : }
      60             : 
      61      229547 : Handle<Script> FrameInspector::GetScript() {
      62      229547 :   return Handle<Script>::cast(frame_summary_.script());
      63             : }
      64             : 
      65     1019474 : Handle<JSFunction> FrameInspector::GetFunction() {
      66     1019474 :   return frame_summary_.AsJavaScript().function();
      67             : }
      68             : 
      69       96918 : Handle<Object> FrameInspector::GetParameter(int index) {
      70       96918 :   if (is_optimized_) return deoptimized_frame_->GetParameter(index);
      71             :   // TODO(clemensh): Handle wasm_interpreted_frame_.
      72       75344 :   return handle(frame_->GetParameter(index), isolate_);
      73             : }
      74             : 
      75     9519700 : Handle<Object> FrameInspector::GetExpression(int index) {
      76             :   // TODO(turbofan): Revisit once we support deoptimization.
      77    28559100 :   if (frame_->is_java_script() &&
      78     9537462 :       javascript_frame()->LookupCode()->is_turbofanned() &&
      79       17762 :       javascript_frame()->function()->shared()->asm_function()) {
      80          24 :     return isolate_->factory()->undefined_value();
      81             :   }
      82             :   return is_optimized_ ? deoptimized_frame_->GetExpression(index)
      83    19012014 :                        : handle(frame_->GetExpression(index), isolate_);
      84             : }
      85             : 
      86      424115 : int FrameInspector::GetSourcePosition() {
      87      424115 :   return frame_summary_.SourcePosition();
      88             : }
      89             : 
      90      229173 : bool FrameInspector::IsConstructor() { return frame_summary_.is_constructor(); }
      91             : 
      92      749086 : Handle<Object> FrameInspector::GetContext() {
      93             :   return is_optimized_ ? deoptimized_frame_->GetContext()
      94     2182478 :                        : handle(frame_->context(), isolate_);
      95             : }
      96             : 
      97             : // To inspect all the provided arguments the frame might need to be
      98             : // replaced with the arguments frame.
      99       16015 : void FrameInspector::SetArgumentsFrame(StandardFrame* frame) {
     100             :   DCHECK(has_adapted_arguments_);
     101             :   DCHECK(frame->is_arguments_adaptor());
     102       16015 :   frame_ = frame;
     103       32030 :   is_optimized_ = frame_->is_optimized();
     104       32030 :   is_interpreted_ = frame_->is_interpreted();
     105             :   DCHECK(!is_optimized_);
     106       16015 : }
     107             : 
     108             : 
     109             : // Create a plain JSObject which materializes the local scope for the specified
     110             : // frame.
     111      130126 : void FrameInspector::MaterializeStackLocals(Handle<JSObject> target,
     112             :                                             Handle<ScopeInfo> scope_info) {
     113      130126 :   HandleScope scope(isolate_);
     114             :   // First fill all parameters.
     115      357804 :   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
     116             :     // Do not materialize the parameter if it is shadowed by a context local.
     117             :     // TODO(yangguo): check whether this is necessary, now that we materialize
     118             :     //                context locals as well.
     119       48776 :     Handle<String> name(scope_info->ParameterName(i));
     120       58320 :     if (ScopeInfo::VariableIsSynthetic(*name)) continue;
     121       47492 :     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
     122             : 
     123             :     Handle<Object> value =
     124       39232 :         i < GetParametersCount()
     125             :             ? GetParameter(i)
     126       40842 :             : Handle<Object>::cast(isolate_->factory()->undefined_value());
     127             :     DCHECK(!value->IsTheHole(isolate_));
     128             : 
     129       78464 :     JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
     130             :   }
     131             : 
     132             :   // Second fill all stack locals.
     133     9560192 :   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
     134     4715033 :     Handle<String> name(scope_info->StackLocalName(i));
     135     4715033 :     if (ScopeInfo::VariableIsSynthetic(*name)) continue;
     136     4615413 :     Handle<Object> value = GetExpression(scope_info->StackLocalIndex(i));
     137             :     // TODO(yangguo): We convert optimized out values to {undefined} when they
     138             :     // are passed to the debugger. Eventually we should handle them somehow.
     139     9230826 :     if (value->IsTheHole(isolate_)) {
     140        1791 :       value = isolate_->factory()->undefined_value();
     141             :     }
     142     9230826 :     if (value->IsOptimizedOut(isolate_)) {
     143        1296 :       value = isolate_->factory()->undefined_value();
     144             :     }
     145     9230826 :     JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check();
     146             :   }
     147      130126 : }
     148             : 
     149             : 
     150      120194 : void FrameInspector::MaterializeStackLocals(Handle<JSObject> target,
     151             :                                             Handle<JSFunction> function) {
     152             :   Handle<SharedFunctionInfo> shared(function->shared());
     153             :   Handle<ScopeInfo> scope_info(shared->scope_info());
     154      120194 :   MaterializeStackLocals(target, scope_info);
     155      120194 : }
     156             : 
     157             : 
     158       14390 : void FrameInspector::UpdateStackLocalsFromMaterializedObject(
     159             :     Handle<JSObject> target, Handle<ScopeInfo> scope_info) {
     160             :   // Optimized frames and wasm frames are not supported. Simply give up.
     161       36934 :   if (is_optimized_ || frame_->is_wasm()) return;
     162             : 
     163        8154 :   HandleScope scope(isolate_);
     164             : 
     165             :   // Parameters.
     166       22644 :   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
     167             :     // Shadowed parameters were not materialized.
     168        3168 :     Handle<String> name(scope_info->ParameterName(i));
     169        3168 :     if (ScopeInfo::VariableIsSynthetic(*name)) continue;
     170        2880 :     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
     171             : 
     172             :     DCHECK(!javascript_frame()->GetParameter(i)->IsTheHole(isolate_));
     173             :     Handle<Object> value =
     174        4872 :         Object::GetPropertyOrElement(target, name).ToHandleChecked();
     175        2436 :     javascript_frame()->SetParameterValue(i, *value);
     176             :   }
     177             : 
     178             :   // Stack locals.
     179       94312 :   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
     180       43079 :     Handle<String> name(scope_info->StackLocalName(i));
     181       43079 :     if (ScopeInfo::VariableIsSynthetic(*name)) continue;
     182       42991 :     int index = scope_info->StackLocalIndex(i);
     183       85982 :     if (frame_->GetExpression(index)->IsTheHole(isolate_)) continue;
     184             :     Handle<Object> value =
     185       85758 :         Object::GetPropertyOrElement(target, name).ToHandleChecked();
     186       42879 :     frame_->SetExpression(index, *value);
     187             :   }
     188             : }
     189             : 
     190             : 
     191           0 : bool FrameInspector::ParameterIsShadowedByContextLocal(
     192             :     Handle<ScopeInfo> info, Handle<String> parameter_name) {
     193             :   VariableMode mode;
     194             :   InitializationFlag init_flag;
     195             :   MaybeAssignedFlag maybe_assigned_flag;
     196             :   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
     197       50372 :                                      &maybe_assigned_flag) != -1;
     198             : }
     199             : 
     200      245126 : SaveContext* DebugFrameHelper::FindSavedContextForFrame(Isolate* isolate,
     201             :                                                         StandardFrame* frame) {
     202     1266656 :   SaveContext* save = isolate->save_context();
     203     1756908 :   while (save != NULL && !save->IsBelowFrame(frame)) {
     204             :     save = save->prev();
     205             :   }
     206             :   DCHECK(save != NULL);
     207      245126 :   return save;
     208             : }
     209             : 
     210      229701 : int DebugFrameHelper::FindIndexedNonNativeFrame(StackTraceFrameIterator* it,
     211             :                                                 int index) {
     212             :   int count = -1;
     213     2624120 :   for (; !it->done(); it->Advance()) {
     214     1312060 :     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
     215     1312060 :     it->frame()->Summarize(&frames);
     216     2396538 :     for (int i = frames.length() - 1; i >= 0; i--) {
     217             :       // Omit functions from native and extension scripts.
     218     2628358 :       if (!frames[i].is_subject_to_debugging()) continue;
     219     1314179 :       if (++count == index) return i;
     220             :     }
     221             :   }
     222             :   return -1;
     223             : }
     224             : 
     225             : 
     226             : }  // namespace internal
     227             : }  // namespace v8

Generated by: LCOV version 1.10