| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 <setjmp.h> | 5 #include <setjmp.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #if defined(TARGET_ARCH_MIPS) | 9 #if defined(TARGET_ARCH_MIPS) |
| 10 | 10 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 98 |
| 99 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc); | 99 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc); |
| 100 | 100 |
| 101 static void PrintDartFrame(uword pc, uword fp, uword sp, | 101 static void PrintDartFrame(uword pc, uword fp, uword sp, |
| 102 const Function& function, | 102 const Function& function, |
| 103 intptr_t token_pos, | 103 intptr_t token_pos, |
| 104 bool is_optimized, | 104 bool is_optimized, |
| 105 bool is_inlined); | 105 bool is_inlined); |
| 106 void PrintBacktrace(); | 106 void PrintBacktrace(); |
| 107 | 107 |
| 108 static const int32_t kSimulatorBreakpointInstruction = | |
| 109 Instr::kBreakPointInstruction | | |
| 110 (Instr::kSimulatorBreakCode << kBreakCodeShift); | |
| 111 | |
| 112 // Set or delete a breakpoint. Returns true if successful. | 108 // Set or delete a breakpoint. Returns true if successful. |
| 113 bool SetBreakpoint(Instr* breakpc); | 109 bool SetBreakpoint(Instr* breakpc); |
| 114 bool DeleteBreakpoint(Instr* breakpc); | 110 bool DeleteBreakpoint(Instr* breakpc); |
| 115 | 111 |
| 116 // Undo and redo all breakpoints. This is needed to bracket disassembly and | 112 // Undo and redo all breakpoints. This is needed to bracket disassembly and |
| 117 // execution to skip past breakpoints when run from the debugger. | 113 // execution to skip past breakpoints when run from the debugger. |
| 118 void UndoBreakpoints(); | 114 void UndoBreakpoints(); |
| 119 void RedoBreakpoints(); | 115 void RedoBreakpoints(); |
| 120 }; | 116 }; |
| 121 | 117 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 | 382 |
| 387 void SimulatorDebugger::UndoBreakpoints() { | 383 void SimulatorDebugger::UndoBreakpoints() { |
| 388 if (sim_->break_pc_ != NULL) { | 384 if (sim_->break_pc_ != NULL) { |
| 389 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); | 385 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); |
| 390 } | 386 } |
| 391 } | 387 } |
| 392 | 388 |
| 393 | 389 |
| 394 void SimulatorDebugger::RedoBreakpoints() { | 390 void SimulatorDebugger::RedoBreakpoints() { |
| 395 if (sim_->break_pc_ != NULL) { | 391 if (sim_->break_pc_ != NULL) { |
| 396 sim_->break_pc_->SetInstructionBits(kSimulatorBreakpointInstruction); | 392 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction); |
| 397 } | 393 } |
| 398 } | 394 } |
| 399 | 395 |
| 400 | 396 |
| 401 void SimulatorDebugger::Debug() { | 397 void SimulatorDebugger::Debug() { |
| 402 intptr_t last_pc = -1; | 398 intptr_t last_pc = -1; |
| 403 bool done = false; | 399 bool done = false; |
| 404 | 400 |
| 405 #define COMMAND_SIZE 63 | 401 #define COMMAND_SIZE 63 |
| 406 #define ARG_SIZE 255 | 402 #define ARG_SIZE 255 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 533 OS::Print("printobject <*reg or *addr>\n"); | 529 OS::Print("printobject <*reg or *addr>\n"); |
| 534 } | 530 } |
| 535 } else if (strcmp(cmd, "disasm") == 0) { | 531 } else if (strcmp(cmd, "disasm") == 0) { |
| 536 uint32_t start = 0; | 532 uint32_t start = 0; |
| 537 uint32_t end = 0; | 533 uint32_t end = 0; |
| 538 if (args == 1) { | 534 if (args == 1) { |
| 539 start = sim_->get_pc(); | 535 start = sim_->get_pc(); |
| 540 end = start + (10 * Instr::kInstrSize); | 536 end = start + (10 * Instr::kInstrSize); |
| 541 } else if (args == 2) { | 537 } else if (args == 2) { |
| 542 if (GetValue(arg1, &start)) { | 538 if (GetValue(arg1, &start)) { |
| 543 // no length parameter passed, assume 10 instructions | 539 // No length parameter passed, assume 10 instructions. |
| 544 if (Simulator::IsIllegalAddress(start)) { | 540 if (Simulator::IsIllegalAddress(start)) { |
| 545 // If start isn't a valid address, warn and use PC instead | 541 // If start isn't a valid address, warn and use PC instead. |
| 546 OS::Print("First argument yields invalid address: 0x%x\n", start); | 542 OS::Print("First argument yields invalid address: 0x%x\n", start); |
| 547 OS::Print("Using PC instead"); | 543 OS::Print("Using PC instead\n"); |
| 548 start = sim_->get_pc(); | 544 start = sim_->get_pc(); |
| 549 } | 545 } |
| 550 end = start + (10 * Instr::kInstrSize); | 546 end = start + (10 * Instr::kInstrSize); |
| 551 } | 547 } |
| 552 } else { | 548 } else { |
| 553 uint32_t length; | 549 uint32_t length; |
| 554 if (GetValue(arg1, &start) && GetValue(arg2, &length)) { | 550 if (GetValue(arg1, &start) && GetValue(arg2, &length)) { |
| 555 if (Simulator::IsIllegalAddress(start)) { | 551 if (Simulator::IsIllegalAddress(start)) { |
| 556 // If start isn't a valid address, warn and use PC instead | 552 // If start isn't a valid address, warn and use PC instead. |
| 557 OS::Print("First argument yields invalid address: 0x%x\n", start); | 553 OS::Print("First argument yields invalid address: 0x%x\n", start); |
| 558 OS::Print("Using PC instead\n"); | 554 OS::Print("Using PC instead\n"); |
| 559 start = sim_->get_pc(); | 555 start = sim_->get_pc(); |
| 560 } | 556 } |
| 561 end = start + (length * Instr::kInstrSize); | 557 end = start + (length * Instr::kInstrSize); |
| 562 } | 558 } |
| 563 } | 559 } |
| 564 | 560 if ((start > 0) && (end > start)) { |
| 565 Disassembler::Disassemble(start, end); | 561 Disassembler::Disassemble(start, end); |
| 562 } else { |
| 563 OS::Print("disasm [<address> [<number_of_instructions>]]\n"); |
| 564 } |
| 566 } else if (strcmp(cmd, "gdb") == 0) { | 565 } else if (strcmp(cmd, "gdb") == 0) { |
| 567 OS::Print("relinquishing control to gdb\n"); | 566 OS::Print("relinquishing control to gdb\n"); |
| 568 OS::DebugBreak(); | 567 OS::DebugBreak(); |
| 569 OS::Print("regaining control from gdb\n"); | 568 OS::Print("regaining control from gdb\n"); |
| 570 } else if (strcmp(cmd, "break") == 0) { | 569 } else if (strcmp(cmd, "break") == 0) { |
| 571 if (args == 2) { | 570 if (args == 2) { |
| 572 uint32_t addr; | 571 uint32_t addr; |
| 573 if (GetValue(arg1, &addr)) { | 572 if (GetValue(arg1, &addr)) { |
| 574 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { | 573 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { |
| 575 OS::Print("setting breakpoint failed\n"); | 574 OS::Print("setting breakpoint failed\n"); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 Redirection* current; | 773 Redirection* current; |
| 775 for (current = list_; current != NULL; current = current->next_) { | 774 for (current = list_; current != NULL; current = current->next_) { |
| 776 if (current->address_of_break_instruction() == address_of_break) { | 775 if (current->address_of_break_instruction() == address_of_break) { |
| 777 return current->external_function_; | 776 return current->external_function_; |
| 778 } | 777 } |
| 779 } | 778 } |
| 780 return 0; | 779 return 0; |
| 781 } | 780 } |
| 782 | 781 |
| 783 private: | 782 private: |
| 784 static const int32_t kRedirectInstruction = | |
| 785 Instr::kBreakPointInstruction | (Instr::kRedirectCode << kBreakCodeShift); | |
| 786 | |
| 787 Redirection(uword external_function, | 783 Redirection(uword external_function, |
| 788 Simulator::CallKind call_kind, | 784 Simulator::CallKind call_kind, |
| 789 int argument_count) | 785 int argument_count) |
| 790 : external_function_(external_function), | 786 : external_function_(external_function), |
| 791 call_kind_(call_kind), | 787 call_kind_(call_kind), |
| 792 argument_count_(argument_count), | 788 argument_count_(argument_count), |
| 793 break_instruction_(kRedirectInstruction), | 789 break_instruction_(Instr::kSimulatorRedirectInstruction), |
| 794 next_(list_) { | 790 next_(list_) { |
| 795 list_ = this; | 791 list_ = this; |
| 796 } | 792 } |
| 797 | 793 |
| 798 uword external_function_; | 794 uword external_function_; |
| 799 Simulator::CallKind call_kind_; | 795 Simulator::CallKind call_kind_; |
| 800 int argument_count_; | 796 int argument_count_; |
| 801 uint32_t break_instruction_; | 797 uint32_t break_instruction_; |
| 802 Redirection* next_; | 798 Redirection* next_; |
| 803 static Redirection* list_; | 799 static Redirection* list_; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 | 1107 |
| 1112 | 1108 |
| 1113 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { | 1109 bool Simulator::HasExclusiveAccessAndOpen(uword addr) { |
| 1114 Isolate* isolate = Isolate::Current(); | 1110 Isolate* isolate = Isolate::Current(); |
| 1115 ASSERT(isolate != NULL); | 1111 ASSERT(isolate != NULL); |
| 1116 ASSERT(addr != 0); | 1112 ASSERT(addr != 0); |
| 1117 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); | 1113 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); |
| 1118 bool result = false; | 1114 bool result = false; |
| 1119 for (int i = 0; i < kNumAddressTags; i++) { | 1115 for (int i = 0; i < kNumAddressTags; i++) { |
| 1120 if (exclusive_access_state_[i].isolate == isolate) { | 1116 if (exclusive_access_state_[i].isolate == isolate) { |
| 1121 // Check whether the current isolates address reservation matches. | 1117 // Check whether the current isolate's address reservation matches. |
| 1122 if (exclusive_access_state_[i].addr == addr) { | 1118 if (exclusive_access_state_[i].addr == addr) { |
| 1123 result = true; | 1119 result = true; |
| 1124 } | 1120 } |
| 1125 exclusive_access_state_[i].addr = 0; | 1121 exclusive_access_state_[i].addr = 0; |
| 1126 } else if (exclusive_access_state_[i].addr == addr) { | 1122 } else if (exclusive_access_state_[i].addr == addr) { |
| 1127 // Other isolates with matching address lose their reservations. | 1123 // Other isolates with matching address lose their reservations. |
| 1128 exclusive_access_state_[i].addr = 0; | 1124 exclusive_access_state_[i].addr = 0; |
| 1129 } | 1125 } |
| 1130 } | 1126 } |
| 1131 return result; | 1127 return result; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 ASSERT(instr->OpcodeField() == SPECIAL); | 1192 ASSERT(instr->OpcodeField() == SPECIAL); |
| 1197 ASSERT(instr->FunctionField() == BREAK); | 1193 ASSERT(instr->FunctionField() == BREAK); |
| 1198 if (instr->BreakCodeField() == Instr::kStopMessageCode) { | 1194 if (instr->BreakCodeField() == Instr::kStopMessageCode) { |
| 1199 SimulatorDebugger dbg(this); | 1195 SimulatorDebugger dbg(this); |
| 1200 const char* message = *reinterpret_cast<const char**>( | 1196 const char* message = *reinterpret_cast<const char**>( |
| 1201 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); | 1197 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); |
| 1202 set_pc(get_pc() + Instr::kInstrSize); | 1198 set_pc(get_pc() + Instr::kInstrSize); |
| 1203 dbg.Stop(instr, message); | 1199 dbg.Stop(instr, message); |
| 1204 // Adjust for extra pc increment. | 1200 // Adjust for extra pc increment. |
| 1205 set_pc(get_pc() - Instr::kInstrSize); | 1201 set_pc(get_pc() - Instr::kInstrSize); |
| 1206 } else if (instr->BreakCodeField() == Instr::kMsgMessageCode) { | 1202 } else if (instr->BreakCodeField() == Instr::kSimulatorMessageCode) { |
| 1207 const char* message = *reinterpret_cast<const char**>( | 1203 const char* message = *reinterpret_cast<const char**>( |
| 1208 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); | 1204 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); |
| 1209 if (FLAG_trace_sim) { | 1205 if (FLAG_trace_sim) { |
| 1210 OS::Print("Message: %s\n", message); | 1206 OS::Print("Message: %s\n", message); |
| 1211 } else { | 1207 } else { |
| 1212 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits()); | 1208 OS::PrintErr("Bad break code: 0x%x\n", instr->InstructionBits()); |
| 1213 UnimplementedInstruction(instr); | 1209 UnimplementedInstruction(instr); |
| 1214 } | 1210 } |
| 1215 } else if (instr->BreakCodeField() == Instr::kRedirectCode) { | 1211 } else if (instr->BreakCodeField() == Instr::kSimulatorRedirectCode) { |
| 1216 SimulatorSetjmpBuffer buffer(this); | 1212 SimulatorSetjmpBuffer buffer(this); |
| 1217 | 1213 |
| 1218 if (!setjmp(buffer.buffer_)) { | 1214 if (!setjmp(buffer.buffer_)) { |
| 1219 int32_t saved_ra = get_register(RA); | 1215 int32_t saved_ra = get_register(RA); |
| 1220 Redirection* redirection = Redirection::FromBreakInstruction(instr); | 1216 Redirection* redirection = Redirection::FromBreakInstruction(instr); |
| 1221 uword external = redirection->external_function(); | 1217 uword external = redirection->external_function(); |
| 1222 if (FLAG_trace_sim) { | 1218 if (FLAG_trace_sim) { |
| 1223 OS::Print("Call to host function at 0x%" Pd "\n", external); | 1219 OS::Print("Call to host function at 0x%" Pd "\n", external); |
| 1224 } | 1220 } |
| 1225 | 1221 |
| (...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 if (IsIllegalAddress(pc_)) { | 2288 if (IsIllegalAddress(pc_)) { |
| 2293 HandleIllegalAccess(pc_, instr); | 2289 HandleIllegalAccess(pc_, instr); |
| 2294 } else { | 2290 } else { |
| 2295 InstructionDecode(instr); | 2291 InstructionDecode(instr); |
| 2296 } | 2292 } |
| 2297 } | 2293 } |
| 2298 } else { | 2294 } else { |
| 2299 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when | 2295 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
| 2300 // we reach the particular instruction count or address. | 2296 // we reach the particular instruction count or address. |
| 2301 while (pc_ != kEndSimulatingPC) { | 2297 while (pc_ != kEndSimulatingPC) { |
| 2298 Instr* instr = Instr::At(pc_); |
| 2302 icount_++; | 2299 icount_++; |
| 2303 Instr* instr = Instr::At(pc_); | 2300 if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) { |
| 2304 if (static_cast<int>(icount_) == FLAG_stop_sim_at) { | |
| 2305 SimulatorDebugger dbg(this); | 2301 SimulatorDebugger dbg(this); |
| 2306 dbg.Stop(instr, "Instruction count reached"); | 2302 dbg.Stop(instr, "Instruction count reached"); |
| 2307 } else if (reinterpret_cast<int>(instr) == FLAG_stop_sim_at) { | 2303 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) { |
| 2308 SimulatorDebugger dbg(this); | 2304 SimulatorDebugger dbg(this); |
| 2309 dbg.Stop(instr, "Instruction address reached"); | 2305 dbg.Stop(instr, "Instruction address reached"); |
| 2306 } else if (IsIllegalAddress(pc_)) { |
| 2307 HandleIllegalAccess(pc_, instr); |
| 2310 } else { | 2308 } else { |
| 2311 if (IsIllegalAddress(pc_)) { | 2309 InstructionDecode(instr); |
| 2312 HandleIllegalAccess(pc_, instr); | |
| 2313 } else { | |
| 2314 InstructionDecode(instr); | |
| 2315 } | |
| 2316 } | 2310 } |
| 2317 } | 2311 } |
| 2318 } | 2312 } |
| 2319 } | 2313 } |
| 2320 | 2314 |
| 2321 | 2315 |
| 2322 int64_t Simulator::Call(int32_t entry, | 2316 int64_t Simulator::Call(int32_t entry, |
| 2323 int32_t parameter0, | 2317 int32_t parameter0, |
| 2324 int32_t parameter1, | 2318 int32_t parameter1, |
| 2325 int32_t parameter2, | 2319 int32_t parameter2, |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2480 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 2474 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 2481 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 2475 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 2482 buf->Longjmp(); | 2476 buf->Longjmp(); |
| 2483 } | 2477 } |
| 2484 | 2478 |
| 2485 } // namespace dart | 2479 } // namespace dart |
| 2486 | 2480 |
| 2487 #endif // !defined(HOST_ARCH_MIPS) | 2481 #endif // !defined(HOST_ARCH_MIPS) |
| 2488 | 2482 |
| 2489 #endif // defined TARGET_ARCH_MIPS | 2483 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |