11cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/codegen/source-position.h"
61cb0ef41Sopenharmony_ci#include "src/codegen/optimized-compilation-info.h"
71cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h"
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cinamespace v8 {
101cb0ef41Sopenharmony_cinamespace internal {
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SourcePositionInfo& pos) {
131cb0ef41Sopenharmony_ci  out << "<";
141cb0ef41Sopenharmony_ci  if (!pos.script.is_null() && pos.script->name().IsString()) {
151cb0ef41Sopenharmony_ci    out << String::cast(pos.script->name()).ToCString(DISALLOW_NULLS).get();
161cb0ef41Sopenharmony_ci  } else {
171cb0ef41Sopenharmony_ci    out << "unknown";
181cb0ef41Sopenharmony_ci  }
191cb0ef41Sopenharmony_ci  out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
201cb0ef41Sopenharmony_ci  return out;
211cb0ef41Sopenharmony_ci}
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out,
241cb0ef41Sopenharmony_ci                         const std::vector<SourcePositionInfo>& stack) {
251cb0ef41Sopenharmony_ci  bool first = true;
261cb0ef41Sopenharmony_ci  for (const SourcePositionInfo& pos : stack) {
271cb0ef41Sopenharmony_ci    if (!first) out << " inlined at ";
281cb0ef41Sopenharmony_ci    out << pos;
291cb0ef41Sopenharmony_ci    first = false;
301cb0ef41Sopenharmony_ci  }
311cb0ef41Sopenharmony_ci  return out;
321cb0ef41Sopenharmony_ci}
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& out, const SourcePosition& pos) {
351cb0ef41Sopenharmony_ci  if (pos.isInlined()) {
361cb0ef41Sopenharmony_ci    out << "<inlined(" << pos.InliningId() << "):";
371cb0ef41Sopenharmony_ci  } else {
381cb0ef41Sopenharmony_ci    out << "<not inlined:";
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  if (pos.IsExternal()) {
421cb0ef41Sopenharmony_ci    out << pos.ExternalLine() << ", " << pos.ExternalFileId() << ">";
431cb0ef41Sopenharmony_ci  } else {
441cb0ef41Sopenharmony_ci    out << pos.ScriptOffset() << ">";
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci  return out;
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_cistd::vector<SourcePositionInfo> SourcePosition::InliningStack(
501cb0ef41Sopenharmony_ci    OptimizedCompilationInfo* cinfo) const {
511cb0ef41Sopenharmony_ci  SourcePosition pos = *this;
521cb0ef41Sopenharmony_ci  std::vector<SourcePositionInfo> stack;
531cb0ef41Sopenharmony_ci  while (pos.isInlined()) {
541cb0ef41Sopenharmony_ci    const auto& inl = cinfo->inlined_functions()[pos.InliningId()];
551cb0ef41Sopenharmony_ci    stack.push_back(SourcePositionInfo(pos, inl.shared_info));
561cb0ef41Sopenharmony_ci    pos = inl.position.position;
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci  stack.push_back(SourcePositionInfo(pos, cinfo->shared_info()));
591cb0ef41Sopenharmony_ci  return stack;
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_cistd::vector<SourcePositionInfo> SourcePosition::InliningStack(
631cb0ef41Sopenharmony_ci    Handle<Code> code) const {
641cb0ef41Sopenharmony_ci  Isolate* isolate = code->GetIsolate();
651cb0ef41Sopenharmony_ci  DeoptimizationData deopt_data =
661cb0ef41Sopenharmony_ci      DeoptimizationData::cast(code->deoptimization_data());
671cb0ef41Sopenharmony_ci  SourcePosition pos = *this;
681cb0ef41Sopenharmony_ci  std::vector<SourcePositionInfo> stack;
691cb0ef41Sopenharmony_ci  while (pos.isInlined()) {
701cb0ef41Sopenharmony_ci    InliningPosition inl = deopt_data.InliningPositions().get(pos.InliningId());
711cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> function(
721cb0ef41Sopenharmony_ci        deopt_data.GetInlinedFunction(inl.inlined_function_id), isolate);
731cb0ef41Sopenharmony_ci    stack.push_back(SourcePositionInfo(pos, function));
741cb0ef41Sopenharmony_ci    pos = inl.position;
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> function(
771cb0ef41Sopenharmony_ci      SharedFunctionInfo::cast(deopt_data.SharedFunctionInfo()), isolate);
781cb0ef41Sopenharmony_ci  stack.push_back(SourcePositionInfo(pos, function));
791cb0ef41Sopenharmony_ci  return stack;
801cb0ef41Sopenharmony_ci}
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ciSourcePositionInfo SourcePosition::FirstInfo(Handle<Code> code) const {
831cb0ef41Sopenharmony_ci  DisallowGarbageCollection no_gc;
841cb0ef41Sopenharmony_ci  Isolate* isolate = code->GetIsolate();
851cb0ef41Sopenharmony_ci  DeoptimizationData deopt_data =
861cb0ef41Sopenharmony_ci      DeoptimizationData::cast(code->deoptimization_data());
871cb0ef41Sopenharmony_ci  SourcePosition pos = *this;
881cb0ef41Sopenharmony_ci  if (pos.isInlined()) {
891cb0ef41Sopenharmony_ci    InliningPosition inl = deopt_data.InliningPositions().get(pos.InliningId());
901cb0ef41Sopenharmony_ci    Handle<SharedFunctionInfo> function(
911cb0ef41Sopenharmony_ci        deopt_data.GetInlinedFunction(inl.inlined_function_id), isolate);
921cb0ef41Sopenharmony_ci    return SourcePositionInfo(pos, function);
931cb0ef41Sopenharmony_ci  }
941cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> function(
951cb0ef41Sopenharmony_ci      SharedFunctionInfo::cast(deopt_data.SharedFunctionInfo()), isolate);
961cb0ef41Sopenharmony_ci  return SourcePositionInfo(pos, function);
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_civoid SourcePosition::Print(std::ostream& out,
1001cb0ef41Sopenharmony_ci                           SharedFunctionInfo function) const {
1011cb0ef41Sopenharmony_ci  Script::PositionInfo pos;
1021cb0ef41Sopenharmony_ci  Object source_name;
1031cb0ef41Sopenharmony_ci  if (function.script().IsScript()) {
1041cb0ef41Sopenharmony_ci    Script script = Script::cast(function.script());
1051cb0ef41Sopenharmony_ci    source_name = script.name();
1061cb0ef41Sopenharmony_ci    script.GetPositionInfo(ScriptOffset(), &pos, Script::WITH_OFFSET);
1071cb0ef41Sopenharmony_ci  }
1081cb0ef41Sopenharmony_ci  out << "<";
1091cb0ef41Sopenharmony_ci  if (source_name.IsString()) {
1101cb0ef41Sopenharmony_ci    out << String::cast(source_name)
1111cb0ef41Sopenharmony_ci               .ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)
1121cb0ef41Sopenharmony_ci               .get();
1131cb0ef41Sopenharmony_ci  } else {
1141cb0ef41Sopenharmony_ci    out << "unknown";
1151cb0ef41Sopenharmony_ci  }
1161cb0ef41Sopenharmony_ci  out << ":" << pos.line + 1 << ":" << pos.column + 1 << ">";
1171cb0ef41Sopenharmony_ci}
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_civoid SourcePosition::PrintJson(std::ostream& out) const {
1201cb0ef41Sopenharmony_ci  if (IsExternal()) {
1211cb0ef41Sopenharmony_ci    out << "{ \"line\" : " << ExternalLine() << ", "
1221cb0ef41Sopenharmony_ci        << "  \"fileId\" : " << ExternalFileId() << ", "
1231cb0ef41Sopenharmony_ci        << "  \"inliningId\" : " << InliningId() << "}";
1241cb0ef41Sopenharmony_ci  } else {
1251cb0ef41Sopenharmony_ci    out << "{ \"scriptOffset\" : " << ScriptOffset() << ", "
1261cb0ef41Sopenharmony_ci        << "  \"inliningId\" : " << InliningId() << "}";
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_civoid SourcePosition::Print(std::ostream& out, Code code) const {
1311cb0ef41Sopenharmony_ci  DeoptimizationData deopt_data =
1321cb0ef41Sopenharmony_ci      DeoptimizationData::cast(code.deoptimization_data());
1331cb0ef41Sopenharmony_ci  if (!isInlined()) {
1341cb0ef41Sopenharmony_ci    SharedFunctionInfo function(
1351cb0ef41Sopenharmony_ci        SharedFunctionInfo::cast(deopt_data.SharedFunctionInfo()));
1361cb0ef41Sopenharmony_ci    Print(out, function);
1371cb0ef41Sopenharmony_ci  } else {
1381cb0ef41Sopenharmony_ci    InliningPosition inl = deopt_data.InliningPositions().get(InliningId());
1391cb0ef41Sopenharmony_ci    if (inl.inlined_function_id == -1) {
1401cb0ef41Sopenharmony_ci      out << *this;
1411cb0ef41Sopenharmony_ci    } else {
1421cb0ef41Sopenharmony_ci      SharedFunctionInfo function =
1431cb0ef41Sopenharmony_ci          deopt_data.GetInlinedFunction(inl.inlined_function_id);
1441cb0ef41Sopenharmony_ci      Print(out, function);
1451cb0ef41Sopenharmony_ci    }
1461cb0ef41Sopenharmony_ci    out << " inlined at ";
1471cb0ef41Sopenharmony_ci    inl.position.Print(out, code);
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci}
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ciSourcePositionInfo::SourcePositionInfo(SourcePosition pos,
1521cb0ef41Sopenharmony_ci                                       Handle<SharedFunctionInfo> f)
1531cb0ef41Sopenharmony_ci    : position(pos),
1541cb0ef41Sopenharmony_ci      shared(f),
1551cb0ef41Sopenharmony_ci      script(f.is_null() || !f->script().IsScript()
1561cb0ef41Sopenharmony_ci                 ? Handle<Script>::null()
1571cb0ef41Sopenharmony_ci                 : handle(Script::cast(f->script()), f->GetIsolate())) {
1581cb0ef41Sopenharmony_ci  if (!script.is_null()) {
1591cb0ef41Sopenharmony_ci    Script::PositionInfo info;
1601cb0ef41Sopenharmony_ci    if (Script::GetPositionInfo(script, pos.ScriptOffset(), &info,
1611cb0ef41Sopenharmony_ci                                Script::WITH_OFFSET)) {
1621cb0ef41Sopenharmony_ci      line = info.line;
1631cb0ef41Sopenharmony_ci      column = info.column;
1641cb0ef41Sopenharmony_ci    }
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci}
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci}  // namespace internal
1691cb0ef41Sopenharmony_ci}  // namespace v8
170