Chromium Code Reviews| Index: src/disassembler.cc |
| diff --git a/src/disassembler.cc b/src/disassembler.cc |
| index 6c0542ec90369a4da54c140611bbcc446171806b..8f0f758e6d9e8d6201df827a13eb68fb71ddb0ef 100644 |
| --- a/src/disassembler.cc |
| +++ b/src/disassembler.cc |
| @@ -74,6 +74,96 @@ static void DumpBuffer(std::ostream* os, StringBuilder* out) { |
| static const int kOutBufferSize = 2048 + String::kMaxShortPrintLength; |
| static const int kRelocInfoPosition = 57; |
| +static void PrintRelocInfo(StringBuilder* out, Isolate* isolate, |
| + const ExternalReferenceEncoder& ref_encoder, |
| + std::ostream* os, RelocInfo* relocinfo, |
| + bool first_reloc_info = true) { |
| + // Indent the printing of the reloc info. |
| + if (first_reloc_info) { |
| + // The first reloc info is printed after the disassembled instruction. |
| + out->AddPadding(' ', kRelocInfoPosition - out->position()); |
| + } else { |
| + // Additional reloc infos are printed on separate lines. |
| + DumpBuffer(os, out); |
| + out->AddPadding(' ', kRelocInfoPosition); |
| + } |
| + |
| + RelocInfo::Mode rmode = relocinfo->rmode(); |
| + if (rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) { |
| + out->AddFormatted(" ;; debug: deopt position, script offset '%d'", |
| + static_cast<int>(relocinfo->data())); |
| + } else if (rmode == RelocInfo::DEOPT_INLINING_ID) { |
| + out->AddFormatted(" ;; debug: deopt position, inlining id '%d'", |
| + static_cast<int>(relocinfo->data())); |
| + } else if (rmode == RelocInfo::DEOPT_REASON) { |
| + DeoptimizeReason reason = static_cast<DeoptimizeReason>(relocinfo->data()); |
| + out->AddFormatted(" ;; debug: deopt reason '%s'", |
| + DeoptimizeReasonToString(reason)); |
| + } else if (rmode == RelocInfo::DEOPT_ID) { |
| + out->AddFormatted(" ;; debug: deopt index %d", |
| + static_cast<int>(relocinfo->data())); |
| + } else if (rmode == RelocInfo::EMBEDDED_OBJECT) { |
| + HeapStringAllocator allocator; |
| + StringStream accumulator(&allocator); |
| + relocinfo->target_object()->ShortPrint(&accumulator); |
| + std::unique_ptr<char[]> obj_name = accumulator.ToCString(); |
| + out->AddFormatted(" ;; object: %s", obj_name.get()); |
| + } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { |
| + const char* reference_name = ref_encoder.NameOfAddress( |
| + isolate, relocinfo->target_external_reference()); |
| + out->AddFormatted(" ;; external reference (%s)", reference_name); |
| + } else if (RelocInfo::IsCodeTarget(rmode)) { |
| + out->AddFormatted(" ;; code:"); |
| + Code* code = Code::GetCodeFromTargetAddress(relocinfo->target_address()); |
| + Code::Kind kind = code->kind(); |
| + if (code->is_inline_cache_stub()) { |
| + out->AddFormatted(" %s", Code::Kind2String(kind)); |
| + if (kind == Code::BINARY_OP_IC || kind == Code::TO_BOOLEAN_IC || |
| + kind == Code::COMPARE_IC) { |
| + InlineCacheState ic_state = IC::StateFromCode(code); |
| + out->AddFormatted(" %s", Code::ICState2String(ic_state)); |
| + } |
| + } else if (kind == Code::STUB || kind == Code::HANDLER) { |
| + // Get the STUB key and extract major and minor key. |
| + uint32_t key = code->stub_key(); |
| + uint32_t minor_key = CodeStub::MinorKeyFromKey(key); |
| + CodeStub::Major major_key = CodeStub::GetMajorKey(code); |
| + DCHECK(major_key == CodeStub::MajorKeyFromKey(key)); |
| + out->AddFormatted(" %s, %s, ", Code::Kind2String(kind), |
| + CodeStub::MajorName(major_key)); |
| + out->AddFormatted("minor: %d", minor_key); |
| + } else { |
| + out->AddFormatted(" %s", Code::Kind2String(kind)); |
| + } |
| + if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { |
| + out->AddFormatted(" (id = %d)", static_cast<int>(relocinfo->data())); |
| + } |
| + } else if (RelocInfo::IsRuntimeEntry(rmode) && |
| + isolate->deoptimizer_data() != nullptr) { |
| + // A runtime entry reloinfo might be a deoptimization bailout-> |
| + Address addr = relocinfo->target_address(); |
| + int id = |
| + Deoptimizer::GetDeoptimizationId(isolate, addr, Deoptimizer::EAGER); |
| + if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| + id = Deoptimizer::GetDeoptimizationId(isolate, addr, Deoptimizer::LAZY); |
| + if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| + id = Deoptimizer::GetDeoptimizationId(isolate, addr, Deoptimizer::SOFT); |
| + if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| + out->AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); |
| + } else { |
| + out->AddFormatted(" ;; soft deoptimization bailout %d", id); |
| + } |
| + } else { |
| + out->AddFormatted(" ;; lazy deoptimization bailout %d", id); |
| + } |
| + } else { |
| + out->AddFormatted(" ;; deoptimization bailout %d", id); |
| + } |
| + } else { |
| + out->AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); |
| + } |
| +} |
| + |
| static int DecodeIt(Isolate* isolate, std::ostream* os, |
| const V8NameConverter& converter, byte* begin, byte* end) { |
| SealHandleScope shs(isolate); |
| @@ -162,97 +252,32 @@ static int DecodeIt(Isolate* isolate, std::ostream* os, |
| // Put together the reloc info |
| RelocInfo relocinfo(pcs[i], rmodes[i], datas[i], converter.code()); |
| - // Indent the printing of the reloc info. |
| - if (i == 0) { |
| - // The first reloc info is printed after the disassembled instruction. |
| - out.AddPadding(' ', kRelocInfoPosition - out.position()); |
| - } else { |
| - // Additional reloc infos are printed on separate lines. |
| - DumpBuffer(os, &out); |
| - out.AddPadding(' ', kRelocInfoPosition); |
| - } |
| + bool first_reloc_info = (i == 0); |
| + PrintRelocInfo(&out, isolate, ref_encoder, os, &relocinfo, |
| + first_reloc_info); |
| + } |
| - RelocInfo::Mode rmode = relocinfo.rmode(); |
| - if (rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) { |
| - out.AddFormatted(" ;; debug: deopt position, script offset '%d'", |
| - static_cast<int>(relocinfo.data())); |
| - } else if (rmode == RelocInfo::DEOPT_INLINING_ID) { |
| - out.AddFormatted(" ;; debug: deopt position, inlining id '%d'", |
| - static_cast<int>(relocinfo.data())); |
| - } else if (rmode == RelocInfo::DEOPT_REASON) { |
| - DeoptimizeReason reason = |
| - static_cast<DeoptimizeReason>(relocinfo.data()); |
| - out.AddFormatted(" ;; debug: deopt reason '%s'", |
| - DeoptimizeReasonToString(reason)); |
| - } else if (rmode == RelocInfo::DEOPT_ID) { |
| - out.AddFormatted(" ;; debug: deopt index %d", |
| - static_cast<int>(relocinfo.data())); |
| - } else if (rmode == RelocInfo::EMBEDDED_OBJECT) { |
| - HeapStringAllocator allocator; |
| - StringStream accumulator(&allocator); |
| - relocinfo.target_object()->ShortPrint(&accumulator); |
| - std::unique_ptr<char[]> obj_name = accumulator.ToCString(); |
| - out.AddFormatted(" ;; object: %s", obj_name.get()); |
| - } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { |
| - const char* reference_name = ref_encoder.NameOfAddress( |
| - isolate, relocinfo.target_external_reference()); |
| - out.AddFormatted(" ;; external reference (%s)", reference_name); |
| - } else if (RelocInfo::IsCodeTarget(rmode)) { |
| - out.AddFormatted(" ;; code:"); |
| - Code* code = Code::GetCodeFromTargetAddress(relocinfo.target_address()); |
| - Code::Kind kind = code->kind(); |
| - if (code->is_inline_cache_stub()) { |
| - out.AddFormatted(" %s", Code::Kind2String(kind)); |
| - if (kind == Code::BINARY_OP_IC || kind == Code::TO_BOOLEAN_IC || |
| - kind == Code::COMPARE_IC) { |
| - InlineCacheState ic_state = IC::StateFromCode(code); |
| - out.AddFormatted(" %s", Code::ICState2String(ic_state)); |
| + // If this is a constant pool load and we haven't found any RelocInfo |
| + // already, check if we can find some RelocInfo for the target address in |
| + // the constant pool. |
| + if (pcs.is_empty() && converter.code() != nullptr) { |
| + RelocInfo dummy_rinfo(prev_pc, RelocInfo::NONE32, 0, nullptr); |
| + if (dummy_rinfo.IsInConstantPool()) { |
| + byte* constant_pool_entry_address = |
| + dummy_rinfo.constant_pool_entry_address(); |
| + RelocIterator* it = new RelocIterator(converter.code()); |
|
Clemens Hammacher
2017/05/24 10:47:36
This causes a memory leak: http://crbug.com/725714
|
| + while (!it->done()) { |
| + if (it->rinfo()->IsInConstantPool() && |
| + (it->rinfo()->constant_pool_entry_address() == |
| + constant_pool_entry_address)) { |
| + PrintRelocInfo(&out, isolate, ref_encoder, os, it->rinfo()); |
| + break; |
| } |
| - } else if (kind == Code::STUB || kind == Code::HANDLER) { |
| - // Get the STUB key and extract major and minor key. |
| - uint32_t key = code->stub_key(); |
| - uint32_t minor_key = CodeStub::MinorKeyFromKey(key); |
| - CodeStub::Major major_key = CodeStub::GetMajorKey(code); |
| - DCHECK(major_key == CodeStub::MajorKeyFromKey(key)); |
| - out.AddFormatted(" %s, %s, ", Code::Kind2String(kind), |
| - CodeStub::MajorName(major_key)); |
| - out.AddFormatted("minor: %d", minor_key); |
| - } else { |
| - out.AddFormatted(" %s", Code::Kind2String(kind)); |
| + it->next(); |
| } |
| - if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { |
| - out.AddFormatted(" (id = %d)", static_cast<int>(relocinfo.data())); |
| - } |
| - } else if (RelocInfo::IsRuntimeEntry(rmode) && |
| - isolate->deoptimizer_data() != NULL) { |
| - // A runtime entry reloinfo might be a deoptimization bailout. |
| - Address addr = relocinfo.target_address(); |
| - int id = Deoptimizer::GetDeoptimizationId(isolate, |
| - addr, |
| - Deoptimizer::EAGER); |
| - if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| - id = Deoptimizer::GetDeoptimizationId(isolate, |
| - addr, |
| - Deoptimizer::LAZY); |
| - if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| - id = Deoptimizer::GetDeoptimizationId(isolate, |
| - addr, |
| - Deoptimizer::SOFT); |
| - if (id == Deoptimizer::kNotDeoptimizationEntry) { |
| - out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); |
| - } else { |
| - out.AddFormatted(" ;; soft deoptimization bailout %d", id); |
| - } |
| - } else { |
| - out.AddFormatted(" ;; lazy deoptimization bailout %d", id); |
| - } |
| - } else { |
| - out.AddFormatted(" ;; deoptimization bailout %d", id); |
| - } |
| - } else { |
| - out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); |
| } |
| } |
| + |
| DumpBuffer(os, &out); |
| } |