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

Side by Side Diff: runtime/vm/simulator_arm64.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_arm64.h ('k') | runtime/vm/simulator_mips.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64) 9 #if defined(TARGET_ARCH_ARM64)
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_ARM64) 12 #if !defined(HOST_ARCH_ARM64)
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_arm64.h" 17 #include "vm/constants_arm64.h"
18 #include "vm/disassembler.h" 18 #include "vm/disassembler.h"
19 #include "vm/lockers.h" 19 #include "vm/lockers.h"
20 #include "vm/native_arguments.h" 20 #include "vm/native_arguments.h"
21 #include "vm/stack_frame.h" 21 #include "vm/stack_frame.h"
22 #include "vm/os_thread.h" 22 #include "vm/os_thread.h"
23 23
24 namespace dart { 24 namespace dart {
25 25
26 DEFINE_FLAG(int, trace_sim_after, -1, 26 DEFINE_FLAG(uint64_t, trace_sim_after, ULLONG_MAX,
27 "Trace simulator execution after instruction count reached."); 27 "Trace simulator execution after instruction count reached.");
28 DEFINE_FLAG(int, stop_sim_at, -1, 28 DEFINE_FLAG(uint64_t, stop_sim_at, ULLONG_MAX,
29 "Instruction address or instruction count to stop simulator at."); 29 "Instruction address or instruction count to stop simulator at.");
30 30
31 31
32 // 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
33 // SScanF not being implemented in a platform independent way through 33 // SScanF not being implemented in a platform independent way through
34 // 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
35 // Library does not provide vsscanf. 35 // Library does not provide vsscanf.
36 #define SScanF sscanf // NOLINT 36 #define SScanF sscanf // NOLINT
37 37
38 38
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 return false; 191 return false;
192 } 192 }
193 *value = *(reinterpret_cast<int64_t*>(addr)); 193 *value = *(reinterpret_cast<int64_t*>(addr));
194 return true; 194 return true;
195 } 195 }
196 } 196 }
197 if (strcmp("pc", desc) == 0) { 197 if (strcmp("pc", desc) == 0) {
198 *value = sim_->get_pc(); 198 *value = sim_->get_pc();
199 return true; 199 return true;
200 } 200 }
201 if (strcmp("icount", desc) == 0) {
202 *value = sim_->get_icount();
203 return true;
204 }
205 bool retval = SScanF(desc, "0x%"Px64, value) == 1; 201 bool retval = SScanF(desc, "0x%"Px64, value) == 1;
206 if (!retval) { 202 if (!retval) {
207 retval = SScanF(desc, "%"Px64, value) == 1; 203 retval = SScanF(desc, "%"Px64, value) == 1;
208 } 204 }
209 return retval; 205 return retval;
210 } 206 }
211 207
212 208
213 bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) { 209 bool SimulatorDebugger::GetSValue(char* desc, uint32_t* value) {
214 VRegister vreg = LookupVRegisterByName(desc); 210 VRegister vreg = LookupVRegisterByName(desc);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) { 470 } else if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
475 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 471 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
476 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) { 472 } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
477 // Execute the one instruction we broke at with breakpoints disabled. 473 // Execute the one instruction we broke at with breakpoints disabled.
478 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc())); 474 sim_->InstructionDecode(reinterpret_cast<Instr*>(sim_->get_pc()));
479 // Leave the debugger shell. 475 // Leave the debugger shell.
480 done = true; 476 done = true;
481 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) { 477 } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
482 if (args == 2) { 478 if (args == 2) {
483 uint64_t value; 479 uint64_t value;
484 if (GetValue(arg1, &value)) { 480 if (strcmp(arg1, "icount") == 0) {
481 value = sim_->get_icount();
482 OS::Print("icount: %"Pu64" 0x%"Px64"\n", value, value);
483 } else if (GetValue(arg1, &value)) {
485 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value); 484 OS::Print("%s: %"Pu64" 0x%"Px64"\n", arg1, value, value);
486 } else { 485 } else {
487 OS::Print("%s unrecognized\n", arg1); 486 OS::Print("%s unrecognized\n", arg1);
488 } 487 }
489 } else { 488 } else {
490 OS::Print("print <reg or value or *addr>\n"); 489 OS::Print("print <reg or icount or value or *addr>\n");
491 } 490 }
492 } else if ((strcmp(cmd, "pf") == 0) || 491 } else if ((strcmp(cmd, "pf") == 0) ||
493 (strcmp(cmd, "printfloat") == 0)) { 492 (strcmp(cmd, "printfloat") == 0)) {
494 if (args == 2) { 493 if (args == 2) {
495 uint32_t value; 494 uint32_t value;
496 if (GetSValue(arg1, &value)) { 495 if (GetSValue(arg1, &value)) {
497 float svalue = bit_cast<float, uint32_t>(value); 496 float svalue = bit_cast<float, uint32_t>(value);
498 OS::Print("%s: %d 0x%x %.8g\n", 497 OS::Print("%s: %d 0x%x %.8g\n",
499 arg1, value, value, svalue); 498 arg1, value, value, svalue);
500 } else { 499 } else {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 OS::Print("V flag: %d\n", sim_->v_flag_); 633 OS::Print("V flag: %d\n", sim_->v_flag_);
635 } else if (strcmp(cmd, "unstop") == 0) { 634 } else if (strcmp(cmd, "unstop") == 0) {
636 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize; 635 intptr_t stop_pc = sim_->get_pc() - Instr::kInstrSize;
637 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc); 636 Instr* stop_instr = reinterpret_cast<Instr*>(stop_pc);
638 if (stop_instr->IsExceptionGenOp()) { 637 if (stop_instr->IsExceptionGenOp()) {
639 stop_instr->SetInstructionBits(Instr::kNopInstruction); 638 stop_instr->SetInstructionBits(Instr::kNopInstruction);
640 } else { 639 } else {
641 OS::Print("Not at debugger stop.\n"); 640 OS::Print("Not at debugger stop.\n");
642 } 641 }
643 } else if (strcmp(cmd, "trace") == 0) { 642 } else if (strcmp(cmd, "trace") == 0) {
644 if (FLAG_trace_sim_after == -1) { 643 if (FLAG_trace_sim_after == ULLONG_MAX) {
645 FLAG_trace_sim_after = sim_->get_icount(); 644 FLAG_trace_sim_after = sim_->get_icount();
646 OS::Print("execution tracing on\n"); 645 OS::Print("execution tracing on\n");
647 } else { 646 } else {
648 FLAG_trace_sim_after = -1; 647 FLAG_trace_sim_after = ULLONG_MAX;
649 OS::Print("execution tracing off\n"); 648 OS::Print("execution tracing off\n");
650 } 649 }
651 } else if (strcmp(cmd, "bt") == 0) { 650 } else if (strcmp(cmd, "bt") == 0) {
652 PrintBacktrace(); 651 PrintBacktrace();
653 } else { 652 } else {
654 OS::Print("Unknown command: %s\n", cmd); 653 OS::Print("Unknown command: %s\n", cmd);
655 } 654 }
656 } 655 }
657 delete[] line; 656 delete[] line;
658 } 657 }
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 // validity. 1056 // validity.
1058 uword Simulator::StackTop() const { 1057 uword Simulator::StackTop() const {
1059 // To be safe in potential stack underflows we leave some buffer above and 1058 // To be safe in potential stack underflows we leave some buffer above and
1060 // set the stack top. 1059 // set the stack top.
1061 return reinterpret_cast<uword>(stack_) + 1060 return reinterpret_cast<uword>(stack_) +
1062 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer); 1061 (Isolate::GetSpecifiedStackSize() + Isolate::kStackSizeBuffer);
1063 } 1062 }
1064 1063
1065 1064
1066 bool Simulator::IsTracingExecution() const { 1065 bool Simulator::IsTracingExecution() const {
1067 // Integer flag values are signed, so we must cast to unsigned. 1066 return icount_ > FLAG_trace_sim_after;
1068 // The default of -1 hence becomes the maximum unsigned value.
1069 return (static_cast<uintptr_t>(icount_) >
1070 static_cast<uintptr_t>(FLAG_trace_sim_after));
1071 } 1067 }
1072 1068
1073 1069
1074 intptr_t Simulator::ReadX(uword addr, Instr* instr) { 1070 intptr_t Simulator::ReadX(uword addr, Instr* instr) {
1075 if ((addr & 7) == 0) { 1071 if ((addr & 7) == 0) {
1076 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr); 1072 intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
1077 return *ptr; 1073 return *ptr;
1078 } 1074 }
1079 UnalignedAccess("read", addr, instr); 1075 UnalignedAccess("read", addr, instr);
1080 return 0; 1076 return 0;
(...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 } else { 3296 } else {
3301 UnimplementedInstruction(instr); 3297 UnimplementedInstruction(instr);
3302 } 3298 }
3303 } 3299 }
3304 3300
3305 3301
3306 // Executes the current instruction. 3302 // Executes the current instruction.
3307 void Simulator::InstructionDecode(Instr* instr) { 3303 void Simulator::InstructionDecode(Instr* instr) {
3308 pc_modified_ = false; 3304 pc_modified_ = false;
3309 if (IsTracingExecution()) { 3305 if (IsTracingExecution()) {
3310 OS::Print("%" Pd " ", icount_); 3306 OS::Print("%"Pu64, icount_);
3311 const uword start = reinterpret_cast<uword>(instr); 3307 const uword start = reinterpret_cast<uword>(instr);
3312 const uword end = start + Instr::kInstrSize; 3308 const uword end = start + Instr::kInstrSize;
3313 Disassembler::Disassemble(start, end); 3309 Disassembler::Disassemble(start, end);
3314 } 3310 }
3315 3311
3316 if (instr->IsDPImmediateOp()) { 3312 if (instr->IsDPImmediateOp()) {
3317 DecodeDPImmediate(instr); 3313 DecodeDPImmediate(instr);
3318 } else if (instr->IsCompareBranchOp()) { 3314 } else if (instr->IsCompareBranchOp()) {
3319 DecodeCompareBranch(instr); 3315 DecodeCompareBranch(instr);
3320 } else if (instr->IsLoadStoreOp()) { 3316 } else if (instr->IsLoadStoreOp()) {
(...skipping 12 matching lines...) Expand all
3333 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize); 3329 set_pc(reinterpret_cast<int64_t>(instr) + Instr::kInstrSize);
3334 } 3330 }
3335 } 3331 }
3336 3332
3337 3333
3338 void Simulator::Execute() { 3334 void Simulator::Execute() {
3339 // Get the PC to simulate. Cannot use the accessor here as we need the 3335 // Get the PC to simulate. Cannot use the accessor here as we need the
3340 // raw PC value and not the one used as input to arithmetic instructions. 3336 // raw PC value and not the one used as input to arithmetic instructions.
3341 uword program_counter = get_pc(); 3337 uword program_counter = get_pc();
3342 3338
3343 if (FLAG_stop_sim_at == 0) { 3339 if (FLAG_stop_sim_at == ULLONG_MAX) {
3344 // Fast version of the dispatch loop without checking whether the simulator 3340 // Fast version of the dispatch loop without checking whether the simulator
3345 // should be stopping at a particular executed instruction. 3341 // should be stopping at a particular executed instruction.
3346 while (program_counter != kEndSimulatingPC) { 3342 while (program_counter != kEndSimulatingPC) {
3347 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3343 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3348 icount_++; 3344 icount_++;
3349 if (IsIllegalAddress(program_counter)) { 3345 if (IsIllegalAddress(program_counter)) {
3350 HandleIllegalAccess(program_counter, instr); 3346 HandleIllegalAccess(program_counter, instr);
3351 } else { 3347 } else {
3352 InstructionDecode(instr); 3348 InstructionDecode(instr);
3353 } 3349 }
3354 program_counter = get_pc(); 3350 program_counter = get_pc();
3355 } 3351 }
3356 } else { 3352 } else {
3357 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when 3353 // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
3358 // we reach the particular instruction count or address. 3354 // we reach the particular instruction count or address.
3359 while (program_counter != kEndSimulatingPC) { 3355 while (program_counter != kEndSimulatingPC) {
3360 Instr* instr = reinterpret_cast<Instr*>(program_counter); 3356 Instr* instr = reinterpret_cast<Instr*>(program_counter);
3361 icount_++; 3357 icount_++;
3362 if (static_cast<intptr_t>(icount_) == FLAG_stop_sim_at) { 3358 if (icount_ == FLAG_stop_sim_at) {
3363 SimulatorDebugger dbg(this); 3359 SimulatorDebugger dbg(this);
3364 dbg.Stop(instr, "Instruction count reached"); 3360 dbg.Stop(instr, "Instruction count reached");
3365 } else if (reinterpret_cast<intptr_t>(instr) == FLAG_stop_sim_at) { 3361 } else if (reinterpret_cast<uint64_t>(instr) == FLAG_stop_sim_at) {
3366 SimulatorDebugger dbg(this); 3362 SimulatorDebugger dbg(this);
3367 dbg.Stop(instr, "Instruction address reached"); 3363 dbg.Stop(instr, "Instruction address reached");
3368 } else if (IsIllegalAddress(program_counter)) { 3364 } else if (IsIllegalAddress(program_counter)) {
3369 HandleIllegalAccess(program_counter, instr); 3365 HandleIllegalAccess(program_counter, instr);
3370 } else { 3366 } else {
3371 InstructionDecode(instr); 3367 InstructionDecode(instr);
3372 } 3368 }
3373 program_counter = get_pc(); 3369 program_counter = get_pc();
3374 } 3370 }
3375 } 3371 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3505 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception)); 3501 set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
3506 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace)); 3502 set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
3507 buf->Longjmp(); 3503 buf->Longjmp();
3508 } 3504 }
3509 3505
3510 } // namespace dart 3506 } // namespace dart
3511 3507
3512 #endif // !defined(HOST_ARCH_ARM64) 3508 #endif // !defined(HOST_ARCH_ARM64)
3513 3509
3514 #endif // defined TARGET_ARCH_ARM64 3510 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/simulator_arm64.h ('k') | runtime/vm/simulator_mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698