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

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

Issue 898093003: Make instruction counter in simulators 64-bit (issue 22302). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months 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> // NOLINT 5 #include <setjmp.h> // NOLINT
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/os_thread.h" 23 #include "vm/os_thread.h"
24 24
25 namespace dart { 25 namespace dart {
26 26
27 DEFINE_FLAG(int, trace_sim_after, -1, 27 DEFINE_FLAG(uint64_t, trace_sim_after, ULLONG_MAX,
28 "Trace simulator execution after instruction count reached."); 28 "Trace simulator execution after instruction count reached.");
29 DEFINE_FLAG(int, stop_sim_at, -1, 29 DEFINE_FLAG(uint64_t, stop_sim_at, ULLONG_MAX,
30 "Instruction address or instruction count to stop simulator at."); 30 "Instruction address or instruction count to stop simulator at.");
31 31
32 32
33 // This macro provides a platform independent use of sscanf. The reason for 33 // This macro provides a platform independent use of sscanf. The reason for
34 // SScanF not being implemented in a platform independent way through 34 // SScanF not being implemented in a platform independent way through
35 // OS in the same way as SNPrint is that the Windows C Run-Time 35 // OS in the same way as SNPrint is that the Windows C Run-Time
36 // Library does not provide vsscanf. 36 // Library does not provide vsscanf.
37 #define SScanF sscanf // NOLINT 37 #define SScanF sscanf // NOLINT
38 38
39 39
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 if (desc[0] == '*') { 193 if (desc[0] == '*') {
194 uint32_t addr; 194 uint32_t addr;
195 if (GetValue(desc + 1, &addr)) { 195 if (GetValue(desc + 1, &addr)) {
196 if (Simulator::IsIllegalAddress(addr)) { 196 if (Simulator::IsIllegalAddress(addr)) {
197 return false; 197 return false;
198 } 198 }
199 *value = *(reinterpret_cast<uint32_t*>(addr)); 199 *value = *(reinterpret_cast<uint32_t*>(addr));
200 return true; 200 return true;
201 } 201 }
202 } 202 }
203 if (strcmp("icount", desc) == 0) {
204 *value = sim_->get_icount();
205 return true;
206 }
207 bool retval = SScanF(desc, "0x%x", value) == 1; 203 bool retval = SScanF(desc, "0x%x", value) == 1;
208 if (!retval) { 204 if (!retval) {
209 retval = SScanF(desc, "%x", value) == 1; 205 retval = SScanF(desc, "%x", value) == 1;
210 } 206 }
211 return retval; 207 return retval;
212 } 208 }
213 209
214 210
215 bool SimulatorDebugger::GetFValue(char* desc, float* value) { 211 bool SimulatorDebugger::GetFValue(char* desc, float* value) {
216 SRegister sreg = LookupSRegisterByName(desc); 212 SRegister sreg = LookupSRegisterByName(desc);
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 451 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
456 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 452 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
457 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 453 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
458 // Execute the one instruction we broke at with breakpoints disabled. 454 // Execute the one instruction we broke at with breakpoints disabled.
459 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 455 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
460 // Leave the debugger shell. 456 // Leave the debugger shell.
461 done = true; 457 done = true;
462 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 458 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
463 if (args == 2) { 459 if (args == 2) {
464 uint32_t value; 460 uint32_t value;
465 if (GetValue(arg1, &value)) { 461 if (strcmp(arg1, "icount") == 0) {
462 const uint64_t icount = sim_->get_icount();
463 OS::Print("icount: %"Pu64" 0x%"Px64"\n", icount, icount);
464 } else if (GetValue(arg1, &value)) {
466 OS::Print("%s: %u 0x%x\n", arg1, value, value); 465 OS::Print("%s: %u 0x%x\n", arg1, value, value);
467 } else { 466 } else {
468 OS::Print("%s unrecognized\n", arg1); 467 OS::Print("%s unrecognized\n", arg1);
469 } 468 }
470 } else { 469 } else {
471 OS::Print("print <reg or value or *addr>\n"); 470 OS::Print("print <reg or icount or value or *addr>\n");
472 } 471 }
473 } else if ((strcmp(cmd, "ps") == 0) || 472 } else if ((strcmp(cmd, "ps") == 0) ||
474 (strcmp(cmd, "printsingle") == 0)) { 473 (strcmp(cmd, "printsingle") == 0)) {
475 if (args == 2) { 474 if (args == 2) {
476 float fvalue; 475 float fvalue;
477 if (GetFValue(arg1, &fvalue)) { 476 if (GetFValue(arg1, &fvalue)) {
478 uint32_t value = bit_cast<uint32_t, float>(fvalue); 477 uint32_t value = bit_cast<uint32_t, float>(fvalue);
479 OS::Print("%s: 0%u 0x%x %.8g\n", arg1, value, value, fvalue); 478 OS::Print("%s: 0%u 0x%x %.8g\n", arg1, value, value, fvalue);
480 } else { 479 } else {
481 OS::Print("%s unrecognized\n", arg1); 480 OS::Print("%s unrecognized\n", arg1);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 OS::Print("V flag: %d\n", sim_->fp_v_flag_); 587 OS::Print("V flag: %d\n", sim_->fp_v_flag_);
589 } else if (strcmp(cmd, "unstop") == 0) { 588 } else if (strcmp(cmd, "unstop") == 0) {
590 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 589 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
591 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 590 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
592 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) { 591 if (stop_instr->IsSvc() || stop_instr->IsBkpt()) {
593 stop_instr->SetInstructionBits(Instr::kNopInstruction); 592 stop_instr->SetInstructionBits(Instr::kNopInstruction);
594 } else { 593 } else {
595 OS::Print("Not at debugger stop.\n"); 594 OS::Print("Not at debugger stop.\n");
596 } 595 }
597 } else if (strcmp(cmd, "trace") == 0) { 596 } else if (strcmp(cmd, "trace") == 0) {
598 if (FLAG_trace_sim_after == -1) { 597 if (FLAG_trace_sim_after == ULLONG_MAX) {
599 FLAG_trace_sim_after = sim_->get_icount(); 598 FLAG_trace_sim_after = sim_->get_icount();
600 OS::Print("execution tracing on\n"); 599 OS::Print("execution tracing on\n");
601 } else { 600 } else {
602 FLAG_trace_sim_after = -1; 601 FLAG_trace_sim_after = ULLONG_MAX;
603 OS::Print("execution tracing off\n"); 602 OS::Print("execution tracing off\n");
604 } 603 }
605 } else if (strcmp(cmd, "bt") == 0) { 604 } else if (strcmp(cmd, "bt") == 0) {
606 PrintBacktrace(); 605 PrintBacktrace();
607 } else { 606 } else {
608 OS::Print("Unknown command: %s\n", cmd); 607 OS::Print("Unknown command: %s\n", cmd);
609 } 608 }
610 } 609 }
611 delete[] line; 610 delete[] line;
612 } 611 }
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 // validity. 1178 // validity.
1180 uword Simulator::StackTop() const { 1179 uword Simulator::StackTop() const {
1181 // To be safe in potential stack underflows we leave some buffer above and 1180 // To be safe in potential stack underflows we leave some buffer above and
1182 // set the stack top. 1181 // set the stack top.
1183 return reinterpret_cast<uword>(stack_) + 1182 return reinterpret_cast<uword>(stack_) +
1184 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer); 1183 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
1185 } 1184 }
1186 1185
1187 1186
1188 bool Simulator::IsTracingExecution() const { 1187 bool Simulator::IsTracingExecution() const {
1189 // Integer flag values are signed, so we must cast to unsigned. 1188 return icount_ > FLAG_trace_sim_after;
1190 // The default of -1 hence becomes the maximum unsigned value.
1191 return (static_cast<uintptr_t>(icount_) >
1192 static_cast<uintptr_t>(FLAG_trace_sim_after));
1193 } 1189 }
1194 1190
1195 1191
1196 // Unsupported instructions use Format to print an error and stop execution. 1192 // Unsupported instructions use Format to print an error and stop execution.
1197 void Simulator::Format(Instr* instr, const char* format) { 1193 void Simulator::Format(Instr* instr, const char* format) {
1198 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n", 1194 OS::Print("Simulator found unsupported instruction:\n 0x%p: %s\n",
1199 instr, 1195 instr,
1200 format); 1196 format);
1201 UNIMPLEMENTED(); 1197 UNIMPLEMENTED();
1202 } 1198 }
(...skipping 2381 matching lines...) Expand 10 before | Expand all | Expand 10 after
3584 UnimplementedInstruction(instr); 3580 UnimplementedInstruction(instr);
3585 } 3581 }
3586 } 3582 }
3587 } 3583 }
3588 3584
3589 3585
3590 // Executes the current instruction. 3586 // Executes the current instruction.
3591 void Simulator::InstructionDecode(Instr* instr) { 3587 void Simulator::InstructionDecode(Instr* instr) {
3592 pc_modified_ = false; 3588 pc_modified_ = false;
3593 if (IsTracingExecution()) { 3589 if (IsTracingExecution()) {
3594 OS::Print("%" Pd " ", icount_); 3590 OS::Print("%"Pu64, icount_);
3595 const uword start = reinterpret_cast<uword>(instr); 3591 const uword start = reinterpret_cast<uword>(instr);
3596 const uword end = start + Instr::kInstrSize; 3592 const uword end = start + Instr::kInstrSize;
3597 Disassembler::Disassemble(start, end); 3593 Disassembler::Disassemble(start, end);
3598 } 3594 }
3599 if (instr->ConditionField() == kSpecialCondition) { 3595 if (instr->ConditionField() == kSpecialCondition) {
3600 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) { 3596 if (instr->InstructionBits() == static_cast<int32_t>(0xf57ff01f)) {
3601 // Format(instr, "clrex"); 3597 // Format(instr, "clrex");
3602 ClearExclusive(); 3598 ClearExclusive();
3603 } else { 3599 } else {
3604 if (instr->IsSIMDDataProcessing()) { 3600 if (instr->IsSIMDDataProcessing()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3649 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize); 3645 set_register(PC, reinterpret_cast<int32_t>(instr) + Instr::kInstrSize);
3650 } 3646 }
3651 } 3647 }
3652 3648
3653 3649
3654 void Simulator::Execute() { 3650 void Simulator::Execute() {
3655 // Get the PC to simulate. Cannot use the accessor here as we need the 3651 // Get the PC to simulate. Cannot use the accessor here as we need the
3656 // raw PC value and not the one used as input to arithmetic instructions. 3652 // raw PC value and not the one used as input to arithmetic instructions.
3657 uword program_counter = get_pc(); 3653 uword program_counter = get_pc();
3658 3654
3659 if (FLAG_stop_sim_at == 0) { 3655 if (FLAG_stop_sim_at == ULLONG_MAX) {
3660 // Fast version of the dispatch loop without checking whether the simulator 3656 // Fast version of the dispatch loop without checking whether the simulator
3661 // should be stopping at a particular executed instruction. 3657 // should be stopping at a particular executed instruction.
3662 while (program_counter != kEndSimulatingPC) { 3658 while (program_counter != kEndSimulatingPC) {
3663 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3659 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3664 icount_++; 3660 icount_++;
3665 if (IsIllegalAddress(program_counter)) { 3661 if (IsIllegalAddress(program_counter)) {
3666 HandleIllegalAccess(program_counter, instr); 3662 HandleIllegalAccess(program_counter, instr);
3667 } else { 3663 } else {
3668 InstructionDecode(instr); 3664 InstructionDecode(instr);
3669 } 3665 }
3670 program_counter = get_pc(); 3666 program_counter = get_pc();
3671 } 3667 }
3672 } else { 3668 } else {
3673 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 3669 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
3674 // we reach the particular instruction count or address. 3670 // we reach the particular instruction count or address.
3675 while (program_counter != kEndSimulatingPC) { 3671 while (program_counter != kEndSimulatingPC) {
3676 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3672 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3677 icount_++; 3673 icount_++;
3678 if (icount_ == FLAG_stop_sim_at) { 3674 if (icount_ == FLAG_stop_sim_at) {
3679 SimulatorDebugger dbg(this); 3675 SimulatorDebugger dbg(this);
3680 dbg.Stop(instr, "Instruction count reached"); 3676 dbg.Stop(instr, "Instruction count reached");
3681 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) { 3677 } else if (reinterpret_cast<uint64_t>(instr) == FLAG_stop_sim_at) {
3682 SimulatorDebugger dbg(this); 3678 SimulatorDebugger dbg(this);
3683 dbg.Stop(instr, "Instruction address reached"); 3679 dbg.Stop(instr, "Instruction address reached");
3684 } else if (IsIllegalAddress(program_counter)) { 3680 } else if (IsIllegalAddress(program_counter)) {
3685 HandleIllegalAccess(program_counter, instr); 3681 HandleIllegalAccess(program_counter, instr);
3686 } else { 3682 } else {
3687 InstructionDecode(instr); 3683 InstructionDecode(instr);
3688 } 3684 }
3689 program_counter = get_pc(); 3685 program_counter = get_pc();
3690 } 3686 }
3691 } 3687 }
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
3882 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); 3878 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
3883 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); 3879 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
3884 buf->Longjmp(); 3880 buf->Longjmp();
3885 } 3881 }
3886 3882
3887 } // namespace dart 3883 } // namespace dart
3888 3884
3889 #endif // !defined(HOST_ARCH_ARM) 3885 #endif // !defined(HOST_ARCH_ARM)
3890 3886
3891 #endif // defined TARGET_ARCH_ARM 3887 #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