LCOV - code coverage report
Current view: top level - src - simulator.h (source / functions) Hit Total Coverage
Test: app.info Lines: 6 6 100.0 %
Date: 2019-04-19 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2009 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_SIMULATOR_H_
       6             : #define V8_SIMULATOR_H_
       7             : 
       8             : #include "src/globals.h"
       9             : #include "src/objects/code.h"
      10             : 
      11             : #if !defined(USE_SIMULATOR)
      12             : #include "src/utils.h"
      13             : #endif
      14             : 
      15             : #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
      16             : // No simulator for ia32 or x64.
      17             : #elif V8_TARGET_ARCH_ARM64
      18             : #include "src/arm64/simulator-arm64.h"
      19             : #elif V8_TARGET_ARCH_ARM
      20             : #include "src/arm/simulator-arm.h"
      21             : #elif V8_TARGET_ARCH_PPC
      22             : #include "src/ppc/simulator-ppc.h"
      23             : #elif V8_TARGET_ARCH_MIPS
      24             : #include "src/mips/simulator-mips.h"
      25             : #elif V8_TARGET_ARCH_MIPS64
      26             : #include "src/mips64/simulator-mips64.h"
      27             : #elif V8_TARGET_ARCH_S390
      28             : #include "src/s390/simulator-s390.h"
      29             : #else
      30             : #error Unsupported target architecture.
      31             : #endif
      32             : 
      33             : namespace v8 {
      34             : namespace internal {
      35             : 
      36             : #if defined(USE_SIMULATOR)
      37             : // Running with a simulator.
      38             : 
      39             : // The simulator has its own stack. Thus it has a different stack limit from
      40             : // the C-based native code.  The JS-based limit normally points near the end of
      41             : // the simulator stack.  When the C-based limit is exhausted we reflect that by
      42             : // lowering the JS-based limit as well, to make stack checks trigger.
      43             : class SimulatorStack : public v8::internal::AllStatic {
      44             :  public:
      45             :   static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
      46             :                                             uintptr_t c_limit) {
      47             :     return Simulator::current(isolate)->StackLimit(c_limit);
      48             :   }
      49             : 
      50             :   // Returns the current stack address on the simulator stack frame.
      51             :   // The returned address is comparable with JS stack address.
      52             :   static inline uintptr_t RegisterJSStackComparableAddress(
      53             :       v8::internal::Isolate* isolate) {
      54             :     // The value of |kPlaceHolder| is actually not used.  It just occupies a
      55             :     // single word on the stack frame of the simulator.
      56             :     const uintptr_t kPlaceHolder = 0x4A535350u;  // "JSSP" in ASCII
      57             :     return Simulator::current(isolate)->PushAddress(kPlaceHolder);
      58             :   }
      59             : 
      60             :   static inline void UnregisterJSStackComparableAddress(
      61             :       v8::internal::Isolate* isolate) {
      62             :     Simulator::current(isolate)->PopAddress();
      63             :   }
      64             : };
      65             : 
      66             : #else  // defined(USE_SIMULATOR)
      67             : // Running without a simulator on a native platform.
      68             : 
      69             : // The stack limit beyond which we will throw stack overflow errors in
      70             : // generated code. Because generated code uses the C stack, we just use
      71             : // the C stack limit.
      72             : class SimulatorStack : public v8::internal::AllStatic {
      73             :  public:
      74             :   static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
      75             :                                             uintptr_t c_limit) {
      76             :     USE(isolate);
      77             :     return c_limit;
      78             :   }
      79             : 
      80             :   // Returns the current stack address on the native stack frame.
      81             :   // The returned address is comparable with JS stack address.
      82             :   static inline uintptr_t RegisterJSStackComparableAddress(
      83             :       v8::internal::Isolate* isolate) {
      84             :     USE(isolate);
      85    20997470 :     return internal::GetCurrentStackPosition();
      86             :   }
      87             : 
      88             :   static inline void UnregisterJSStackComparableAddress(
      89             :       v8::internal::Isolate* isolate) {
      90             :     USE(isolate);
      91             :   }
      92             : };
      93             : 
      94             : #endif  // defined(USE_SIMULATOR)
      95             : 
      96             : // Use this class either as {GeneratedCode<ret, arg1, arg2>} or
      97             : // {GeneratedCode<ret(arg1, arg2)>} (see specialization below).
      98             : template <typename Return, typename... Args>
      99             : class GeneratedCode {
     100             :  public:
     101             :   using Signature = Return(Args...);
     102             : 
     103             :   static GeneratedCode FromAddress(Isolate* isolate, Address addr) {
     104    79221765 :     return GeneratedCode(isolate, reinterpret_cast<Signature*>(addr));
     105             :   }
     106             : 
     107             :   static GeneratedCode FromBuffer(Isolate* isolate, byte* buffer) {
     108         165 :     return GeneratedCode(isolate, reinterpret_cast<Signature*>(buffer));
     109             :   }
     110             : 
     111             :   static GeneratedCode FromCode(Code code) {
     112             :     return FromAddress(code->GetIsolate(), code->entry());
     113             :   }
     114             : 
     115             : #ifdef USE_SIMULATOR
     116             :   // Defined in simulator-base.h.
     117             :   Return Call(Args... args) {
     118             :     return Simulator::current(isolate_)->template Call<Return>(
     119             :         reinterpret_cast<Address>(fn_ptr_), args...);
     120             :   }
     121             : 
     122             :   DISABLE_CFI_ICALL Return CallIrregexp(Args... args) { return Call(args...); }
     123             : #else
     124             : 
     125             :   DISABLE_CFI_ICALL Return Call(Args... args) {
     126             :     // When running without a simulator we call the entry directly.
     127             : #if V8_OS_AIX
     128             :     // AIX ABI requires function descriptors (FD).  Artificially create a pseudo
     129             :     // FD to ensure correct dispatch to generated code.  The 'volatile'
     130             :     // declaration is required to avoid the compiler from not observing the
     131             :     // alias of the pseudo FD to the function pointer, and hence, optimizing the
     132             :     // pseudo FD declaration/initialization away.
     133             :     volatile Address function_desc[] = {reinterpret_cast<Address>(fn_ptr_), 0,
     134             :                                         0};
     135             :     Signature* fn = reinterpret_cast<Signature*>(function_desc);
     136             :     return fn(args...);
     137             : #else
     138    79114616 :     return fn_ptr_(args...);
     139             : #endif  // V8_OS_AIX
     140             :   }
     141             : 
     142             :   DISABLE_CFI_ICALL Return CallIrregexp(Args... args) {
     143             :     // When running without a simulator we call the entry directly.
     144      111476 :     return fn_ptr_(args...);
     145             :   }
     146             : #endif  // USE_SIMULATOR
     147             : 
     148             :  private:
     149             :   friend class GeneratedCode<Return(Args...)>;
     150             :   Isolate* isolate_;
     151             :   Signature* fn_ptr_;
     152             :   GeneratedCode(Isolate* isolate, Signature* fn_ptr)
     153             :       : isolate_(isolate), fn_ptr_(fn_ptr) {}
     154             : };
     155             : 
     156             : // Allow to use {GeneratedCode<ret(arg1, arg2)>} instead of
     157             : // {GeneratedCode<ret, arg1, arg2>}.
     158             : template <typename Return, typename... Args>
     159             : class GeneratedCode<Return(Args...)> : public GeneratedCode<Return, Args...> {
     160             :  public:
     161             :   // Automatically convert from {GeneratedCode<ret, arg1, arg2>} to
     162             :   // {GeneratedCode<ret(arg1, arg2)>}.
     163             :   GeneratedCode(GeneratedCode<Return, Args...> other)
     164             :       : GeneratedCode<Return, Args...>(other.isolate_, other.fn_ptr_) {}
     165             : };
     166             : 
     167             : }  // namespace internal
     168      122036 : }  // namespace v8
     169             : 
     170             : #endif  // V8_SIMULATOR_H_

Generated by: LCOV version 1.10