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