Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1328)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 789903002: Complete and clean up breakpoint support in all 3 debuggers embedded in MIPS, (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/simulator_arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM) 9 #if defined(TARGET_ARCH_ARM)
10 10
11 // Only build the simulator if not compiling for real ARM hardware. 11 // Only build the simulator if not compiling for real ARM hardware.
12 #if !defined(HOST_ARCH_ARM) 12 #if !defined(HOST_ARCH_ARM)
13 13
14 #include "vm/simulator.h" 14 #include "vm/simulator.h"
15 15
16 #include "vm/assembler.h" 16 #include "vm/assembler.h"
17 #include "vm/constants_arm.h" 17 #include "vm/constants_arm.h"
18 #include "vm/cpu.h" 18 #include "vm/cpu.h"
19 #include "vm/disassembler.h" 19 #include "vm/disassembler.h"
20 #include "vm/lockers.h" 20 #include "vm/lockers.h"
21 #include "vm/native_arguments.h" 21 #include "vm/native_arguments.h"
22 #include "vm/stack_frame.h" 22 #include "vm/stack_frame.h"
23 #include "vm/thread.h" 23 #include "vm/thread.h"
24 24
25 namespace dart { 25 namespace dart {
26 26
27 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution."); 27 DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution.");
28 DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); 28 DEFINE_FLAG(int, stop_sim_at, 0,
29 "Instruction address or instruction count to stop simulator at.");
29 30
30 31
31 // This macro provides a platform independent use of sscanf. The reason for 32 // This macro provides a platform independent use of sscanf. The reason for
32 // SScanF not being implemented in a platform independent way through 33 // SScanF not being implemented in a platform independent way through
33 // OS in the same way as SNPrint is that the Windows C Run-Time 34 // OS in the same way as SNPrint is that the Windows C Run-Time
34 // Library does not provide vsscanf. 35 // Library does not provide vsscanf.
35 #define SScanF sscanf // NOLINT 36 #define SScanF sscanf // NOLINT
36 37
37 38
38 // Unimplemented counter class for debugging and measurement purposes.
39 class StatsCounter {
40 public:
41 explicit StatsCounter(const char* name) {
42 // UNIMPLEMENTED();
43 }
44
45 void Increment() {
46 // UNIMPLEMENTED();
47 }
48 };
49
50
51 // SimulatorSetjmpBuffer are linked together, and the last created one 39 // SimulatorSetjmpBuffer are linked together, and the last created one
52 // is referenced by the Simulator. When an exception is thrown, the exception 40 // is referenced by the Simulator. When an exception is thrown, the exception
53 // runtime looks at where to jump and finds the corresponding 41 // runtime looks at where to jump and finds the corresponding
54 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler. 42 // SimulatorSetjmpBuffer based on the stack pointer of the exception handler.
55 // The runtime then does a Longjmp on that buffer to return to the simulator. 43 // The runtime then does a Longjmp on that buffer to return to the simulator.
56 class SimulatorSetjmpBuffer { 44 class SimulatorSetjmpBuffer {
57 public: 45 public:
58 int Setjmp() { return setjmp(buffer_); } 46 int Setjmp() { return setjmp(buffer_); }
59 void Longjmp() { 47 void Longjmp() {
60 // "This" is now the last setjmp buffer. 48 // "This" is now the last setjmp buffer.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 81
94 // The SimulatorDebugger class is used by the simulator while debugging 82 // The SimulatorDebugger class is used by the simulator while debugging
95 // simulated ARM code. 83 // simulated ARM code.
96 class SimulatorDebugger { 84 class SimulatorDebugger {
97 public: 85 public:
98 explicit SimulatorDebugger(Simulator* sim); 86 explicit SimulatorDebugger(Simulator* sim);
99 ~SimulatorDebugger(); 87 ~SimulatorDebugger();
100 88
101 void Stop(Instr* instr, const char* message); 89 void Stop(Instr* instr, const char* message);
102 void Debug(); 90 void Debug();
103
104 char* ReadLine(const char* prompt); 91 char* ReadLine(const char* prompt);
105 92
106 private: 93 private:
107 static const int32_t kSimulatorBreakpointInstr = // svc #kBreakpointSvcCode
108 ((AL << kConditionShift) | (0xf << 24) | kBreakpointSvcCode);
109 static const int32_t kNopInstr = // nop
110 ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12));
111
112 Simulator* sim_; 94 Simulator* sim_;
113 95
114 bool GetValue(char* desc, uint32_t* value); 96 bool GetValue(char* desc, uint32_t* value);
115 bool GetFValue(char* desc, float* value); 97 bool GetFValue(char* desc, float* value);
116 bool GetDValue(char* desc, double* value); 98 bool GetDValue(char* desc, double* value);
117 99
118 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc); 100 static intptr_t GetApproximateTokenIndex(const Code& code, uword pc);
119 101
120 static void PrintDartFrame(uword pc, uword fp, uword sp, 102 static void PrintDartFrame(uword pc, uword fp, uword sp,
121 const Function& function, 103 const Function& function,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 if (desc[0] == '*') { 192 if (desc[0] == '*') {
211 uint32_t addr; 193 uint32_t addr;
212 if (GetValue(desc + 1, &addr)) { 194 if (GetValue(desc + 1, &addr)) {
213 if (Simulator::IsIllegalAddress(addr)) { 195 if (Simulator::IsIllegalAddress(addr)) {
214 return false; 196 return false;
215 } 197 }
216 *value = *(reinterpret_cast<uint32_t*>(addr)); 198 *value = *(reinterpret_cast<uint32_t*>(addr));
217 return true; 199 return true;
218 } 200 }
219 } 201 }
202 if (strcmp("icount", desc) == 0) {
203 *value = sim_->get_icount();
204 return true;
205 }
220 bool retval = SScanF(desc, "0x%x", value) == 1; 206 bool retval = SScanF(desc, "0x%x", value) == 1;
221 if (!retval) { 207 if (!retval) {
222 retval = SScanF(desc, "%x", value) == 1; 208 retval = SScanF(desc, "%x", value) == 1;
223 } 209 }
224 return retval; 210 return retval;
225 } 211 }
226 212
227 213
228 bool SimulatorDebugger::GetFValue(char* desc, float* value) { 214 bool SimulatorDebugger::GetFValue(char* desc, float* value) {
229 SRegister sreg = LookupSRegisterByName(desc); 215 SRegister sreg = LookupSRegisterByName(desc);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 371
386 void SimulatorDebugger::UndoBreakpoints() { 372 void SimulatorDebugger::UndoBreakpoints() {
387 if (sim_->break_pc_ != NULL) { 373 if (sim_->break_pc_ != NULL) {
388 sim_->break_pc_->SetInstructionBits(sim_->break_instr_); 374 sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
389 } 375 }
390 } 376 }
391 377
392 378
393 void SimulatorDebugger::RedoBreakpoints() { 379 void SimulatorDebugger::RedoBreakpoints() {
394 if (sim_->break_pc_ != NULL) { 380 if (sim_->break_pc_ != NULL) {
395 sim_->break_pc_->SetInstructionBits(kSimulatorBreakpointInstr); 381 sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction);
396 } 382 }
397 } 383 }
398 384
399 385
400 void SimulatorDebugger::Debug() { 386 void SimulatorDebugger::Debug() {
401 intptr_t last_pc = -1; 387 intptr_t last_pc = -1;
402 bool done = false; 388 bool done = false;
403 389
404 #define COMMAND_SIZE 63 390 #define COMMAND_SIZE 63
405 #define ARG_SIZE 255 391 #define ARG_SIZE 255
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 "disasm -- disassemble instrs at current pc location\n" 431 "disasm -- disassemble instrs at current pc location\n"
446 " other variants are:\n" 432 " other variants are:\n"
447 " disasm <address>\n" 433 " disasm <address>\n"
448 " disasm <address> <number_of_instructions>\n" 434 " disasm <address> <number_of_instructions>\n"
449 " by default 10 instrs are disassembled\n" 435 " by default 10 instrs are disassembled\n"
450 "del -- delete breakpoints\n" 436 "del -- delete breakpoints\n"
451 "flags -- print flag values\n" 437 "flags -- print flag values\n"
452 "gdb -- transfer control to gdb\n" 438 "gdb -- transfer control to gdb\n"
453 "h/help -- print this help string\n" 439 "h/help -- print this help string\n"
454 "break <address> -- set break point at specified address\n" 440 "break <address> -- set break point at specified address\n"
455 "p/print <reg or value or *addr> -- print integer value\n" 441 "p/print <reg or icount or value or *addr> -- print integer\n"
456 "ps/printsingle <sreg or *addr> -- print float value\n" 442 "ps/printsingle <sreg or *addr> -- print float value\n"
457 "pd/printdouble <dreg or *addr> -- print double value\n" 443 "pd/printdouble <dreg or *addr> -- print double value\n"
458 "po/printobject <*reg or *addr> -- print object\n" 444 "po/printobject <*reg or *addr> -- print object\n"
459 "si/stepi -- single step an instruction\n" 445 "si/stepi -- single step an instruction\n"
460 "trace -- toggle execution tracing mode\n" 446 "trace -- toggle execution tracing mode\n"
461 "bt -- print backtrace\n" 447 "bt -- print backtrace\n"
462 "unstop -- if current pc is a stop instr make it a nop\n" 448 "unstop -- if current pc is a stop instr make it a nop\n"
463 "q/quit -- Quit the debugger and exit the program\n"); 449 "q/quit -- Quit the debugger and exit the program\n");
464 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) { 450 } else if ((strcmp(cmd, "quit") == 0) || (strcmp(cmd, "q") == 0)) {
465 OS::Print("Quitting\n"); 451 OS::Print("Quitting\n");
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 OS::Print("printobject <*reg or *addr>\n"); 519 OS::Print("printobject <*reg or *addr>\n");
534 } 520 }
535 } else if (strcmp(cmd, "disasm") == 0) { 521 } else if (strcmp(cmd, "disasm") == 0) {
536 uint32_t start = 0; 522 uint32_t start = 0;
537 uint32_t end = 0; 523 uint32_t end = 0;
538 if (args == 1) { 524 if (args == 1) {
539 start = sim_->get_pc(); 525 start = sim_->get_pc();
540 end = start + (10 * Instr::kInstrSize); 526 end = start + (10 * Instr::kInstrSize);
541 } else if (args == 2) { 527 } else if (args == 2) {
542 if (GetValue(arg1, &start)) { 528 if (GetValue(arg1, &start)) {
543 // no length parameter passed, assume 10 instructions 529 // No length parameter passed, assume 10 instructions.
530 if (Simulator::IsIllegalAddress(start)) {
531 // If start isn't a valid address, warn and use PC instead.
532 OS::Print("First argument yields invalid address: 0x%x\n", start);
533 OS::Print("Using PC instead\n");
534 start = sim_->get_pc();
535 }
544 end = start + (10 * Instr::kInstrSize); 536 end = start + (10 * Instr::kInstrSize);
545 } 537 }
546 } else { 538 } else {
547 uint32_t length; 539 uint32_t length;
548 if (GetValue(arg1, &start) && GetValue(arg2, &length)) { 540 if (GetValue(arg1, &start) && GetValue(arg2, &length)) {
541 if (Simulator::IsIllegalAddress(start)) {
542 // If start isn't a valid address, warn and use PC instead.
543 OS::Print("First argument yields invalid address: 0x%x\n", start);
544 OS::Print("Using PC instead\n");
545 start = sim_->get_pc();
546 }
549 end = start + (length * Instr::kInstrSize); 547 end = start + (length * Instr::kInstrSize);
550 } 548 }
551 } 549 }
552 550 if ((start > 0) && (end > start)) {
553 Disassembler::Disassemble(start, end); 551 Disassembler::Disassemble(start, end);
552 } else {
553 OS::Print("disasm [<address> [<number_of_instructions>]]\n");
554 }
554 } else if (strcmp(cmd, "gdb") == 0) { 555 } else if (strcmp(cmd, "gdb") == 0) {
555 OS::Print("relinquishing control to gdb\n"); 556 OS::Print("relinquishing control to gdb\n");
556 OS::DebugBreak(); 557 OS::DebugBreak();
557 OS::Print("regaining control from gdb\n"); 558 OS::Print("regaining control from gdb\n");
558 } else if (strcmp(cmd, "break") == 0) { 559 } else if (strcmp(cmd, "break") == 0) {
559 if (args == 2) { 560 if (args == 2) {
560 uint32_t addr; 561 uint32_t addr;
561 if (GetValue(arg1, &addr)) { 562 if (GetValue(arg1, &addr)) {
562 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) { 563 if (!SetBreakpoint(reinterpret_cast<Instr*>(addr))) {
563 OS::Print("setting breakpoint failed\n"); 564 OS::Print("setting breakpoint failed\n");
(...skipping 16 matching lines...) Expand all
580 OS::Print("V flag: %d\n", sim_->v_flag_); 581 OS::Print("V flag: %d\n", sim_->v_flag_);
581 OS::Print("FPSCR: "); 582 OS::Print("FPSCR: ");
582 OS::Print("N flag: %d; ", sim_->fp_n_flag_); 583 OS::Print("N flag: %d; ", sim_->fp_n_flag_);
583 OS::Print("Z flag: %d; ", sim_->fp_z_flag_); 584 OS::Print("Z flag: %d; ", sim_->fp_z_flag_);
584 OS::Print("C flag: %d; ", sim_->fp_c_flag_); 585 OS::Print("C flag: %d; ", sim_->fp_c_flag_);
585 OS::Print("V flag: %d\n", sim_->fp_v_flag_); 586 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
586 } else if (strcmp(cmd, "unstop") == 0) { 587 } else if (strcmp(cmd, "unstop") == 0) {
587 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 588 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
588 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 589 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
589 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) { 590 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
590 stop_instr->SetInstructionBits(kNopInstr); 591 stop_instr->SetInstructionBits(Instr::kNopInstruction);
591 } else { 592 } else {
592 OS::Print("Not at debugger stop.\n"); 593 OS::Print("Not at debugger stop.\n");
593 } 594 }
594 } else if (strcmp(cmd, "trace") == 0) { 595 } else if (strcmp(cmd, "trace") == 0) {
595 FLAG_trace_sim = !FLAG_trace_sim; 596 FLAG_trace_sim = !FLAG_trace_sim;
596 OS::Print("execution tracing %s\n", FLAG_trace_sim ? "on" : "off"); 597 OS::Print("execution tracing %s\n", FLAG_trace_sim ? "on" : "off");
597 } else if (strcmp(cmd, "bt") == 0) { 598 } else if (strcmp(cmd, "bt") == 0) {
598 PrintBacktrace(); 599 PrintBacktrace();
599 } else { 600 } else {
600 OS::Print("Unknown command: %s\n", cmd); 601 OS::Print("Unknown command: %s\n", cmd);
(...skipping 10 matching lines...) Expand all
611 #undef ARG_SIZE 612 #undef ARG_SIZE
612 613
613 #undef STR 614 #undef STR
614 #undef XSTR 615 #undef XSTR
615 } 616 }
616 617
617 618
618 char* SimulatorDebugger::ReadLine(const char* prompt) { 619 char* SimulatorDebugger::ReadLine(const char* prompt) {
619 char* result = NULL; 620 char* result = NULL;
620 char line_buf[256]; 621 char line_buf[256];
621 int offset = 0; 622 intptr_t offset = 0;
622 bool keep_going = true; 623 bool keep_going = true;
623 OS::Print("%s", prompt); 624 OS::Print("%s", prompt);
624 while (keep_going) { 625 while (keep_going) {
625 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) { 626 if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
626 // fgets got an error. Just give up. 627 // fgets got an error. Just give up.
627 if (result != NULL) { 628 if (result != NULL) {
628 delete[] result; 629 delete[] result;
629 } 630 }
630 return NULL; 631 return NULL;
631 } 632 }
632 int len = strlen(line_buf); 633 intptr_t len = strlen(line_buf);
633 if (len > 1 && 634 if (len > 1 &&
634 line_buf[len - 2] == '\\' && 635 line_buf[len - 2] == '\\' &&
635 line_buf[len - 1] == '\n') { 636 line_buf[len - 1] == '\n') {
636 // When we read a line that ends with a "\" we remove the escape and 637 // When we read a line that ends with a "\" we remove the escape and
637 // append the remainder. 638 // append the remainder.
638 line_buf[len - 2] = '\n'; 639 line_buf[len - 2] = '\n';
639 line_buf[len - 1] = 0; 640 line_buf[len - 1] = 0;
640 len -= 1; 641 len -= 1;
641 } else if ((len > 0) && (line_buf[len - 1] == '\n')) { 642 } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
642 // Since we read a new line we are done reading the line. This 643 // Since we read a new line we are done reading the line. This
643 // will exit the loop after copying this buffer into the result. 644 // will exit the loop after copying this buffer into the result.
644 keep_going = false; 645 keep_going = false;
645 } 646 }
646 if (result == NULL) { 647 if (result == NULL) {
647 // Allocate the initial result and make room for the terminating '\0' 648 // Allocate the initial result and make room for the terminating '\0'
648 result = new char[len + 1]; 649 result = new char[len + 1];
649 if (result == NULL) { 650 if (result == NULL) {
650 // OOM, so cannot readline anymore. 651 // OOM, so cannot readline anymore.
651 return NULL; 652 return NULL;
652 } 653 }
653 } else { 654 } else {
654 // Allocate a new result with enough room for the new addition. 655 // Allocate a new result with enough room for the new addition.
655 int new_len = offset + len + 1; 656 intptr_t new_len = offset + len + 1;
656 char* new_result = new char[new_len]; 657 char* new_result = new char[new_len];
657 if (new_result == NULL) { 658 if (new_result == NULL) {
658 // OOM, free the buffer allocated so far and return NULL. 659 // OOM, free the buffer allocated so far and return NULL.
659 delete[] result; 660 delete[] result;
660 return NULL; 661 return NULL;
661 } else { 662 } else {
662 // Copy the existing input into the new array and set the new 663 // Copy the existing input into the new array and set the new
663 // array as the result. 664 // array as the result.
664 memmove(new_result, result, offset); 665 memmove(new_result, result, offset);
665 delete[] result; 666 delete[] result;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 Redirection* current; 791 Redirection* current;
791 for (current = list_; current != NULL; current = current->next_) { 792 for (current = list_; current != NULL; current = current->next_) {
792 if (current->address_of_svc_instruction() == address_of_svc) { 793 if (current->address_of_svc_instruction() == address_of_svc) {
793 return current->external_function_; 794 return current->external_function_;
794 } 795 }
795 } 796 }
796 return 0; 797 return 0;
797 } 798 }
798 799
799 private: 800 private:
800 static const int32_t kRedirectSvcInstruction =
801 ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode);
802 Redirection(uword external_function, 801 Redirection(uword external_function,
803 Simulator::CallKind call_kind, 802 Simulator::CallKind call_kind,
804 int argument_count) 803 int argument_count)
805 : external_function_(external_function), 804 : external_function_(external_function),
806 call_kind_(call_kind), 805 call_kind_(call_kind),
807 argument_count_(argument_count), 806 argument_count_(argument_count),
808 svc_instruction_(kRedirectSvcInstruction), 807 svc_instruction_(Instr::kSimulatorRedirectInstruction),
809 next_(list_) { 808 next_(list_) {
810 list_ = this; 809 list_ = this;
811 } 810 }
812 811
813 uword external_function_; 812 uword external_function_;
814 Simulator::CallKind call_kind_; 813 Simulator::CallKind call_kind_;
815 int argument_count_; 814 int argument_count_;
816 uint32_t svc_instruction_; 815 uint32_t svc_instruction_;
817 Redirection* next_; 816 Redirection* next_;
818 static Redirection* list_; 817 static Redirection* list_;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 void Simulator::UnimplementedInstruction(Instr* instr) { 994 void Simulator::UnimplementedInstruction(Instr* instr) {
996 char buffer[64]; 995 char buffer[64];
997 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr); 996 snprintf(buffer, sizeof(buffer), "Unimplemented instruction: pc=%p\n", instr);
998 SimulatorDebugger dbg(this); 997 SimulatorDebugger dbg(this);
999 dbg.Stop(instr, buffer); 998 dbg.Stop(instr, buffer);
1000 FATAL("Cannot continue execution after unimplemented instruction."); 999 FATAL("Cannot continue execution after unimplemented instruction.");
1001 } 1000 }
1002 1001
1003 1002
1004 intptr_t Simulator::ReadW(uword addr, Instr* instr) { 1003 intptr_t Simulator::ReadW(uword addr, Instr* instr) {
1005 static StatsCounter counter_read_w("Simulated word reads");
1006 counter_read_w.Increment();
1007 if ((addr & 3) == 0) { 1004 if ((addr & 3) == 0) {
1008 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1005 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1009 return *ptr; 1006 return *ptr;
1010 } 1007 }
1011 UnalignedAccess("read", addr, instr); 1008 UnalignedAccess("read", addr, instr);
1012 return 0; 1009 return 0;
1013 } 1010 }
1014 1011
1015 1012
1016 void Simulator::WriteW(uword addr, intptr_t value, Instr* instr) { 1013 void Simulator::WriteW(uword addr, intptr_t value, Instr* instr) {
1017 static StatsCounter counter_write_w("Simulated word writes");
1018 counter_write_w.Increment();
1019 if ((addr & 3) == 0) { 1014 if ((addr & 3) == 0) {
1020 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1015 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1021 *ptr = value; 1016 *ptr = value;
1022 return; 1017 return;
1023 } 1018 }
1024 UnalignedAccess("write", addr, instr); 1019 UnalignedAccess("write", addr, instr);
1025 } 1020 }
1026 1021
1027 1022
1028 uint16_t Simulator::ReadHU(uword addr, Instr* instr) { 1023 uint16_t Simulator::ReadHU(uword addr, Instr* instr) {
1029 static StatsCounter counter_read_hu("Simulated unsigned halfword reads");
1030 counter_read_hu.Increment();
1031 if ((addr & 1) == 0) { 1024 if ((addr & 1) == 0) {
1032 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1025 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1033 return *ptr; 1026 return *ptr;
1034 } 1027 }
1035 UnalignedAccess("unsigned halfword read", addr, instr); 1028 UnalignedAccess("unsigned halfword read", addr, instr);
1036 return 0; 1029 return 0;
1037 } 1030 }
1038 1031
1039 1032
1040 int16_t Simulator::ReadH(uword addr, Instr* instr) { 1033 int16_t Simulator::ReadH(uword addr, Instr* instr) {
1041 static StatsCounter counter_read_h("Simulated signed halfword reads");
1042 counter_read_h.Increment();
1043 if ((addr & 1) == 0) { 1034 if ((addr & 1) == 0) {
1044 int16_t* ptr = reinterpret_cast<int16_t*>(addr); 1035 int16_t* ptr = reinterpret_cast<int16_t*>(addr);
1045 return *ptr; 1036 return *ptr;
1046 } 1037 }
1047 UnalignedAccess("signed halfword read", addr, instr); 1038 UnalignedAccess("signed halfword read", addr, instr);
1048 return 0; 1039 return 0;
1049 } 1040 }
1050 1041
1051 1042
1052 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { 1043 void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) {
1053 static StatsCounter counter_write_h("Simulated halfword writes");
1054 counter_write_h.Increment();
1055 if ((addr & 1) == 0) { 1044 if ((addr & 1) == 0) {
1056 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); 1045 uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
1057 *ptr = value; 1046 *ptr = value;
1058 return; 1047 return;
1059 } 1048 }
1060 UnalignedAccess("halfword write", addr, instr); 1049 UnalignedAccess("halfword write", addr, instr);
1061 } 1050 }
1062 1051
1063 1052
1064 uint8_t Simulator::ReadBU(uword addr) { 1053 uint8_t Simulator::ReadBU(uword addr) {
1065 static StatsCounter counter_read_bu("Simulated unsigned byte reads");
1066 counter_read_bu.Increment();
1067 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1054 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1068 return *ptr; 1055 return *ptr;
1069 } 1056 }
1070 1057
1071 1058
1072 int8_t Simulator::ReadB(uword addr) { 1059 int8_t Simulator::ReadB(uword addr) {
1073 static StatsCounter counter_read_b("Simulated signed byte reads");
1074 counter_read_b.Increment();
1075 int8_t* ptr = reinterpret_cast<int8_t*>(addr); 1060 int8_t* ptr = reinterpret_cast<int8_t*>(addr);
1076 return *ptr; 1061 return *ptr;
1077 } 1062 }
1078 1063
1079 1064
1080 void Simulator::WriteB(uword addr, uint8_t value) { 1065 void Simulator::WriteB(uword addr, uint8_t value) {
1081 static StatsCounter counter_write_b("Simulated byte writes");
1082 counter_write_b.Increment();
1083 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); 1066 uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
1084 *ptr = value; 1067 *ptr = value;
1085 } 1068 }
1086 1069
1087 1070
1088 // Synchronization primitives support. 1071 // Synchronization primitives support.
1089 void Simulator::SetExclusiveAccess(uword addr) { 1072 void Simulator::SetExclusiveAccess(uword addr) {
1090 Isolate* isolate = Isolate::Current(); 1073 Isolate* isolate = Isolate::Current();
1091 ASSERT(isolate != NULL); 1074 ASSERT(isolate != NULL);
1092 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate); 1075 DEBUG_ASSERT(exclusive_access_lock_->Owner() == isolate);
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 break; 1616 break;
1634 } 1617 }
1635 case kStopMessageSvcCode: { 1618 case kStopMessageSvcCode: {
1636 SimulatorDebugger dbg(this); 1619 SimulatorDebugger dbg(this);
1637 const char* message = *reinterpret_cast<const char**>( 1620 const char* message = *reinterpret_cast<const char**>(
1638 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize); 1621 reinterpret_cast<intptr_t>(instr) - Instr::kInstrSize);
1639 set_pc(get_pc() + Instr::kInstrSize); 1622 set_pc(get_pc() + Instr::kInstrSize);
1640 dbg.Stop(instr, message); 1623 dbg.Stop(instr, message);
1641 break; 1624 break;
1642 } 1625 }
1643 case kWordSpillMarkerSvcCode: {
1644 static StatsCounter counter_spill_w("Simulated word spills");
1645 counter_spill_w.Increment();
1646 break;
1647 }
1648 case kDWordSpillMarkerSvcCode: {
1649 static StatsCounter counter_spill_d("Simulated double word spills");
1650 counter_spill_d.Increment();
1651 break;
1652 }
1653 default: { 1626 default: {
1654 UNREACHABLE(); 1627 UNREACHABLE();
1655 break; 1628 break;
1656 } 1629 }
1657 } 1630 }
1658 } 1631 }
1659 1632
1660 1633
1661 // Handle execution based on instruction types. 1634 // Handle execution based on instruction types.
1662 1635
(...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 } 3620 }
3648 } 3621 }
3649 } 3622 }
3650 if (!pc_modified_) { 3623 if (!pc_modified_) {
3651 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); 3624 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
3652 } 3625 }
3653 } 3626 }
3654 3627
3655 3628
3656 void Simulator::Execute() { 3629 void Simulator::Execute() {
3657 static StatsCounter counter_instructions("Simulated instructions");
3658
3659 // Get the PC to simulate. Cannot use the accessor here as we need the 3630 // Get the PC to simulate. Cannot use the accessor here as we need the
3660 // raw PC value and not the one used as input to arithmetic instructions. 3631 // raw PC value and not the one used as input to arithmetic instructions.
3661 uword program_counter = get_pc(); 3632 uword program_counter = get_pc();
3662 3633
3663 if (FLAG_stop_sim_at == 0) { 3634 if (FLAG_stop_sim_at == 0) {
3664 // Fast version of the dispatch loop without checking whether the simulator 3635 // Fast version of the dispatch loop without checking whether the simulator
3665 // should be stopping at a particular executed instruction. 3636 // should be stopping at a particular executed instruction.
3666 while (program_counter != kEndSimulatingPC) { 3637 while (program_counter != kEndSimulatingPC) {
3667 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3638 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3668 icount_++; 3639 icount_++;
3669 counter_instructions.Increment();
3670 if (IsIllegalAddress(program_counter)) { 3640 if (IsIllegalAddress(program_counter)) {
3671 HandleIllegalAccess(program_counter, instr); 3641 HandleIllegalAccess(program_counter, instr);
3672 } else { 3642 } else {
3673 InstructionDecode(instr); 3643 InstructionDecode(instr);
3674 } 3644 }
3675 program_counter = get_pc(); 3645 program_counter = get_pc();
3676 } 3646 }
3677 } else { 3647 } else {
3678 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 3648 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
3679 // we reach the particular instruction count. 3649 // we reach the particular instruction count or address.
3680 while (program_counter != kEndSimulatingPC) { 3650 while (program_counter != kEndSimulatingPC) {
3681 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3651 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3682 icount_++; 3652 icount_++;
3683 counter_instructions.Increment(); 3653 if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) {
3684 if (icount_ == FLAG_stop_sim_at) {
3685 SimulatorDebugger dbg(this); 3654 SimulatorDebugger dbg(this);
3686 dbg.Stop(instr, "Instruction count reached"); 3655 dbg.Stop(instr, "Instruction count reached");
3656 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) {
3657 SimulatorDebugger dbg(this);
3658 dbg.Stop(instr, "Instruction address reached");
3687 } else if (IsIllegalAddress(program_counter)) { 3659 } else if (IsIllegalAddress(program_counter)) {
3688 HandleIllegalAccess(program_counter, instr); 3660 HandleIllegalAccess(program_counter, instr);
3689 } else { 3661 } else {
3690 InstructionDecode(instr); 3662 InstructionDecode(instr);
3691 } 3663 }
3692 program_counter = get_pc(); 3664 program_counter = get_pc();
3693 } 3665 }
3694 } 3666 }
3695 } 3667 }
3696 3668
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3885 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 3857 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
3886 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3858 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
3887 buf->Longjmp(); 3859 buf->Longjmp();
3888 } 3860 }
3889 3861
3890 } // namespace dart 3862 } // namespace dart
3891 3863
3892 #endif // !defined(HOST_ARCH_ARM) 3864 #endif // !defined(HOST_ARCH_ARM)
3893 3865
3894 #endif // defined TARGET_ARCH_ARM 3866 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm.h ('k') | runtime/vm/simulator_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698