Index: runtime/vm/simulator_arm.cc |
=================================================================== |
--- runtime/vm/simulator_arm.cc (revision 42212) |
+++ runtime/vm/simulator_arm.cc (working copy) |
@@ -25,7 +25,8 @@ |
namespace dart { |
DEFINE_FLAG(bool, trace_sim, false, "Trace simulator execution."); |
-DEFINE_FLAG(int, stop_sim_at, 0, "Address to stop simulator at."); |
+DEFINE_FLAG(int, stop_sim_at, 0, |
+ "Instruction address or instruction count to stop simulator at."); |
// This macro provides a platform independent use of sscanf. The reason for |
@@ -35,19 +36,6 @@ |
#define SScanF sscanf // NOLINT |
-// Unimplemented counter class for debugging and measurement purposes. |
-class StatsCounter { |
- public: |
- explicit StatsCounter(const char* name) { |
- // UNIMPLEMENTED(); |
- } |
- |
- void Increment() { |
- // UNIMPLEMENTED(); |
- } |
-}; |
- |
- |
// SimulatorSetjmpBuffer are linked together, and the last created one |
// is referenced by the Simulator. When an exception is thrown, the exception |
// runtime looks at where to jump and finds the corresponding |
@@ -100,15 +88,9 @@ |
void Stop(Instr* instr, const char* message); |
void Debug(); |
- |
char* ReadLine(const char* prompt); |
private: |
- static const int32_t kSimulatorBreakpointInstr = // svc #kBreakpointSvcCode |
- ((AL << kConditionShift) | (0xf << 24) | kBreakpointSvcCode); |
- static const int32_t kNopInstr = // nop |
- ((AL << kConditionShift) | (0x32 << 20) | (0xf << 12)); |
- |
Simulator* sim_; |
bool GetValue(char* desc, uint32_t* value); |
@@ -217,6 +199,10 @@ |
return true; |
} |
} |
+ if (strcmp("icount", desc) == 0) { |
+ *value = sim_->get_icount(); |
+ return true; |
+ } |
bool retval = SScanF(desc, "0x%x", value) == 1; |
if (!retval) { |
retval = SScanF(desc, "%x", value) == 1; |
@@ -392,7 +378,7 @@ |
void SimulatorDebugger::RedoBreakpoints() { |
if (sim_->break_pc_ != NULL) { |
- sim_->break_pc_->SetInstructionBits(kSimulatorBreakpointInstr); |
+ sim_->break_pc_->SetInstructionBits(Instr::kSimulatorBreakpointInstruction); |
} |
} |
@@ -452,7 +438,7 @@ |
"gdb -- transfer control to gdb\n" |
"h/help -- print this help string\n" |
"break <address> -- set break point at specified address\n" |
- "p/print <reg or value or *addr> -- print integer value\n" |
+ "p/print <reg or icount or value or *addr> -- print integer\n" |
"ps/printsingle <sreg or *addr> -- print float value\n" |
"pd/printdouble <dreg or *addr> -- print double value\n" |
"po/printobject <*reg or *addr> -- print object\n" |
@@ -540,17 +526,32 @@ |
end = start + (10 * Instr::kInstrSize); |
} else if (args == 2) { |
if (GetValue(arg1, &start)) { |
- // no length parameter passed, assume 10 instructions |
+ // No length parameter passed, assume 10 instructions. |
+ if (Simulator::IsIllegalAddress(start)) { |
+ // If start isn't a valid address, warn and use PC instead. |
+ OS::Print("First argument yields invalid address: 0x%x\n", start); |
+ OS::Print("Using PC instead\n"); |
+ start = sim_->get_pc(); |
+ } |
end = start + (10 * Instr::kInstrSize); |
} |
} else { |
uint32_t length; |
if (GetValue(arg1, &start) && GetValue(arg2, &length)) { |
+ if (Simulator::IsIllegalAddress(start)) { |
+ // If start isn't a valid address, warn and use PC instead. |
+ OS::Print("First argument yields invalid address: 0x%x\n", start); |
+ OS::Print("Using PC instead\n"); |
+ start = sim_->get_pc(); |
+ } |
end = start + (length * Instr::kInstrSize); |
} |
} |
- |
- Disassembler::Disassemble(start, end); |
+ if ((start > 0) && (end > start)) { |
+ Disassembler::Disassemble(start, end); |
+ } else { |
+ OS::Print("disasm [<address> [<number_of_instructions>]]\n"); |
+ } |
} else if (strcmp(cmd, "gdb") == 0) { |
OS::Print("relinquishing control to gdb\n"); |
OS::DebugBreak(); |
@@ -587,7 +588,7 @@ |
intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; |
Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); |
if (stop_instr->IsSvc() || stop_instr->IsBkpt()) { |
- stop_instr->SetInstructionBits(kNopInstr); |
+ stop_instr->SetInstructionBits(Instr::kNopInstruction); |
} else { |
OS::Print("Not at debugger stop.\n"); |
} |
@@ -618,7 +619,7 @@ |
char* SimulatorDebugger::ReadLine(const char* prompt) { |
char* result = NULL; |
char line_buf[256]; |
- int offset = 0; |
+ intptr_t offset = 0; |
bool keep_going = true; |
OS::Print("%s", prompt); |
while (keep_going) { |
@@ -629,7 +630,7 @@ |
} |
return NULL; |
} |
- int len = strlen(line_buf); |
+ intptr_t len = strlen(line_buf); |
if (len > 1 && |
line_buf[len - 2] == '\\' && |
line_buf[len - 1] == '\n') { |
@@ -652,7 +653,7 @@ |
} |
} else { |
// Allocate a new result with enough room for the new addition. |
- int new_len = offset + len + 1; |
+ intptr_t new_len = offset + len + 1; |
char* new_result = new char[new_len]; |
if (new_result == NULL) { |
// OOM, free the buffer allocated so far and return NULL. |
@@ -797,8 +798,6 @@ |
} |
private: |
- static const int32_t kRedirectSvcInstruction = |
- ((AL << kConditionShift) | (0xf << 24) | kRedirectionSvcCode); |
Redirection(uword external_function, |
Simulator::CallKind call_kind, |
int argument_count) |
@@ -805,7 +804,7 @@ |
: external_function_(external_function), |
call_kind_(call_kind), |
argument_count_(argument_count), |
- svc_instruction_(kRedirectSvcInstruction), |
+ svc_instruction_(Instr::kSimulatorRedirectInstruction), |
next_(list_) { |
list_ = this; |
} |
@@ -1002,8 +1001,6 @@ |
intptr_t Simulator::ReadW(uword addr, Instr* instr) { |
- static StatsCounter counter_read_w("Simulated word reads"); |
- counter_read_w.Increment(); |
if ((addr & 3) == 0) { |
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
return *ptr; |
@@ -1014,8 +1011,6 @@ |
void Simulator::WriteW(uword addr, intptr_t value, Instr* instr) { |
- static StatsCounter counter_write_w("Simulated word writes"); |
- counter_write_w.Increment(); |
if ((addr & 3) == 0) { |
intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); |
*ptr = value; |
@@ -1026,8 +1021,6 @@ |
uint16_t Simulator::ReadHU(uword addr, Instr* instr) { |
- static StatsCounter counter_read_hu("Simulated unsigned halfword reads"); |
- counter_read_hu.Increment(); |
if ((addr & 1) == 0) { |
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
return *ptr; |
@@ -1038,8 +1031,6 @@ |
int16_t Simulator::ReadH(uword addr, Instr* instr) { |
- static StatsCounter counter_read_h("Simulated signed halfword reads"); |
- counter_read_h.Increment(); |
if ((addr & 1) == 0) { |
int16_t* ptr = reinterpret_cast<int16_t*>(addr); |
return *ptr; |
@@ -1050,8 +1041,6 @@ |
void Simulator::WriteH(uword addr, uint16_t value, Instr* instr) { |
- static StatsCounter counter_write_h("Simulated halfword writes"); |
- counter_write_h.Increment(); |
if ((addr & 1) == 0) { |
uint16_t* ptr = reinterpret_cast<uint16_t*>(addr); |
*ptr = value; |
@@ -1062,8 +1051,6 @@ |
uint8_t Simulator::ReadBU(uword addr) { |
- static StatsCounter counter_read_bu("Simulated unsigned byte reads"); |
- counter_read_bu.Increment(); |
uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
return *ptr; |
} |
@@ -1070,8 +1057,6 @@ |
int8_t Simulator::ReadB(uword addr) { |
- static StatsCounter counter_read_b("Simulated signed byte reads"); |
- counter_read_b.Increment(); |
int8_t* ptr = reinterpret_cast<int8_t*>(addr); |
return *ptr; |
} |
@@ -1078,8 +1063,6 @@ |
void Simulator::WriteB(uword addr, uint8_t value) { |
- static StatsCounter counter_write_b("Simulated byte writes"); |
- counter_write_b.Increment(); |
uint8_t* ptr = reinterpret_cast<uint8_t*>(addr); |
*ptr = value; |
} |
@@ -1640,16 +1623,6 @@ |
dbg.Stop(instr, message); |
break; |
} |
- case kWordSpillMarkerSvcCode: { |
- static StatsCounter counter_spill_w("Simulated word spills"); |
- counter_spill_w.Increment(); |
- break; |
- } |
- case kDWordSpillMarkerSvcCode: { |
- static StatsCounter counter_spill_d("Simulated double word spills"); |
- counter_spill_d.Increment(); |
- break; |
- } |
default: { |
UNREACHABLE(); |
break; |
@@ -3654,8 +3627,6 @@ |
void Simulator::Execute() { |
- static StatsCounter counter_instructions("Simulated instructions"); |
- |
// Get the PC to simulate. Cannot use the accessor here as we need the |
// raw PC value and not the one used as input to arithmetic instructions. |
uword program_counter = get_pc(); |
@@ -3666,7 +3637,6 @@ |
while (program_counter != kEndSimulatingPC) { |
Instr* instr = reinterpret_cast<Instr*>(program_counter); |
icount_++; |
- counter_instructions.Increment(); |
if (IsIllegalAddress(program_counter)) { |
HandleIllegalAccess(program_counter, instr); |
} else { |
@@ -3676,14 +3646,16 @@ |
} |
} else { |
// FLAG_stop_sim_at is at the non-default value. Stop in the debugger when |
- // we reach the particular instruction count. |
+ // we reach the particular instruction count or address. |
while (program_counter != kEndSimulatingPC) { |
Instr* instr = reinterpret_cast<Instr*>(program_counter); |
icount_++; |
- counter_instructions.Increment(); |
- if (icount_ == FLAG_stop_sim_at) { |
+ if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) { |
SimulatorDebugger dbg(this); |
dbg.Stop(instr, "Instruction count reached"); |
+ } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) { |
+ SimulatorDebugger dbg(this); |
+ dbg.Stop(instr, "Instruction address reached"); |
} else if (IsIllegalAddress(program_counter)) { |
HandleIllegalAccess(program_counter, instr); |
} else { |