| 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 |