OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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_DBC) | 9 #if defined(TARGET_ARCH_DBC) |
10 | 10 |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; | 522 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; |
523 intrinsics_[kDouble_lessEqualThanIntrinsic] = | 523 intrinsics_[kDouble_lessEqualThanIntrinsic] = |
524 SimulatorHelpers::Double_lessEqualThan; | 524 SimulatorHelpers::Double_lessEqualThan; |
525 intrinsics_[kClearAsyncThreadStackTraceIntrinsic] = | 525 intrinsics_[kClearAsyncThreadStackTraceIntrinsic] = |
526 SimulatorHelpers::ClearAsyncThreadStack; | 526 SimulatorHelpers::ClearAsyncThreadStack; |
527 intrinsics_[kSetAsyncThreadStackTraceIntrinsic] = | 527 intrinsics_[kSetAsyncThreadStackTraceIntrinsic] = |
528 SimulatorHelpers::SetAsyncThreadStackTrace; | 528 SimulatorHelpers::SetAsyncThreadStackTrace; |
529 } | 529 } |
530 | 530 |
531 | 531 |
532 Simulator::Simulator() : stack_(NULL), fp_(NULL) { | 532 Simulator::Simulator() : stack_(NULL), fp_(NULL), icount_(0) { |
533 // Setup simulator support first. Some of this information is needed to | 533 // Setup simulator support first. Some of this information is needed to |
534 // setup the architecture state. | 534 // setup the architecture state. |
535 // We allocate the stack here, the size is computed as the sum of | 535 // We allocate the stack here, the size is computed as the sum of |
536 // the size specified by the user and the buffer space needed for | 536 // the size specified by the user and the buffer space needed for |
537 // handling stack overflow exceptions. To be safe in potential | 537 // handling stack overflow exceptions. To be safe in potential |
538 // stack underflows we also add some underflow buffer space. | 538 // stack underflows we also add some underflow buffer space. |
539 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + | 539 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + |
540 OSThread::kStackSizeBuffer + | 540 OSThread::kStackSizeBuffer + |
541 kSimulatorStackUnderflowSize) / | 541 kSimulatorStackUnderflowSize) / |
542 sizeof(uintptr_t)]; | 542 sizeof(uintptr_t)]; |
(...skipping 25 matching lines...) Expand all Loading... |
568 // Returns the top of the stack area to enable checking for stack pointer | 568 // Returns the top of the stack area to enable checking for stack pointer |
569 // validity. | 569 // validity. |
570 uword Simulator::StackTop() const { | 570 uword Simulator::StackTop() const { |
571 // To be safe in potential stack underflows we leave some buffer above and | 571 // To be safe in potential stack underflows we leave some buffer above and |
572 // set the stack top. | 572 // set the stack top. |
573 return StackBase() + | 573 return StackBase() + |
574 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); | 574 (OSThread::GetSpecifiedStackSize() + OSThread::kStackSizeBuffer); |
575 } | 575 } |
576 | 576 |
577 | 577 |
| 578 // Returns true if tracing of executed instructions is enabled. |
| 579 DART_FORCE_INLINE bool Simulator::IsTracingExecution() const { |
| 580 return icount_ > FLAG_trace_sim_after; |
| 581 } |
| 582 |
| 583 |
| 584 // Prints bytecode instruction at given pc for instruction tracing. |
| 585 DART_NOINLINE void Simulator::TraceInstruction(uint32_t* pc) const { |
| 586 THR_Print("%" Pu64 " ", icount_); |
| 587 if (FLAG_support_disassembler) { |
| 588 Disassembler::Disassemble(reinterpret_cast<uword>(pc), |
| 589 reinterpret_cast<uword>(pc + 1)); |
| 590 } else { |
| 591 THR_Print("Disassembler not supported in this mode.\n"); |
| 592 } |
| 593 } |
| 594 |
| 595 |
578 // Calls into the Dart runtime are based on this interface. | 596 // Calls into the Dart runtime are based on this interface. |
579 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); | 597 typedef void (*SimulatorRuntimeCall)(NativeArguments arguments); |
580 | 598 |
581 // Calls to leaf Dart runtime functions are based on this interface. | 599 // Calls to leaf Dart runtime functions are based on this interface. |
582 typedef intptr_t (*SimulatorLeafRuntimeCall)(intptr_t r0, | 600 typedef intptr_t (*SimulatorLeafRuntimeCall)(intptr_t r0, |
583 intptr_t r1, | 601 intptr_t r1, |
584 intptr_t r2, | 602 intptr_t r2, |
585 intptr_t r3); | 603 intptr_t r3); |
586 | 604 |
587 // Calls to leaf float Dart runtime functions are based on this interface. | 605 // Calls to leaf float Dart runtime functions are based on this interface. |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
977 thread->set_vm_tag(VMTag::kDartTagId); | 995 thread->set_vm_tag(VMTag::kDartTagId); |
978 thread->set_top_exit_frame_info(0); | 996 thread->set_top_exit_frame_info(0); |
979 return true; | 997 return true; |
980 } else { | 998 } else { |
981 return false; | 999 return false; |
982 } | 1000 } |
983 } | 1001 } |
984 | 1002 |
985 // Note: all macro helpers are intended to be used only inside Simulator::Call. | 1003 // Note: all macro helpers are intended to be used only inside Simulator::Call. |
986 | 1004 |
| 1005 // Counts and prints executed bytecode instructions (in a non-PRODUCT mode). |
| 1006 #if !defined(PRODUCT) |
| 1007 #define TRACE_INSTRUCTION \ |
| 1008 icount_++; \ |
| 1009 if (IsTracingExecution()) { \ |
| 1010 TraceInstruction(pc - 1); \ |
| 1011 } |
| 1012 #else |
| 1013 #define TRACE_INSTRUCTION |
| 1014 #endif |
| 1015 |
987 // Decode opcode and A part of the given value and dispatch to the | 1016 // Decode opcode and A part of the given value and dispatch to the |
988 // corresponding bytecode handler. | 1017 // corresponding bytecode handler. |
989 #define DISPATCH_OP(val) \ | 1018 #define DISPATCH_OP(val) \ |
990 do { \ | 1019 do { \ |
991 op = (val); \ | 1020 op = (val); \ |
992 rA = ((op >> 8) & 0xFF); \ | 1021 rA = ((op >> 8) & 0xFF); \ |
| 1022 TRACE_INSTRUCTION \ |
993 goto* dispatch[op & 0xFF]; \ | 1023 goto* dispatch[op & 0xFF]; \ |
994 } while (0) | 1024 } while (0) |
995 | 1025 |
996 // Fetch next operation from PC, increment program counter and dispatch. | 1026 // Fetch next operation from PC, increment program counter and dispatch. |
997 #define DISPATCH() DISPATCH_OP(*pc++) | 1027 #define DISPATCH() DISPATCH_OP(*pc++) |
998 | 1028 |
999 // Define entry point that handles bytecode Name with the given operand format. | 1029 // Define entry point that handles bytecode Name with the given operand format. |
1000 #define BYTECODE(Name, Operands) \ | 1030 #define BYTECODE(Name, Operands) \ |
1001 BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands) | 1031 BYTECODE_HEADER(Name, DECLARE_##Operands, DECODE_##Operands) |
1002 | 1032 |
(...skipping 2897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3900 pc_ = pc; | 3930 pc_ = pc; |
3901 } | 3931 } |
3902 | 3932 |
3903 buf->Longjmp(); | 3933 buf->Longjmp(); |
3904 UNREACHABLE(); | 3934 UNREACHABLE(); |
3905 } | 3935 } |
3906 | 3936 |
3907 } // namespace dart | 3937 } // namespace dart |
3908 | 3938 |
3909 #endif // defined TARGET_ARCH_DBC | 3939 #endif // defined TARGET_ARCH_DBC |
OLD | NEW |