diff options
Diffstat (limited to 'V8Binding/v8/src/disassembler.cc')
-rw-r--r-- | V8Binding/v8/src/disassembler.cc | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/V8Binding/v8/src/disassembler.cc b/V8Binding/v8/src/disassembler.cc deleted file mode 100644 index e2f908d..0000000 --- a/V8Binding/v8/src/disassembler.cc +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "v8.h" - -#include "code-stubs.h" -#include "codegen-inl.h" -#include "debug.h" -#include "disasm.h" -#include "disassembler.h" -#include "macro-assembler.h" -#include "serialize.h" -#include "string-stream.h" - -namespace v8 { -namespace internal { - -#ifdef ENABLE_DISASSEMBLER - -void Disassembler::Dump(FILE* f, byte* begin, byte* end) { - for (byte* pc = begin; pc < end; pc++) { - if (f == NULL) { - PrintF("%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n", pc, pc - begin, *pc); - } else { - fprintf(f, "%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n", - reinterpret_cast<uintptr_t>(pc), pc - begin, *pc); - } - } -} - - -class V8NameConverter: public disasm::NameConverter { - public: - explicit V8NameConverter(Code* code) : code_(code) {} - virtual const char* NameOfAddress(byte* pc) const; - virtual const char* NameInCode(byte* addr) const; - Code* code() const { return code_; } - private: - Code* code_; -}; - - -const char* V8NameConverter::NameOfAddress(byte* pc) const { - static v8::internal::EmbeddedVector<char, 128> buffer; - - const char* name = Builtins::Lookup(pc); - if (name != NULL) { - OS::SNPrintF(buffer, "%s (%p)", name, pc); - return buffer.start(); - } - - if (code_ != NULL) { - int offs = pc - code_->instruction_start(); - // print as code offset, if it seems reasonable - if (0 <= offs && offs < code_->instruction_size()) { - OS::SNPrintF(buffer, "%d (%p)", offs, pc); - return buffer.start(); - } - } - - return disasm::NameConverter::NameOfAddress(pc); -} - - -const char* V8NameConverter::NameInCode(byte* addr) const { - // The V8NameConverter is used for well known code, so we can "safely" - // dereference pointers in generated code. - return (code_ != NULL) ? reinterpret_cast<const char*>(addr) : ""; -} - - -static void DumpBuffer(FILE* f, char* buff) { - if (f == NULL) { - PrintF("%s", buff); - } else { - fprintf(f, "%s", buff); - } -} - -static const int kOutBufferSize = 2048 + String::kMaxShortPrintLength; -static const int kRelocInfoPosition = 57; - -static int DecodeIt(FILE* f, - const V8NameConverter& converter, - byte* begin, - byte* end) { - NoHandleAllocation ha; - AssertNoAllocation no_alloc; - ExternalReferenceEncoder ref_encoder; - - v8::internal::EmbeddedVector<char, 128> decode_buffer; - v8::internal::EmbeddedVector<char, kOutBufferSize> out_buffer; - byte* pc = begin; - disasm::Disassembler d(converter); - RelocIterator* it = NULL; - if (converter.code() != NULL) { - it = new RelocIterator(converter.code()); - } else { - // No relocation information when printing code stubs. - } - int constants = -1; // no constants being decoded at the start - - while (pc < end) { - // First decode instruction so that we know its length. - byte* prev_pc = pc; - if (constants > 0) { - OS::SNPrintF(decode_buffer, - "%08x constant", - *reinterpret_cast<int32_t*>(pc)); - constants--; - pc += 4; - } else { - int num_const = d.ConstantPoolSizeAt(pc); - if (num_const >= 0) { - OS::SNPrintF(decode_buffer, - "%08x constant pool begin", - *reinterpret_cast<int32_t*>(pc)); - constants = num_const; - pc += 4; - } else if (it != NULL && !it->done() && it->rinfo()->pc() == pc && - it->rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) { - // raw pointer embedded in code stream, e.g., jump table - byte* ptr = *reinterpret_cast<byte**>(pc); - OS::SNPrintF(decode_buffer, - "%08" V8PRIxPTR " jump table entry %4" V8PRIdPTR, - ptr, - ptr - begin); - pc += 4; - } else { - decode_buffer[0] = '\0'; - pc += d.InstructionDecode(decode_buffer, pc); - } - } - - // Collect RelocInfo for this instruction (prev_pc .. pc-1) - List<const char*> comments(4); - List<byte*> pcs(1); - List<RelocInfo::Mode> rmodes(1); - List<intptr_t> datas(1); - if (it != NULL) { - while (!it->done() && it->rinfo()->pc() < pc) { - if (RelocInfo::IsComment(it->rinfo()->rmode())) { - // For comments just collect the text. - comments.Add(reinterpret_cast<const char*>(it->rinfo()->data())); - } else { - // For other reloc info collect all data. - pcs.Add(it->rinfo()->pc()); - rmodes.Add(it->rinfo()->rmode()); - datas.Add(it->rinfo()->data()); - } - it->next(); - } - } - - StringBuilder out(out_buffer.start(), out_buffer.length()); - - // Comments. - for (int i = 0; i < comments.length(); i++) { - out.AddFormatted(" %s\n", comments[i]); - } - - // Write out comments, resets outp so that we can format the next line. - DumpBuffer(f, out.Finalize()); - out.Reset(); - - // Instruction address and instruction offset. - out.AddFormatted("%p %4d ", prev_pc, prev_pc - begin); - - // Instruction. - out.AddFormatted("%s", decode_buffer.start()); - - // Print all the reloc info for this instruction which are not comments. - for (int i = 0; i < pcs.length(); i++) { - // Put together the reloc info - RelocInfo relocinfo(pcs[i], rmodes[i], datas[i]); - - // 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. - out.AddFormatted("\n"); - out.AddPadding(' ', kRelocInfoPosition); - } - - RelocInfo::Mode rmode = relocinfo.rmode(); - if (RelocInfo::IsPosition(rmode)) { - if (RelocInfo::IsStatementPosition(rmode)) { - out.AddFormatted(" ;; debug: statement %d", relocinfo.data()); - } else { - out.AddFormatted(" ;; debug: position %d", relocinfo.data()); - } - } else if (rmode == RelocInfo::EMBEDDED_OBJECT) { - HeapStringAllocator allocator; - StringStream accumulator(&allocator); - relocinfo.target_object()->ShortPrint(&accumulator); - SmartPointer<const char> obj_name = accumulator.ToCString(); - out.AddFormatted(" ;; object: %s", *obj_name); - } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { - const char* reference_name = - ref_encoder.NameOfAddress(*relocinfo.target_reference_address()); - out.AddFormatted(" ;; external reference (%s)", reference_name); - } else if (RelocInfo::IsCodeTarget(rmode)) { - out.AddFormatted(" ;; code:"); - if (rmode == RelocInfo::CONSTRUCT_CALL) { - out.AddFormatted(" constructor,"); - } - Code* code = Code::GetCodeFromTargetAddress(relocinfo.target_address()); - Code::Kind kind = code->kind(); - if (code->is_inline_cache_stub()) { - if (rmode == RelocInfo::CODE_TARGET_CONTEXT) { - out.AddFormatted(" contextual,"); - } - InlineCacheState ic_state = code->ic_state(); - out.AddFormatted(" %s, %s", Code::Kind2String(kind), - Code::ICState2String(ic_state)); - if (ic_state == MONOMORPHIC) { - PropertyType type = code->type(); - out.AddFormatted(", %s", Code::PropertyType2String(type)); - } - if (code->ic_in_loop() == IN_LOOP) { - out.AddFormatted(", in_loop"); - } - if (kind == Code::CALL_IC) { - out.AddFormatted(", argc = %d", code->arguments_count()); - } - } else if (kind == Code::STUB) { - // Reverse lookup required as the minor key cannot be retrieved - // from the code object. - Object* obj = Heap::code_stubs()->SlowReverseLookup(code); - if (obj != Heap::undefined_value()) { - ASSERT(obj->IsSmi()); - // Get the STUB key and extract major and minor key. - uint32_t key = Smi::cast(obj)->value(); - uint32_t minor_key = CodeStub::MinorKeyFromKey(key); - ASSERT(code->major_key() == CodeStub::MajorKeyFromKey(key)); - out.AddFormatted(" %s, %s, ", - Code::Kind2String(kind), - CodeStub::MajorName(code->major_key())); - switch (code->major_key()) { - case CodeStub::CallFunction: - out.AddFormatted("argc = %d", minor_key); - break; - case CodeStub::Runtime: { - const char* name = - RuntimeStub::GetNameFromMinorKey(minor_key); - out.AddFormatted("%s", name); - break; - } - default: - out.AddFormatted("minor: %d", minor_key); - } - } - } else { - out.AddFormatted(" %s", Code::Kind2String(kind)); - } - } else { - out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); - } - } - out.AddString("\n"); - DumpBuffer(f, out.Finalize()); - out.Reset(); - } - - delete it; - return pc - begin; -} - - -int Disassembler::Decode(FILE* f, byte* begin, byte* end) { - V8NameConverter defaultConverter(NULL); - return DecodeIt(f, defaultConverter, begin, end); -} - - -// Called by Code::CodePrint. -void Disassembler::Decode(FILE* f, Code* code) { - byte* begin = Code::cast(code)->instruction_start(); - byte* end = begin + Code::cast(code)->instruction_size(); - V8NameConverter v8NameConverter(code); - DecodeIt(f, v8NameConverter, begin, end); -} - -#else // ENABLE_DISASSEMBLER - -void Disassembler::Dump(FILE* f, byte* begin, byte* end) {} -int Disassembler::Decode(FILE* f, byte* begin, byte* end) { return 0; } -void Disassembler::Decode(FILE* f, Code* code) {} - -#endif // ENABLE_DISASSEMBLER - -} } // namespace v8::internal |