1d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "code-stubs.h" 3144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h" 33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h" 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "disasm.h" 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "disassembler.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "macro-assembler.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "serialize.h" 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "string-stream.h" 3943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef ENABLE_DISASSEMBLER 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Disassembler::Dump(FILE* f, byte* begin, byte* end) { 4643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (byte* pc = begin; pc < end; pc++) { 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (f == NULL) { 48f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org PrintF("%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n", 49f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org reinterpret_cast<intptr_t>(pc), 50f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org pc - begin, 51f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org *pc); 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 53e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PrintF(f, "%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n", 54e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org reinterpret_cast<uintptr_t>(pc), pc - begin, *pc); 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass V8NameConverter: public disasm::NameConverter { 6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public: 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen explicit V8NameConverter(Code* code) : code_(code) {} 6343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen virtual const char* NameOfAddress(byte* pc) const; 647276f14ca716596e0a0d17539516370c1f453847kasper.lund virtual const char* NameInCode(byte* addr) const; 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* code() const { return code_; } 6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private: 6743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* code_; 68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 69ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org EmbeddedVector<char, 128> v8_buffer_; 7043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 7143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* V8NameConverter::NameOfAddress(byte* pc) const { 74ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const char* name = Isolate::Current()->builtins()->Lookup(pc); 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (name != NULL) { 76ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org OS::SNPrintF(v8_buffer_, "%s (%p)", name, pc); 77ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return v8_buffer_.start(); 7843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (code_ != NULL) { 81c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int offs = static_cast<int>(pc - code_->instruction_start()); 8243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // print as code offset, if it seems reasonable 8343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (0 <= offs && offs < code_->instruction_size()) { 84ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org OS::SNPrintF(v8_buffer_, "%d (%p)", offs, pc); 85ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return v8_buffer_.start(); 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return disasm::NameConverter::NameOfAddress(pc); 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 937276f14ca716596e0a0d17539516370c1f453847kasper.lundconst char* V8NameConverter::NameInCode(byte* addr) const { 947276f14ca716596e0a0d17539516370c1f453847kasper.lund // The V8NameConverter is used for well known code, so we can "safely" 957276f14ca716596e0a0d17539516370c1f453847kasper.lund // dereference pointers in generated code. 967276f14ca716596e0a0d17539516370c1f453847kasper.lund return (code_ != NULL) ? reinterpret_cast<const char*>(addr) : ""; 977276f14ca716596e0a0d17539516370c1f453847kasper.lund} 987276f14ca716596e0a0d17539516370c1f453847kasper.lund 997276f14ca716596e0a0d17539516370c1f453847kasper.lund 1004acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.orgstatic void DumpBuffer(FILE* f, StringBuilder* out) { 1017276f14ca716596e0a0d17539516370c1f453847kasper.lund if (f == NULL) { 1024acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org PrintF("%s\n", out->Finalize()); 1037276f14ca716596e0a0d17539516370c1f453847kasper.lund } else { 104e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org PrintF(f, "%s\n", out->Finalize()); 1057276f14ca716596e0a0d17539516370c1f453847kasper.lund } 1064acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org out->Reset(); 10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 10843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1094acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 110bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgstatic const int kOutBufferSize = 2048 + String::kMaxShortPrintLength; 11143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic const int kRelocInfoPosition = 57; 11243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgstatic int DecodeIt(Isolate* isolate, 11409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org FILE* f, 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const V8NameConverter& converter, 11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* begin, 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* end) { 11879e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org SealHandleScope shs(isolate); 11979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org DisallowHeapAllocation no_alloc; 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ExternalReferenceEncoder ref_encoder; 121ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Heap* heap = HEAP; 12243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 123b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org v8::internal::EmbeddedVector<char, 128> decode_buffer; 124b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org v8::internal::EmbeddedVector<char, kOutBufferSize> out_buffer; 1254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org StringBuilder out(out_buffer.start(), out_buffer.length()); 12643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* pc = begin; 12743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen disasm::Disassembler d(converter); 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RelocIterator* it = NULL; 12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (converter.code() != NULL) { 13043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it = new RelocIterator(converter.code()); 13143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 13243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // No relocation information when printing code stubs. 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1347276f14ca716596e0a0d17539516370c1f453847kasper.lund int constants = -1; // no constants being decoded at the start 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (pc < end) { 13743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // First decode instruction so that we know its length. 13843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen byte* prev_pc = pc; 1397276f14ca716596e0a0d17539516370c1f453847kasper.lund if (constants > 0) { 1407276f14ca716596e0a0d17539516370c1f453847kasper.lund OS::SNPrintF(decode_buffer, 1417276f14ca716596e0a0d17539516370c1f453847kasper.lund "%08x constant", 1427276f14ca716596e0a0d17539516370c1f453847kasper.lund *reinterpret_cast<int32_t*>(pc)); 1437276f14ca716596e0a0d17539516370c1f453847kasper.lund constants--; 1447276f14ca716596e0a0d17539516370c1f453847kasper.lund pc += 4; 1457276f14ca716596e0a0d17539516370c1f453847kasper.lund } else { 1467276f14ca716596e0a0d17539516370c1f453847kasper.lund int num_const = d.ConstantPoolSizeAt(pc); 1477276f14ca716596e0a0d17539516370c1f453847kasper.lund if (num_const >= 0) { 1487276f14ca716596e0a0d17539516370c1f453847kasper.lund OS::SNPrintF(decode_buffer, 1497276f14ca716596e0a0d17539516370c1f453847kasper.lund "%08x constant pool begin", 1507276f14ca716596e0a0d17539516370c1f453847kasper.lund *reinterpret_cast<int32_t*>(pc)); 1517276f14ca716596e0a0d17539516370c1f453847kasper.lund constants = num_const; 1527276f14ca716596e0a0d17539516370c1f453847kasper.lund pc += 4; 153236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } else if (it != NULL && !it->done() && it->rinfo()->pc() == pc && 154236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org it->rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) { 155236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // raw pointer embedded in code stream, e.g., jump table 156236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org byte* ptr = *reinterpret_cast<byte**>(pc); 157236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org OS::SNPrintF(decode_buffer, 158b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org "%08" V8PRIxPTR " jump table entry %4" V8PRIdPTR, 159b3284ad36ee358a35b81379ad1c449e4f8021362kasperl@chromium.org ptr, 160236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org ptr - begin); 161236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org pc += 4; 1627276f14ca716596e0a0d17539516370c1f453847kasper.lund } else { 1637276f14ca716596e0a0d17539516370c1f453847kasper.lund decode_buffer[0] = '\0'; 164b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org pc += d.InstructionDecode(decode_buffer, pc); 1657276f14ca716596e0a0d17539516370c1f453847kasper.lund } 1667276f14ca716596e0a0d17539516370c1f453847kasper.lund } 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Collect RelocInfo for this instruction (prev_pc .. pc-1) 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen List<const char*> comments(4); 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen List<byte*> pcs(1); 171236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org List<RelocInfo::Mode> rmodes(1); 17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen List<intptr_t> datas(1); 17343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (it != NULL) { 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (!it->done() && it->rinfo()->pc() < pc) { 175236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsComment(it->rinfo()->rmode())) { 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For comments just collect the text. 17743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen comments.Add(reinterpret_cast<const char*>(it->rinfo()->data())); 17843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // For other reloc info collect all data. 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen pcs.Add(it->rinfo()->pc()); 18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen rmodes.Add(it->rinfo()->rmode()); 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen datas.Add(it->rinfo()->data()); 18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen it->next(); 18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 18743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Comments. 18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < comments.length(); i++) { 1904acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org out.AddFormatted(" %s", comments[i]); 1914acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DumpBuffer(f, &out); 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Instruction address and instruction offset. 1957276f14ca716596e0a0d17539516370c1f453847kasper.lund out.AddFormatted("%p %4d ", prev_pc, prev_pc - begin); 19643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1977276f14ca716596e0a0d17539516370c1f453847kasper.lund // Instruction. 198b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted("%s", decode_buffer.start()); 19943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Print all the reloc info for this instruction which are not comments. 20143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < pcs.length(); i++) { 20243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Put together the reloc info 203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo relocinfo(pcs[i], rmodes[i], datas[i], NULL); 20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Indent the printing of the reloc info. 20643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (i == 0) { 20743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // The first reloc info is printed after the disassembled instruction. 2087276f14ca716596e0a0d17539516370c1f453847kasper.lund out.AddPadding(' ', kRelocInfoPosition - out.position()); 20943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Additional reloc infos are printed on separate lines. 2114acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DumpBuffer(f, &out); 2127276f14ca716596e0a0d17539516370c1f453847kasper.lund out.AddPadding(' ', kRelocInfoPosition); 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 215236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org RelocInfo::Mode rmode = relocinfo.rmode(); 216236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsPosition(rmode)) { 217236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (RelocInfo::IsStatementPosition(rmode)) { 218b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" ;; debug: statement %d", relocinfo.data()); 219b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 220b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" ;; debug: position %d", relocinfo.data()); 221b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 222236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } else if (rmode == RelocInfo::EMBEDDED_OBJECT) { 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen HeapStringAllocator allocator; 22443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen StringStream accumulator(&allocator); 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen relocinfo.target_object()->ShortPrint(&accumulator); 22683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org SmartArrayPointer<const char> obj_name = accumulator.ToCString(); 2277276f14ca716596e0a0d17539516370c1f453847kasper.lund out.AddFormatted(" ;; object: %s", *obj_name); 228236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const char* reference_name = 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ref_encoder.NameOfAddress(*relocinfo.target_reference_address()); 2317276f14ca716596e0a0d17539516370c1f453847kasper.lund out.AddFormatted(" ;; external reference (%s)", reference_name); 232236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org } else if (RelocInfo::IsCodeTarget(rmode)) { 233b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" ;; code:"); 234236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (rmode == RelocInfo::CONSTRUCT_CALL) { 235b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" constructor,"); 236b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 2378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org Code* code = Code::GetCodeFromTargetAddress(relocinfo.target_address()); 238b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Code::Kind kind = code->kind(); 239b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (code->is_inline_cache_stub()) { 240236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org if (rmode == RelocInfo::CODE_TARGET_CONTEXT) { 241b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" contextual,"); 242b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 243b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org InlineCacheState ic_state = code->ic_state(); 244b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" %s, %s", Code::Kind2String(kind), 245b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Code::ICState2String(ic_state)); 2462abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org if (ic_state == MONOMORPHIC) { 2477a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org Code::StubType type = code->type(); 2487a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org out.AddFormatted(", %s", Code::StubType2String(type)); 2492abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org } 2501af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) { 251b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(", argc = %d", code->arguments_count()); 252b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 253b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else if (kind == Code::STUB) { 254b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Reverse lookup required as the minor key cannot be retrieved 255b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // from the code object. 256ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Object* obj = heap->code_stubs()->SlowReverseLookup(code); 257ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (obj != heap->undefined_value()) { 258b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org ASSERT(obj->IsSmi()); 259b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Get the STUB key and extract major and minor key. 260b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org uint32_t key = Smi::cast(obj)->value(); 261b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org uint32_t minor_key = CodeStub::MinorKeyFromKey(key); 262d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org CodeStub::Major major_key = CodeStub::GetMajorKey(code); 263d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org ASSERT(major_key == CodeStub::MajorKeyFromKey(key)); 264b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" %s, %s, ", 265b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Code::Kind2String(kind), 266d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org CodeStub::MajorName(major_key, false)); 267d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org switch (major_key) { 268d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org case CodeStub::CallFunction: { 269d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org int argc = 270d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org CallFunctionStub::ExtractArgcFromMinorKey(minor_key); 271d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org out.AddFormatted("argc = %d", argc); 272b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org break; 273d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org } 274d2c22f0121ebc55ee26a9e742f0fd7c0b8397730kmillikin@chromium.org default: 275b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted("minor: %d", minor_key); 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 278b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 279b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" %s", Code::Kind2String(kind)); 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 2818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org if (rmode == RelocInfo::CODE_TARGET_WITH_ID) { 2828e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org out.AddFormatted(" (id = %d)", static_cast<int>(relocinfo.data())); 2838e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org } 2842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } else if (RelocInfo::IsRuntimeEntry(rmode) && 28509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate->deoptimizer_data() != NULL) { 286a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // A runtime entry reloinfo might be a deoptimization bailout. 287a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Address addr = relocinfo.target_address(); 288876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org int id = Deoptimizer::GetDeoptimizationId(isolate, 289876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org addr, 290876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Deoptimizer::EAGER); 291a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 292876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org id = Deoptimizer::GetDeoptimizationId(isolate, 293876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org addr, 294876cca833d7212e476250d102cad185cdcfa9dfesvenpanne@chromium.org Deoptimizer::LAZY); 295a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 296aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org id = Deoptimizer::GetDeoptimizationId(isolate, 297aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org addr, 298aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Deoptimizer::SOFT); 299aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org if (id == Deoptimizer::kNotDeoptimizationEntry) { 300aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); 301aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org } else { 302aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org out.AddFormatted(" ;; soft deoptimization bailout %d", id); 303aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org } 304a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } else { 305a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org out.AddFormatted(" ;; lazy deoptimization bailout %d", id); 306a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 307a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } else { 308a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org out.AddFormatted(" ;; deoptimization bailout %d", id); 309a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 310b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } else { 311b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode)); 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 3144acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DumpBuffer(f, &out); 3154acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 3164acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org 3174acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org // Emit comments following the last instruction (if any). 3184acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (it != NULL) { 3194acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org for ( ; !it->done(); it->next()) { 3204acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org if (RelocInfo::IsComment(it->rinfo()->rmode())) { 3214acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org out.AddFormatted(" %s", 3224acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org reinterpret_cast<const char*>(it->rinfo()->data())); 3234acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org DumpBuffer(f, &out); 3244acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 3254acdc2c8d4caecf7606db8af710366c1d6e28fe5whesse@chromium.org } 32643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen delete it; 329c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org return static_cast<int>(pc - begin); 33043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 33143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33309d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgint Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) { 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V8NameConverter defaultConverter(NULL); 33509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org return DecodeIt(isolate, f, defaultConverter, begin, end); 33643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3397276f14ca716596e0a0d17539516370c1f453847kasper.lund// Called by Code::CodePrint. 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Disassembler::Decode(FILE* f, Code* code) { 34109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Isolate* isolate = code->GetIsolate(); 342b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org int decode_size = code->is_crankshafted() 34383aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org ? static_cast<int>(code->safepoint_table_offset()) 344a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org : code->instruction_size(); 345e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // If there might be a back edge table, stop before reaching it. 346a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org if (code->kind() == Code::FUNCTION) { 347a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org decode_size = 348e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Min(decode_size, static_cast<int>(code->back_edge_table_offset())); 349a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 350a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 351a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org byte* begin = code->instruction_start(); 352a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org byte* end = begin + decode_size; 35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen V8NameConverter v8NameConverter(code); 35409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org DecodeIt(isolate, f, v8NameConverter, begin, end); 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 3567276f14ca716596e0a0d17539516370c1f453847kasper.lund 35743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#else // ENABLE_DISASSEMBLER 35843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Disassembler::Dump(FILE* f, byte* begin, byte* end) {} 36009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.orgint Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) { 36109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org return 0; 36209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org} 363e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 364e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 36543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Disassembler::Decode(FILE* f, Code* code) {} 36643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif // ENABLE_DISASSEMBLER 36843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 370