2  * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved. 
   4  * Redistribution and use in source and binary forms, with or without 
   5  * modification, are permitted provided that the following conditions 
   7  * 1. Redistributions of source code must retain the above copyright 
   8  *    notice, this list of conditions and the following disclaimer. 
   9  * 2. Redistributions in binary form must reproduce the above copyright 
  10  *    notice, this list of conditions and the following disclaimer in the 
  11  *    documentation and/or other materials provided with the distribution. 
  13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 
  14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
  16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR 
  17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
  19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
  20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
  21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
  23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  29 #include "LLIntThunks.h" 
  30 #include "JSCInlines.h" 
  31 #include "RegisterPreservationWrapperGenerator.h" 
  32 #include <wtf/PrintStream.h> 
  36 JITCode::JITCode(JITType jitType
) 
  45 JSValue 
JITCode::execute(VM
* vm
, ProtoCallFrame
* protoCallFrame
) 
  47     JSValue result 
= JSValue::decode(callToJavaScript(executableAddress(), vm
, protoCallFrame
)); 
  48     return vm
->exception() ? jsNull() : result
; 
  51 DFG::CommonData
* JITCode::dfgCommon() 
  53     RELEASE_ASSERT_NOT_REACHED(); 
  57 DFG::JITCode
* JITCode::dfg() 
  59     RELEASE_ASSERT_NOT_REACHED(); 
  63 FTL::JITCode
* JITCode::ftl() 
  65     RELEASE_ASSERT_NOT_REACHED(); 
  69 FTL::ForOSREntryJITCode
* JITCode::ftlForOSREntry() 
  71     RELEASE_ASSERT_NOT_REACHED(); 
  75 JITCodeWithCodeRef::JITCodeWithCodeRef(JITType jitType
) 
  80 JITCodeWithCodeRef::JITCodeWithCodeRef(CodeRef ref
, JITType jitType
) 
  86 JITCodeWithCodeRef::~JITCodeWithCodeRef() 
  90 void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset
) 
  92     RELEASE_ASSERT(m_ref
); 
  93     return reinterpret_cast<char*>(m_ref
.code().executableAddress()) + offset
; 
  96 void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset
) 
  98     RELEASE_ASSERT(m_ref
); 
  99     ASSERT(offset 
<= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code. 
 100     return reinterpret_cast<char*>(m_ref
.code().dataLocation()) + offset
; 
 103 unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode
) 
 105     RELEASE_ASSERT(m_ref
); 
 106     intptr_t result 
= reinterpret_cast<intptr_t>(pointerIntoCode
) - reinterpret_cast<intptr_t>(m_ref
.code().executableAddress()); 
 107     ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result
)) == result
); 
 108     return static_cast<unsigned>(result
); 
 111 size_t JITCodeWithCodeRef::size() 
 113     RELEASE_ASSERT(m_ref
); 
 117 bool JITCodeWithCodeRef::contains(void* address
) 
 119     RELEASE_ASSERT(m_ref
); 
 120     return m_ref
.executableMemory()->contains(address
); 
 123 DirectJITCode::DirectJITCode(JITType jitType
) 
 124     : JITCodeWithCodeRef(jitType
) 
 128 DirectJITCode::DirectJITCode(JITCode::CodeRef ref
, JITCode::CodePtr withArityCheck
, JITType jitType
) 
 129     : JITCodeWithCodeRef(ref
, jitType
) 
 130     , m_withArityCheck(withArityCheck
) 
 134 DirectJITCode::~DirectJITCode() 
 138 void DirectJITCode::initializeCodeRef(JITCode::CodeRef ref
, JITCode::CodePtr withArityCheck
) 
 140     RELEASE_ASSERT(!m_ref
); 
 142     m_withArityCheck 
= withArityCheck
; 
 145 DirectJITCode::RegisterPreservationWrappers
* DirectJITCode::ensureWrappers() 
 148         m_wrappers 
= std::make_unique
<RegisterPreservationWrappers
>(); 
 149     return m_wrappers
.get(); 
 152 JITCode::CodePtr 
DirectJITCode::addressForCall( 
 153     VM
& vm
, ExecutableBase
* executable
, ArityCheckMode arity
, 
 154     RegisterPreservationMode registers
) 
 157     case ArityCheckNotRequired
: 
 159         case RegisterPreservationNotRequired
: 
 160             RELEASE_ASSERT(m_ref
); 
 162         case MustPreserveRegisters
: { 
 164             RegisterPreservationWrappers
* wrappers 
= ensureWrappers(); 
 165             if (!wrappers
->withoutArityCheck
) 
 166                 wrappers
->withoutArityCheck 
= generateRegisterPreservationWrapper(vm
, executable
, m_ref
.code()); 
 167             return wrappers
->withoutArityCheck
.code(); 
 170             UNUSED_PARAM(executable
); 
 171             RELEASE_ASSERT_NOT_REACHED(); 
 176         case RegisterPreservationNotRequired
: 
 177             RELEASE_ASSERT(m_withArityCheck
); 
 178             return m_withArityCheck
; 
 179         case MustPreserveRegisters
: { 
 181             RegisterPreservationWrappers
* wrappers 
= ensureWrappers(); 
 182             if (!wrappers
->withArityCheck
) 
 183                 wrappers
->withArityCheck 
= generateRegisterPreservationWrapper(vm
, executable
, m_withArityCheck
); 
 184             return wrappers
->withArityCheck
.code(); 
 186             RELEASE_ASSERT_NOT_REACHED(); 
 190     RELEASE_ASSERT_NOT_REACHED(); 
 194 NativeJITCode::NativeJITCode(JITType jitType
) 
 195     : JITCodeWithCodeRef(jitType
) 
 199 NativeJITCode::NativeJITCode(CodeRef ref
, JITType jitType
) 
 200     : JITCodeWithCodeRef(ref
, jitType
) 
 204 NativeJITCode::~NativeJITCode() 
 208 void NativeJITCode::initializeCodeRef(CodeRef ref
) 
 214 JITCode::CodePtr 
NativeJITCode::addressForCall( 
 215     VM
&, ExecutableBase
*, ArityCheckMode
, RegisterPreservationMode
) 
 217     RELEASE_ASSERT(!!m_ref
); 
 225 void printInternal(PrintStream
& out
, JSC::JITCode::JITType type
) 
 228     case JSC::JITCode::None
: 
 231     case JSC::JITCode::HostCallThunk
: 
 234     case JSC::JITCode::InterpreterThunk
: 
 237     case JSC::JITCode::BaselineJIT
: 
 238         out
.print("Baseline"); 
 240     case JSC::JITCode::DFGJIT
: 
 243     case JSC::JITCode::FTLJIT
: