| 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 |