43 #ifdef ENABLE_DISASSEMBLER
49 reinterpret_cast<intptr_t>(
pc),
54 reinterpret_cast<uintptr_t>(
pc),
pc - begin, *
pc);
62 explicit V8NameConverter(Code*
code) : code_(code) {}
63 virtual const char* NameOfAddress(
byte*
pc)
const;
64 virtual const char* NameInCode(
byte* addr)
const;
65 Code*
code()
const {
return code_; }
69 EmbeddedVector<char, 128> v8_buffer_;
73 const char* V8NameConverter::NameOfAddress(
byte*
pc)
const {
74 const char* name = Isolate::Current()->builtins()->Lookup(pc);
77 return v8_buffer_.start();
81 int offs =
static_cast<int>(pc - code_->instruction_start());
83 if (0 <= offs && offs < code_->instruction_size()) {
85 return v8_buffer_.start();
93 const char* V8NameConverter::NameInCode(
byte* addr)
const {
96 return (code_ !=
NULL) ?
reinterpret_cast<const char*
>(addr) :
"";
100 static void DumpBuffer(FILE* f, StringBuilder* out) {
102 PrintF(
"%s\n", out->Finalize());
104 fprintf(f,
"%s\n", out->Finalize());
112 static const int kRelocInfoPosition = 57;
114 static int DecodeIt(FILE* f,
115 const V8NameConverter& converter,
118 NoHandleAllocation ha;
119 AssertNoAllocation no_alloc;
120 ExternalReferenceEncoder ref_encoder;
125 StringBuilder out(out_buffer.
start(), out_buffer.
length());
128 RelocIterator* it =
NULL;
129 if (converter.code() !=
NULL) {
130 it =
new RelocIterator(converter.code());
142 *reinterpret_cast<int32_t*>(pc));
146 int num_const = d.ConstantPoolSizeAt(pc);
147 if (num_const >= 0) {
149 "%08x constant pool begin",
150 *reinterpret_cast<int32_t*>(pc));
151 constants = num_const;
153 }
else if (it !=
NULL && !it->done() && it->rinfo()->pc() == pc &&
154 it->rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) {
163 decode_buffer[0] =
'\0';
164 pc += d.InstructionDecode(decode_buffer, pc);
169 List<const char*> comments(4);
171 List<RelocInfo::Mode> rmodes(1);
172 List<intptr_t> datas(1);
174 while (!it->done() && it->rinfo()->pc() <
pc) {
175 if (RelocInfo::IsComment(it->rinfo()->rmode())) {
177 comments.Add(reinterpret_cast<const char*>(it->rinfo()->data()));
180 pcs.Add(it->rinfo()->pc());
181 rmodes.Add(it->rinfo()->rmode());
182 datas.Add(it->rinfo()->data());
189 for (
int i = 0; i < comments.length(); i++) {
190 out.AddFormatted(
" %s", comments[i]);
195 out.AddFormatted(
"%p %4d ", prev_pc, prev_pc - begin);
198 out.AddFormatted(
"%s", decode_buffer.
start());
201 for (
int i = 0; i < pcs.length(); i++) {
203 RelocInfo relocinfo(pcs[i], rmodes[i], datas[i],
NULL);
208 out.AddPadding(
' ', kRelocInfoPosition - out.position());
212 out.AddPadding(
' ', kRelocInfoPosition);
215 RelocInfo::Mode rmode = relocinfo.rmode();
216 if (RelocInfo::IsPosition(rmode)) {
217 if (RelocInfo::IsStatementPosition(rmode)) {
218 out.AddFormatted(
" ;; debug: statement %d", relocinfo.data());
220 out.AddFormatted(
" ;; debug: position %d", relocinfo.data());
222 }
else if (rmode == RelocInfo::EMBEDDED_OBJECT) {
223 HeapStringAllocator allocator;
224 StringStream accumulator(&allocator);
225 relocinfo.target_object()->ShortPrint(&accumulator);
226 SmartArrayPointer<const char> obj_name = accumulator.ToCString();
227 out.AddFormatted(
" ;; object: %s", *obj_name);
228 }
else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
229 const char* reference_name =
230 ref_encoder.NameOfAddress(*relocinfo.target_reference_address());
231 out.AddFormatted(
" ;; external reference (%s)", reference_name);
232 }
else if (RelocInfo::IsCodeTarget(rmode)) {
233 out.AddFormatted(
" ;; code:");
234 if (rmode == RelocInfo::CONSTRUCT_CALL) {
235 out.AddFormatted(
" constructor,");
239 if (code->is_inline_cache_stub()) {
240 if (rmode == RelocInfo::CODE_TARGET_CONTEXT) {
241 out.AddFormatted(
" contextual,");
244 out.AddFormatted(
" %s, %s", Code::Kind2String(kind),
245 Code::ICState2String(ic_state));
248 out.AddFormatted(
", %s", Code::StubType2String(type));
250 if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) {
251 out.AddFormatted(
", argc = %d", code->arguments_count());
253 }
else if (kind == Code::STUB) {
256 Object* obj = heap->code_stubs()->SlowReverseLookup(code);
257 if (obj != heap->undefined_value()) {
261 uint32_t minor_key = CodeStub::MinorKeyFromKey(key);
262 CodeStub::Major major_key = CodeStub::GetMajorKey(code);
263 ASSERT(major_key == CodeStub::MajorKeyFromKey(key));
264 out.AddFormatted(
" %s, %s, ",
265 Code::Kind2String(kind),
266 CodeStub::MajorName(major_key,
false));
268 case CodeStub::CallFunction: {
271 out.AddFormatted(
"argc = %d", argc);
275 out.AddFormatted(
"minor: %d", minor_key);
279 out.AddFormatted(
" %s", Code::Kind2String(kind));
281 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
282 out.AddFormatted(
" (id = %d)", static_cast<int>(relocinfo.data()));
285 Isolate::Current()->deoptimizer_data() !=
NULL) {
287 Address addr = relocinfo.target_address();
290 out.AddFormatted(
" ;; %s", RelocInfo::RelocModeName(rmode));
292 out.AddFormatted(
" ;; deoptimization bailout %d",
id);
295 out.AddFormatted(
" ;; %s", RelocInfo::RelocModeName(rmode));
303 for ( ; !it->done(); it->next()) {
304 if (RelocInfo::IsComment(it->rinfo()->rmode())) {
305 out.AddFormatted(
" %s",
306 reinterpret_cast<const char*>(it->rinfo()->data()));
313 return static_cast<int>(pc - begin);
318 V8NameConverter defaultConverter(
NULL);
319 return DecodeIt(f, defaultConverter, begin, end);
325 int decode_size = (code->kind() == Code::OPTIMIZED_FUNCTION)
326 ? static_cast<int>(code->safepoint_table_offset())
327 : code->instruction_size();
329 if (code->kind() == Code::FUNCTION) {
331 Min(decode_size, static_cast<int>(code->stack_check_table_offset()));
334 byte* begin = code->instruction_start();
335 byte* end = begin + decode_size;
336 V8NameConverter v8NameConverter(code);
337 DecodeIt(f, v8NameConverter, begin, end);
340 #else // ENABLE_DISASSEMBLER
346 #endif // ENABLE_DISASSEMBLER
void PrintF(const char *format,...)
static int ExtractArgcFromMinorKey(int minor_key)
#define ASSERT(condition)
static Smi * cast(Object *object)
static Code * GetCodeFromTargetAddress(Address address)
virtual const char * NameOfAddress(byte *addr) const
static const int kMaxShortPrintLength
static int SNPrintF(Vector< char > str, const char *format,...)
static const int kNotDeoptimizationEntry
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
#define RUNTIME_ENTRY(name, nargs, ressize)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
static int Decode(FILE *f, byte *begin, byte *end)
static void Dump(FILE *f, byte *begin, byte *end)
static int GetDeoptimizationId(Address addr, BailoutType type)