Home | History | Annotate | Download | only in src
      1 // Copyright 2016 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/source-position.h"
      6 #include "src/compilation-info.h"
      7 #include "src/objects-inl.h"
      8 
      9 namespace v8 {
     10 namespace internal {
     11 
     12 std::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) {
     13   Handle<SharedFunctionInfo> function(pos.function);
     14   String* name = nullptr;
     15   if (function->script()->IsScript()) {
     16     Script* script = Script::cast(function->script());
     17     if (script->name()->IsString()) {
     18       name = String::cast(script->name());
     19     }
     20   }
     21   out << "<";
     22   if (name != nullptr) {
     23     out << name->ToCString(DISALLOW_NULLS).get();
     24   } else {
     25     out << "unknown";
     26   }
     27   out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
     28   return out;
     29 }
     30 
     31 std::ostream& operator<<(std::ostream& out,
     32                          const std::vector<SourcePositionInfo>& stack) {
     33   bool first = true;
     34   for (const SourcePositionInfo& pos : stack) {
     35     if (!first) out << " inlined at ";
     36     out << pos;
     37     first = false;
     38   }
     39   return out;
     40 }
     41 
     42 std::ostream& operator<<(std::ostream& out, const SourcePosition& pos) {
     43   if (pos.isInlined()) {
     44     out << "<inlined(" << pos.InliningId() << "):";
     45   } else {
     46     out << "<not inlined:";
     47   }
     48   out << pos.ScriptOffset() << ">";
     49   return out;
     50 }
     51 
     52 std::vector<SourcePositionInfo> SourcePosition::InliningStack(
     53     CompilationInfo* cinfo) const {
     54   SourcePosition pos = *this;
     55   std::vector<SourcePositionInfo> stack;
     56   while (pos.isInlined()) {
     57     const auto& inl = cinfo->inlined_functions()[pos.InliningId()];
     58     stack.push_back(SourcePositionInfo(pos, inl.shared_info));
     59     pos = inl.position.position;
     60   }
     61   stack.push_back(SourcePositionInfo(pos, cinfo->shared_info()));
     62   return stack;
     63 }
     64 
     65 std::vector<SourcePositionInfo> SourcePosition::InliningStack(
     66     Handle<Code> code) const {
     67   Handle<DeoptimizationInputData> deopt_data(
     68       DeoptimizationInputData::cast(code->deoptimization_data()));
     69   SourcePosition pos = *this;
     70   std::vector<SourcePositionInfo> stack;
     71   while (pos.isInlined()) {
     72     InliningPosition inl =
     73         deopt_data->InliningPositions()->get(pos.InliningId());
     74     Handle<SharedFunctionInfo> function(
     75         deopt_data->GetInlinedFunction(inl.inlined_function_id));
     76     stack.push_back(SourcePositionInfo(pos, function));
     77     pos = inl.position;
     78   }
     79   Handle<SharedFunctionInfo> function(
     80       SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
     81   stack.push_back(SourcePositionInfo(pos, function));
     82   return stack;
     83 }
     84 
     85 void SourcePosition::Print(std::ostream& out,
     86                            SharedFunctionInfo* function) const {
     87   Script::PositionInfo pos;
     88   Object* source_name = nullptr;
     89   if (function->script()->IsScript()) {
     90     Script* script = Script::cast(function->script());
     91     source_name = script->name();
     92     script->GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
     93   }
     94   out << "<";
     95   if (source_name != nullptr && source_name->IsString()) {
     96     out << String::cast(source_name)
     97                ->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
     98                .get();
     99   } else {
    100     out << "unknown";
    101   }
    102   out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
    103 }
    104 
    105 void SourcePosition::Print(std::ostream& out, Code* code) const {
    106   DeoptimizationInputData* deopt_data =
    107       DeoptimizationInputData::cast(code->deoptimization_data());
    108   if (!isInlined()) {
    109     SharedFunctionInfo* function(
    110         SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo()));
    111     Print(out, function);
    112   } else {
    113     InliningPosition inl = deopt_data->InliningPositions()->get(InliningId());
    114     if (inl.inlined_function_id == -1) {
    115       out << *this;
    116     } else {
    117       SharedFunctionInfo* function =
    118           deopt_data->GetInlinedFunction(inl.inlined_function_id);
    119       Print(out, function);
    120     }
    121     out << " inlined at ";
    122     inl.position.Print(out, code);
    123   }
    124 }
    125 
    126 SourcePositionInfo::SourcePositionInfo(SourcePosition pos,
    127                                        Handle<SharedFunctionInfo> f)
    128     : position(pos), function(f) {
    129   if (function->script()->IsScript()) {
    130     Handle<Script> script(Script::cast(function->script()));
    131     Script::PositionInfo info;
    132     if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info,
    133                                 Script::WITH_OFFSET)) {
    134       line = info.line;
    135       column = info.column;
    136     }
    137   }
    138 }
    139 
    140 }  // namespace internal
    141 }  // namespace v8
    142