11#include <unordered_map> 
   32#ifdef V8_TARGET_ARCH_X64 
   36#if V8_ENABLE_WEBASSEMBLY 
   44#ifdef ENABLE_DISASSEMBLER 
   48  explicit V8NameConverter(Isolate* isolate, CodeReference code = {})
 
   50  const char* NameOfAddress(uint8_t* 
pc) 
const override;
 
   51  const char* NameInCode(uint8_t* addr) 
const override;
 
   52  const char* RootRelativeName(
int offset) 
const override;
 
   54  const CodeReference& 
code()
 const { 
return code_; }
 
   57  void InitExternalRefsCache() 
const;
 
   62  base::EmbeddedVector<char, 128> v8_buffer_;
 
   68  mutable std::unordered_map<int, const char*> directly_accessed_external_refs_;
 
   71void V8NameConverter::InitExternalRefsCache()
 const {
 
   72  ExternalReferenceTable* external_reference_table =
 
   74  if (!external_reference_table->is_initialized()) 
return;
 
   76  base::AddressRegion addressable_region =
 
   81    Address address = external_reference_table->address(
i);
 
   82    if (addressable_region.contains(address)) {
 
   83      int offset = 
static_cast<int>(address - isolate_root);
 
   84      const char* name = external_reference_table->name(
i);
 
   85      directly_accessed_external_refs_.insert({
offset, name});
 
   90const char* V8NameConverter::NameOfAddress(uint8_t* 
pc)
 const {
 
   91  if (!
code_.is_null()) {
 
   96    if (name != 
nullptr) {
 
   97      SNPrintF(v8_buffer_, 
"%p  (%s)", 
static_cast<void*
>(
pc), name);
 
   98      return v8_buffer_.begin();
 
  101    int offs = 
static_cast<int>(
reinterpret_cast<Address>(
pc) -
 
  102                                code_.instruction_start());
 
  104    if (0 <= offs && offs < 
code_.instruction_size()) {
 
  105      SNPrintF(v8_buffer_, 
"%p  <+0x%x>", 
static_cast<void*
>(
pc), offs);
 
  106      return v8_buffer_.begin();
 
  109#if V8_ENABLE_WEBASSEMBLY 
  112      SNPrintF(v8_buffer_, 
"%p  (%s)", 
static_cast<void*
>(
pc),
 
  114      return v8_buffer_.begin();
 
  122const char* V8NameConverter::NameInCode(uint8_t* addr)
 const {
 
  125  return code_.is_null() ? 
"" : 
reinterpret_cast<const char*
>(addr);
 
  128const char* V8NameConverter::RootRelativeName(
int offset)
 const {
 
  129  if (
isolate_ == 
nullptr) 
return nullptr;
 
  131  const int kRootsTableStart = IsolateData::roots_table_offset();
 
  132  const unsigned kRootsTableSize = 
sizeof(RootsTable);
 
  133  const int kExtRefsTableStart = IsolateData::external_reference_table_offset();
 
  135  const int kBuiltinTier0TableStart = IsolateData::builtin_tier0_table_offset();
 
  136  const unsigned kBuiltinTier0TableSize =
 
  138  const int kBuiltinTableStart = IsolateData::builtin_table_offset();
 
  139  const unsigned kBuiltinTableSize =
 
  142  if (
static_cast<unsigned>(
offset - kRootsTableStart) < kRootsTableSize) {
 
  143    uint32_t offset_in_roots_table = 
offset - kRootsTableStart;
 
  152    return v8_buffer_.begin();
 
  153  } 
else if (
static_cast<unsigned>(
offset - kExtRefsTableStart) <
 
  155    uint32_t offset_in_extref_table = 
offset - kExtRefsTableStart;
 
  167    SNPrintF(v8_buffer_, 
"external reference (%s)",
 
  169                 offset_in_extref_table));
 
  170    return v8_buffer_.begin();
 
  171  } 
else if (
static_cast<unsigned>(
offset - kBuiltinTier0TableStart) <
 
  172             kBuiltinTier0TableSize) {
 
  173    uint32_t offset_in_builtins_table = (
offset - kBuiltinTier0TableStart);
 
  178    SNPrintF(v8_buffer_, 
"builtin (%s)", name);
 
  179    return v8_buffer_.begin();
 
  180  } 
else if (
static_cast<unsigned>(
offset - kBuiltinTableStart) <
 
  182    uint32_t offset_in_builtins_table = (
offset - kBuiltinTableStart);
 
  187    SNPrintF(v8_buffer_, 
"builtin (%s)", name);
 
  188    return v8_buffer_.begin();
 
  191    if (directly_accessed_external_refs_.empty()) {
 
  192      InitExternalRefsCache();
 
  195    auto iter = directly_accessed_external_refs_.find(
offset);
 
  196    if (iter != directly_accessed_external_refs_.end()) {
 
  197      SNPrintF(v8_buffer_, 
"external value (%s)", iter->second);
 
  198      return v8_buffer_.begin();
 
  205static void DumpBuffer(std::ostream& os, std::ostringstream& out) {
 
  206  os << out.str() << std::endl;
 
  210static const int kRelocInfoPosition = 57;
 
  212static void PrintRelocInfo(std::ostringstream& out, Isolate* isolate,
 
  213                           const ExternalReferenceEncoder* ref_encoder,
 
  214                           std::ostream& os, CodeReference host,
 
  215                           RelocInfo* relocinfo, 
bool first_reloc_info = 
true) {
 
  217  int padding = kRelocInfoPosition;
 
  218  if (first_reloc_info) {
 
  220    padding -= std::min(padding, 
static_cast<int>(out.tellp()));
 
  225  std::fill_n(std::ostream_iterator<char>(out), padding, 
' ');
 
  229    out << 
"    ;; debug: deopt position, script offset '" 
  230        << 
static_cast<int>(relocinfo->data()) << 
"'";
 
  232    out << 
"    ;; debug: deopt position, inlining id '" 
  233        << 
static_cast<int>(relocinfo->data()) << 
"'";
 
  239    out << 
"    ;; debug: deopt index " << 
static_cast<int>(relocinfo->data());
 
  242    out << 
"    ;; debug: deopt node id " 
  243        << 
static_cast<uint32_t
>(relocinfo->data());
 
  248    HeapStringAllocator allocator;
 
  249    StringStream accumulator(&allocator);
 
  250    ShortPrint(relocinfo->target_object(isolate), &accumulator);
 
  251    std::unique_ptr<char[]> obj_name = accumulator.ToCString();
 
  253    out << 
"    ;; " << (is_compressed ? 
"(compressed) " : 
"")
 
  254        << 
"object: " << obj_name.get();
 
  256    Address address = relocinfo->target_external_reference();
 
  257    const char* reference_name =
 
  259            ? ref_encoder->NameOfAddress(isolate, address)
 
  262    out << 
"    ;; external reference (" << reference_name << 
")";
 
  264#ifdef V8_ENABLE_LEAPTIERING 
  265    out << 
"    ;; js dispatch handle:0x" << std::hex
 
  266        << relocinfo->js_dispatch_handle();
 
  268        relocinfo->js_dispatch_handle());
 
  270    if (code->is_builtin()) {
 
  281        isolate->heap()->FindCodeForInnerPointer(relocinfo->target_address());
 
  283    if (code->is_builtin()) {
 
  288#if V8_ENABLE_WEBASSEMBLY 
  292        host.as_wasm_code()->native_module()->GetBuiltinInJumptableSlot(
 
  293            relocinfo->wasm_stub_call_address()));
 
  294    out << 
"    ;; wasm stub: " << runtime_stub_name;
 
  297    out << 
"    ;; " << RelocInfo::RelocModeName(rmode);
 
  301static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
 
  302                    std::ostream& os, CodeReference code,
 
  303                    const V8NameConverter& converter, uint8_t* begin,
 
  304                    uint8_t* 
end, 
Address current_pc, 
size_t range_limit) {
 
  305  CHECK(!code.is_null());
 
  307  std::ostringstream out;
 
  311  RelocIterator rit(code);
 
  312  CodeCommentsIterator cit(code.code_comments(), code.code_comments_size());
 
  314#ifdef V8_TARGET_ARCH_X64 
  315  std::unique_ptr<BuiltinJumpTableInfoIterator> table_info_it = 
nullptr;
 
  316  if (code.is_code() && code.as_code()->has_builtin_jump_table_info()) {
 
  317    table_info_it = std::make_unique<BuiltinJumpTableInfoIterator>(
 
  318        code.as_code()->builtin_jump_table_info(),
 
  319        code.as_code()->builtin_jump_table_info_size());
 
  327    uint8_t* prev_pc = 
pc;
 
  328    bool decoding_constant_pool = constants > 0;
 
  329    if (decoding_constant_pool) {
 
  331          decode_buffer, 
"%08x       constant",
 
  336      int num_const = d.ConstantPoolSizeAt(
pc);
 
  337      if (num_const >= 0) {
 
  339            decode_buffer, 
"%08x       constant pool begin (num_const = %d)",
 
  342        constants = num_const;
 
  344      } 
else if (!rit.done() &&
 
  345                 rit.rinfo()->pc() == 
reinterpret_cast<Address>(
pc) &&
 
  351                 reinterpret_cast<intptr_t
>(ptr),
 
  352                 static_cast<size_t>(ptr - begin));
 
  354#ifdef V8_TARGET_ARCH_X64 
  355      } 
else if (table_info_it && table_info_it->HasCurrent() &&
 
  356                 table_info_it->GetPCOffset() ==
 
  357                     static_cast<uint32_t
>(
pc - begin)) {
 
  358        int32_t target_pc_offset = table_info_it->GetTarget();
 
  359        static_assert(
sizeof(target_pc_offset) ==
 
  361        SNPrintF(decode_buffer, 
"jump table entry %08x", target_pc_offset);
 
  363        table_info_it->Next();
 
  366        decode_buffer[0] = 
'\0';
 
  367        pc += d.InstructionDecode(decode_buffer, 
pc);
 
  372    if (range_limit != 0) {
 
  373      if (pc_address > current_pc + range_limit) 
break;
 
  374      if (pc_address <= current_pc - range_limit) 
continue;
 
  378    std::vector<const char*> comments;
 
  379    std::vector<Address> pcs;
 
  380    std::vector<RelocInfo::Mode> rmodes;
 
  381    std::vector<intptr_t> datas;
 
  382    while (!rit.done() && rit.rinfo()->pc() < 
reinterpret_cast<Address>(
pc)) {
 
  384      pcs.push_back(rit.rinfo()->pc());
 
  385      rmodes.push_back(rit.rinfo()->rmode());
 
  386      datas.push_back(rit.rinfo()->data());
 
  389    while (cit.HasCurrent()) {
 
  390      Address cur = cit.GetPCOffset();
 
  391      if (cur >= 
static_cast<Address>(
pc - begin)) 
break;
 
  392      if (range_limit == 0 ||
 
  393          cur + range_limit > current_pc - 
reinterpret_cast<Address>(begin)) {
 
  394        comments.push_back(cit.GetComment());
 
  400    for (
size_t i = 0; 
i < comments.size(); 
i++) {
 
  404      out << 
"                  " << comments[
i];
 
  413        reinterpret_cast<Address>(prev_pc) == current_pc) {
 
  417    out << static_cast<void*>(prev_pc) << 
"  " << std::setw(4) << std::hex
 
  418        << prev_pc - 
begin << 
"  ";
 
  421    out << decode_buffer.
begin();
 
  424    for (
size_t i = 0; 
i < pcs.size(); 
i++) {
 
  426      const CodeReference& host = 
code;
 
  429      if (host.is_code()) {
 
  431        bool first_reloc_info = (
i == 0);
 
  432        PrintRelocInfo(out, isolate, ref_encoder, os, code, &relocinfo,
 
  444    if (pcs.empty() && !code.is_null() && !decoding_constant_pool) {
 
  445      RelocInfo dummy_rinfo(
reinterpret_cast<Address>(prev_pc),
 
  447      if (dummy_rinfo.IsInConstantPool()) {
 
  448        Address constant_pool_entry_address =
 
  449            dummy_rinfo.constant_pool_entry_address();
 
  450        RelocIterator reloc_it(code);
 
  451        while (!reloc_it.done()) {
 
  452          if (reloc_it.rinfo()->IsInConstantPool() &&
 
  453              (reloc_it.rinfo()->constant_pool_entry_address() ==
 
  454               constant_pool_entry_address)) {
 
  455            PrintRelocInfo(out, isolate, ref_encoder, os, code,
 
  465        reinterpret_cast<Address>(prev_pc) == current_pc) {
 
  473  while (cit.HasCurrent()) {
 
  474    Address cur = cit.GetPCOffset();
 
  475    if (range_limit == 0 ||
 
  476        cur + range_limit == current_pc - 
reinterpret_cast<Address>(begin)) {
 
  477      out << 
"                  " << cit.GetComment();
 
  483  return static_cast<int>(
pc - 
begin);
 
  487                         uint8_t* 
end, CodeReference code, 
Address current_pc,
 
  488                         size_t range_limit) {
 
  490                  "Builtins disassembly requires a readable .text section");
 
  491  V8NameConverter v8NameConverter(isolate, code);
 
  495    SealHandleScope shs(isolate);
 
  497    ExternalReferenceEncoder ref_encoder(isolate);
 
  498    return DecodeIt(isolate, &ref_encoder, os, code, v8NameConverter, begin,
 
  499                    end, current_pc, range_limit);
 
  503    return DecodeIt(
nullptr, 
nullptr, os, code, v8NameConverter, begin, 
end,
 
  504                    current_pc, range_limit);
 
  512                         size_t range_limit) {
 
 
@ kContinueOnUnimplementedOpcode
 
virtual const char * NameOfAddress(uint8_t *addr) const
 
constexpr T * begin() const
 
static constexpr int kBuiltinCount
 
const char * Lookup(Address pc)
 
static constexpr int kBuiltinTier0Count
 
static constexpr Builtin FromInt(int id)
 
static V8_EXPORT_PRIVATE const char * name(Builtin builtin)
 
static V8_EXPORT_PRIVATE int Decode(Isolate *isolate, std::ostream &os, uint8_t *begin, uint8_t *end, CodeReference code={}, Address current_pc=kNullAddress, size_t range_limit=0)
 
const char * NameFromOffset(uint32_t offset)
 
static constexpr uint32_t kEntrySize
 
static constexpr uint32_t kSizeInBytes
 
static constexpr int kSize
 
bool is_initialized() const
 
static const char * NameOfIsolateIndependentAddress(Address address, MemorySpan< Address > shared_external_references)
 
static IsolateGroup * current()
 
Address isolate_root() const
 
ExternalReferenceTable * external_reference_table()
 
base::AddressRegion root_register_addressable_region() const
 
static constexpr bool IsCodeTargetMode(Mode mode)
 
static constexpr bool IsCompressedEmbeddedObject(Mode mode)
 
static constexpr bool IsWasmStubCall(Mode mode)
 
static constexpr bool IsEmbeddedObjectMode(Mode mode)
 
static const char * name(RootIndex root_index)
 
ZoneList< RegExpInstruction > code_
 
static V ReadUnalignedValue(Address p)
 
int SNPrintF(Vector< char > str, const char *format,...)
 
Node::Uses::const_iterator begin(const Node::Uses &uses)
 
WasmCodeManager * GetWasmCodeManager()
 
const char * GetWasmCodeKindAsString(WasmCode::Kind kind)
 
PerThreadAssertScopeDebugOnly< false, SAFEPOINTS_ASSERT, HEAP_ALLOCATION_ASSERT > DisallowGarbageCollection
 
const char * CodeKindToString(CodeKind kind)
 
Tagged(T object) -> Tagged< T >
 
char const * DeoptimizeReasonToString(DeoptimizeReason reason)
 
constexpr int kSystemPointerSize
 
void ShortPrint(Tagged< Object > obj, FILE *out)
 
V8_EXPORT_PRIVATE FlagValues v8_flags
 
static constexpr Address kNullAddress
 
#define DCHECK_WITH_MSG(condition, msg)
 
static constexpr int kTargetSize