OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/disassembler.h" | 5 #include "vm/disassembler.h" |
6 | 6 |
7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/code_patcher.h" |
8 #include "vm/deopt_instructions.h" | 9 #include "vm/deopt_instructions.h" |
9 #include "vm/globals.h" | 10 #include "vm/globals.h" |
10 #include "vm/il_printer.h" | 11 #include "vm/il_printer.h" |
11 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
12 #include "vm/json_stream.h" | 13 #include "vm/json_stream.h" |
13 #include "vm/log.h" | 14 #include "vm/log.h" |
14 #include "vm/os.h" | 15 #include "vm/os.h" |
15 #include "vm/code_patcher.h" | |
16 | |
17 | 16 |
18 namespace dart { | 17 namespace dart { |
19 | 18 |
20 #ifndef PRODUCT | 19 #ifndef PRODUCT |
21 | 20 |
22 DECLARE_FLAG(bool, trace_inlining_intervals); | 21 DECLARE_FLAG(bool, trace_inlining_intervals); |
23 DEFINE_FLAG(bool, trace_source_positions, false, "Source position diagnostics"); | 22 DEFINE_FLAG(bool, trace_source_positions, false, "Source position diagnostics"); |
24 | 23 |
25 void DisassembleToStdout::ConsumeInstruction(const Code& code, | 24 void DisassembleToStdout::ConsumeInstruction(const Code& code, |
26 char* hex_buffer, | 25 char* hex_buffer, |
(...skipping 11 matching lines...) Expand all Loading... |
38 THR_Print(" "); | 37 THR_Print(" "); |
39 } | 38 } |
40 } | 39 } |
41 THR_Print("%s", human_buffer); | 40 THR_Print("%s", human_buffer); |
42 if (object != NULL) { | 41 if (object != NULL) { |
43 THR_Print(" %s", object->ToCString()); | 42 THR_Print(" %s", object->ToCString()); |
44 } | 43 } |
45 THR_Print("\n"); | 44 THR_Print("\n"); |
46 } | 45 } |
47 | 46 |
48 | |
49 void DisassembleToStdout::Print(const char* format, ...) { | 47 void DisassembleToStdout::Print(const char* format, ...) { |
50 va_list args; | 48 va_list args; |
51 va_start(args, format); | 49 va_start(args, format); |
52 THR_VPrint(format, args); | 50 THR_VPrint(format, args); |
53 va_end(args); | 51 va_end(args); |
54 } | 52 } |
55 | 53 |
56 | |
57 void DisassembleToJSONStream::ConsumeInstruction(const Code& code, | 54 void DisassembleToJSONStream::ConsumeInstruction(const Code& code, |
58 char* hex_buffer, | 55 char* hex_buffer, |
59 intptr_t hex_size, | 56 intptr_t hex_size, |
60 char* human_buffer, | 57 char* human_buffer, |
61 intptr_t human_size, | 58 intptr_t human_size, |
62 Object* object, | 59 Object* object, |
63 uword pc) { | 60 uword pc) { |
64 // Instructions are represented as four consecutive values in a JSON array. | 61 // Instructions are represented as four consecutive values in a JSON array. |
65 // The first is the address of the instruction, the second is the hex string, | 62 // The first is the address of the instruction, the second is the hex string, |
66 // of the code, and the third is a human readable string, and the fourth is | 63 // of the code, and the third is a human readable string, and the fourth is |
67 // the object loaded by the instruction. | 64 // the object loaded by the instruction. |
68 jsarr_.AddValueF("%" Pp "", pc); | 65 jsarr_.AddValueF("%" Pp "", pc); |
69 jsarr_.AddValue(hex_buffer); | 66 jsarr_.AddValue(hex_buffer); |
70 jsarr_.AddValue(human_buffer); | 67 jsarr_.AddValue(human_buffer); |
71 | 68 |
72 if (object != NULL) { | 69 if (object != NULL) { |
73 jsarr_.AddValue(*object); | 70 jsarr_.AddValue(*object); |
74 } else { | 71 } else { |
75 jsarr_.AddValueNull(); // Not a reference to null. | 72 jsarr_.AddValueNull(); // Not a reference to null. |
76 } | 73 } |
77 } | 74 } |
78 | 75 |
79 | |
80 void DisassembleToJSONStream::Print(const char* format, ...) { | 76 void DisassembleToJSONStream::Print(const char* format, ...) { |
81 va_list args; | 77 va_list args; |
82 va_start(args, format); | 78 va_start(args, format); |
83 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 79 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
84 va_end(args); | 80 va_end(args); |
85 char* p = reinterpret_cast<char*>(malloc(len + 1)); | 81 char* p = reinterpret_cast<char*>(malloc(len + 1)); |
86 va_start(args, format); | 82 va_start(args, format); |
87 intptr_t len2 = OS::VSNPrint(p, len, format, args); | 83 intptr_t len2 = OS::VSNPrint(p, len, format, args); |
88 va_end(args); | 84 va_end(args); |
89 ASSERT(len == len2); | 85 ASSERT(len == len2); |
90 for (intptr_t i = 0; i < len; i++) { | 86 for (intptr_t i = 0; i < len; i++) { |
91 if (p[i] == '\n' || p[i] == '\r') { | 87 if (p[i] == '\n' || p[i] == '\r') { |
92 p[i] = ' '; | 88 p[i] = ' '; |
93 } | 89 } |
94 } | 90 } |
95 // Instructions are represented as four consecutive values in a JSON array. | 91 // Instructions are represented as four consecutive values in a JSON array. |
96 // Comments only use the third slot. See above comment for more information. | 92 // Comments only use the third slot. See above comment for more information. |
97 jsarr_.AddValueNull(); | 93 jsarr_.AddValueNull(); |
98 jsarr_.AddValueNull(); | 94 jsarr_.AddValueNull(); |
99 jsarr_.AddValue(p); | 95 jsarr_.AddValue(p); |
100 jsarr_.AddValueNull(); | 96 jsarr_.AddValueNull(); |
101 free(p); | 97 free(p); |
102 } | 98 } |
103 | 99 |
104 | |
105 void Disassembler::Disassemble(uword start, | 100 void Disassembler::Disassemble(uword start, |
106 uword end, | 101 uword end, |
107 DisassemblyFormatter* formatter, | 102 DisassemblyFormatter* formatter, |
108 const Code& code) { | 103 const Code& code) { |
109 const Code::Comments& comments = | 104 const Code::Comments& comments = |
110 code.IsNull() ? Code::Comments::New(0) : code.comments(); | 105 code.IsNull() ? Code::Comments::New(0) : code.comments(); |
111 ASSERT(formatter != NULL); | 106 ASSERT(formatter != NULL); |
112 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. | 107 char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. |
113 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. | 108 char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. |
114 uword pc = start; | 109 uword pc = start; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, | 147 DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, |
153 sizeof(human_buffer), &instruction_length, code, &object, | 148 sizeof(human_buffer), &instruction_length, code, &object, |
154 pc); | 149 pc); |
155 formatter->ConsumeInstruction(code, hex_buffer, sizeof(hex_buffer), | 150 formatter->ConsumeInstruction(code, hex_buffer, sizeof(hex_buffer), |
156 human_buffer, sizeof(human_buffer), object, | 151 human_buffer, sizeof(human_buffer), object, |
157 pc); | 152 pc); |
158 pc += instruction_length; | 153 pc += instruction_length; |
159 } | 154 } |
160 } | 155 } |
161 | 156 |
162 | |
163 void Disassembler::DisassembleCodeHelper(const char* function_fullname, | 157 void Disassembler::DisassembleCodeHelper(const char* function_fullname, |
164 const Code& code, | 158 const Code& code, |
165 bool optimized) { | 159 bool optimized) { |
166 Zone* zone = Thread::Current()->zone(); | 160 Zone* zone = Thread::Current()->zone(); |
167 LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(zone); | 161 LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(zone); |
168 if (FLAG_print_variable_descriptors) { | 162 if (FLAG_print_variable_descriptors) { |
169 var_descriptors = code.GetLocalVarDescriptors(); | 163 var_descriptors = code.GetLocalVarDescriptors(); |
170 } | 164 } |
171 THR_Print("Code for %sfunction '%s' {\n", optimized ? "optimized " : "", | 165 THR_Print("Code for %sfunction '%s' {\n", optimized ? "optimized " : "", |
172 function_fullname); | 166 function_fullname); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 THR_Print("}\n"); | 289 THR_Print("}\n"); |
296 } | 290 } |
297 if (optimized && FLAG_trace_inlining_intervals) { | 291 if (optimized && FLAG_trace_inlining_intervals) { |
298 code.DumpInlineIntervals(); | 292 code.DumpInlineIntervals(); |
299 } | 293 } |
300 if (FLAG_trace_source_positions) { | 294 if (FLAG_trace_source_positions) { |
301 code.DumpSourcePositions(); | 295 code.DumpSourcePositions(); |
302 } | 296 } |
303 } | 297 } |
304 | 298 |
305 | |
306 void Disassembler::DisassembleCode(const Function& function, | 299 void Disassembler::DisassembleCode(const Function& function, |
307 const Code& code, | 300 const Code& code, |
308 bool optimized) { | 301 bool optimized) { |
309 const char* function_fullname = function.ToFullyQualifiedCString(); | 302 const char* function_fullname = function.ToFullyQualifiedCString(); |
310 DisassembleCodeHelper(function_fullname, code, optimized); | 303 DisassembleCodeHelper(function_fullname, code, optimized); |
311 } | 304 } |
312 | 305 |
313 | |
314 #endif // !PRODUCT | 306 #endif // !PRODUCT |
315 | 307 |
316 } // namespace dart | 308 } // namespace dart |
OLD | NEW |