2017-08-12 16:48:01 +00:00
/*
2020-08-29 13:27:11 +00:00
* Copyright ( C ) 2008 - 2018 Apple Inc . All rights reserved .
2017-08-12 16:48:01 +00:00
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC . ` ` AS IS ' ' AND ANY
* EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL APPLE INC . OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL ,
* EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO ,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR
* PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# pragma once
# include "ArityCheckMode.h"
# include "CallFrame.h"
# include "CodeOrigin.h"
# include "JSCJSValue.h"
# include "MacroAssemblerCodeRef.h"
# include "RegisterSet.h"
# include <wtf/Optional.h>
namespace JSC {
namespace DFG {
class CommonData ;
class JITCode ;
}
namespace FTL {
class ForOSREntryJITCode ;
class JITCode ;
}
2020-08-29 13:27:11 +00:00
namespace DOMJIT {
class Signature ;
}
2017-08-12 16:48:01 +00:00
struct ProtoCallFrame ;
class TrackedReferences ;
class VM ;
2020-08-29 13:27:11 +00:00
enum class JITType : uint8_t {
None ,
HostCallThunk ,
InterpreterThunk ,
BaselineJIT ,
DFGJIT ,
FTLJIT
} ;
2017-08-12 16:48:01 +00:00
class JITCode : public ThreadSafeRefCounted < JITCode > {
public :
2020-08-29 13:27:11 +00:00
template < PtrTag tag > using CodePtr = MacroAssemblerCodePtr < tag > ;
template < PtrTag tag > using CodeRef = MacroAssemblerCodeRef < tag > ;
2017-08-12 16:48:01 +00:00
static const char * typeName ( JITType ) ;
static JITType bottomTierJIT ( )
{
2020-08-29 13:27:11 +00:00
return JITType : : BaselineJIT ;
2017-08-12 16:48:01 +00:00
}
static JITType topTierJIT ( )
{
2020-08-29 13:27:11 +00:00
return JITType : : FTLJIT ;
2017-08-12 16:48:01 +00:00
}
static JITType nextTierJIT ( JITType jitType )
{
switch ( jitType ) {
2020-08-29 13:27:11 +00:00
case JITType : : BaselineJIT :
return JITType : : DFGJIT ;
case JITType : : DFGJIT :
return JITType : : FTLJIT ;
2017-08-12 16:48:01 +00:00
default :
RELEASE_ASSERT_NOT_REACHED ( ) ;
2020-08-29 13:27:11 +00:00
return JITType : : None ;
2017-08-12 16:48:01 +00:00
}
}
static bool isExecutableScript ( JITType jitType )
{
switch ( jitType ) {
2020-08-29 13:27:11 +00:00
case JITType : : None :
case JITType : : HostCallThunk :
2017-08-12 16:48:01 +00:00
return false ;
default :
return true ;
}
}
static bool couldBeInterpreted ( JITType jitType )
{
switch ( jitType ) {
2020-08-29 13:27:11 +00:00
case JITType : : InterpreterThunk :
case JITType : : BaselineJIT :
2017-08-12 16:48:01 +00:00
return true ;
default :
return false ;
}
}
static bool isJIT ( JITType jitType )
{
switch ( jitType ) {
2020-08-29 13:27:11 +00:00
case JITType : : BaselineJIT :
case JITType : : DFGJIT :
case JITType : : FTLJIT :
2017-08-12 16:48:01 +00:00
return true ;
default :
return false ;
}
}
static bool isLowerTier ( JITType expectedLower , JITType expectedHigher )
{
RELEASE_ASSERT ( isExecutableScript ( expectedLower ) ) ;
RELEASE_ASSERT ( isExecutableScript ( expectedHigher ) ) ;
return expectedLower < expectedHigher ;
}
static bool isHigherTier ( JITType expectedHigher , JITType expectedLower )
{
return isLowerTier ( expectedLower , expectedHigher ) ;
}
static bool isLowerOrSameTier ( JITType expectedLower , JITType expectedHigher )
{
return ! isHigherTier ( expectedLower , expectedHigher ) ;
}
static bool isHigherOrSameTier ( JITType expectedHigher , JITType expectedLower )
{
return isLowerOrSameTier ( expectedLower , expectedHigher ) ;
}
static bool isOptimizingJIT ( JITType jitType )
{
2020-08-29 13:27:11 +00:00
return jitType = = JITType : : DFGJIT | | jitType = = JITType : : FTLJIT ;
2017-08-12 16:48:01 +00:00
}
static bool isBaselineCode ( JITType jitType )
{
2020-08-29 13:27:11 +00:00
return jitType = = JITType : : InterpreterThunk | | jitType = = JITType : : BaselineJIT ;
2017-08-12 16:48:01 +00:00
}
2020-08-29 13:27:11 +00:00
virtual const DOMJIT : : Signature * signature ( ) const { return nullptr ; }
2017-08-12 16:48:01 +00:00
2020-08-29 13:27:11 +00:00
enum class ShareAttribute : uint8_t {
NotShared ,
Shared
} ;
2017-08-12 16:48:01 +00:00
protected :
2020-08-29 13:27:11 +00:00
JITCode ( JITType , JITCode : : ShareAttribute = JITCode : : ShareAttribute : : NotShared ) ;
2017-08-12 16:48:01 +00:00
public :
virtual ~ JITCode ( ) ;
JITType jitType ( ) const
{
return m_jitType ;
}
template < typename PointerType >
static JITType jitTypeFor ( PointerType jitCode )
{
if ( ! jitCode )
2020-08-29 13:27:11 +00:00
return JITType : : None ;
2017-08-12 16:48:01 +00:00
return jitCode - > jitType ( ) ;
}
2020-08-29 13:27:11 +00:00
virtual CodePtr < JSEntryPtrTag > addressForCall ( ArityCheckMode ) = 0 ;
2017-08-12 16:48:01 +00:00
virtual void * executableAddressAtOffset ( size_t offset ) = 0 ;
void * executableAddress ( ) { return executableAddressAtOffset ( 0 ) ; }
virtual void * dataAddressAtOffset ( size_t offset ) = 0 ;
virtual unsigned offsetOf ( void * pointerIntoCode ) = 0 ;
virtual DFG : : CommonData * dfgCommon ( ) ;
virtual DFG : : JITCode * dfg ( ) ;
virtual FTL : : JITCode * ftl ( ) ;
virtual FTL : : ForOSREntryJITCode * ftlForOSREntry ( ) ;
2022-10-23 02:55:20 +00:00
virtual void shrinkToFit ( const ConcurrentJSLocker & ) ;
2017-08-12 16:48:01 +00:00
virtual void validateReferences ( const TrackedReferences & ) ;
JSValue execute ( VM * , ProtoCallFrame * ) ;
void * start ( ) { return dataAddressAtOffset ( 0 ) ; }
virtual size_t size ( ) = 0 ;
void * end ( ) { return reinterpret_cast < void * > ( reinterpret_cast < uintptr_t > ( start ( ) ) + size ( ) ) ; }
virtual bool contains ( void * ) = 0 ;
# if ENABLE(JIT)
virtual RegisterSet liveRegistersToPreserveAtExceptionHandlingCallSite ( CodeBlock * , CallSiteIndex ) ;
2020-08-29 13:27:11 +00:00
virtual Optional < CodeOrigin > findPC ( CodeBlock * , void * pc ) { UNUSED_PARAM ( pc ) ; return WTF : : nullopt ; }
2017-08-12 16:48:01 +00:00
# endif
2020-08-29 13:27:11 +00:00
Intrinsic intrinsic ( ) { return m_intrinsic ; }
bool isShared ( ) const { return m_shareAttribute = = ShareAttribute : : Shared ; }
2017-08-12 16:48:01 +00:00
private :
JITType m_jitType ;
2020-08-29 13:27:11 +00:00
ShareAttribute m_shareAttribute ;
protected :
Intrinsic m_intrinsic { NoIntrinsic } ; // Effective only in NativeExecutable.
2017-08-12 16:48:01 +00:00
} ;
class JITCodeWithCodeRef : public JITCode {
protected :
JITCodeWithCodeRef ( JITType ) ;
2020-08-29 13:27:11 +00:00
JITCodeWithCodeRef ( CodeRef < JSEntryPtrTag > , JITType , JITCode : : ShareAttribute ) ;
2017-08-12 16:48:01 +00:00
public :
2022-10-23 02:55:20 +00:00
~ JITCodeWithCodeRef ( ) override ;
2017-08-12 16:48:01 +00:00
void * executableAddressAtOffset ( size_t offset ) override ;
void * dataAddressAtOffset ( size_t offset ) override ;
unsigned offsetOf ( void * pointerIntoCode ) override ;
size_t size ( ) override ;
bool contains ( void * ) override ;
protected :
2020-08-29 13:27:11 +00:00
CodeRef < JSEntryPtrTag > m_ref ;
2017-08-12 16:48:01 +00:00
} ;
2022-10-23 02:55:20 +00:00
DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER ( DirectJITCode ) ;
2017-08-12 16:48:01 +00:00
class DirectJITCode : public JITCodeWithCodeRef {
2022-10-23 02:55:20 +00:00
WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER ( DirectJITCode ) ;
2017-08-12 16:48:01 +00:00
public :
DirectJITCode ( JITType ) ;
2020-08-29 13:27:11 +00:00
DirectJITCode ( CodeRef < JSEntryPtrTag > , CodePtr < JSEntryPtrTag > withArityCheck , JITType , JITCode : : ShareAttribute = JITCode : : ShareAttribute : : NotShared ) ;
DirectJITCode ( CodeRef < JSEntryPtrTag > , CodePtr < JSEntryPtrTag > withArityCheck , JITType , Intrinsic , JITCode : : ShareAttribute = JITCode : : ShareAttribute : : NotShared ) ; // For generated thunk.
2022-10-23 02:55:20 +00:00
~ DirectJITCode ( ) override ;
2017-08-12 16:48:01 +00:00
2020-08-29 13:27:11 +00:00
CodePtr < JSEntryPtrTag > addressForCall ( ArityCheckMode ) override ;
2017-08-12 16:48:01 +00:00
2020-08-29 13:27:11 +00:00
protected :
void initializeCodeRefForDFG ( CodeRef < JSEntryPtrTag > , CodePtr < JSEntryPtrTag > withArityCheck ) ;
2017-08-12 16:48:01 +00:00
private :
2020-08-29 13:27:11 +00:00
CodePtr < JSEntryPtrTag > m_withArityCheck ;
2017-08-12 16:48:01 +00:00
} ;
class NativeJITCode : public JITCodeWithCodeRef {
public :
NativeJITCode ( JITType ) ;
2020-08-29 13:27:11 +00:00
NativeJITCode ( CodeRef < JSEntryPtrTag > , JITType , Intrinsic , JITCode : : ShareAttribute = JITCode : : ShareAttribute : : NotShared ) ;
2022-10-23 02:55:20 +00:00
~ NativeJITCode ( ) override ;
2017-08-12 16:48:01 +00:00
2020-08-29 13:27:11 +00:00
CodePtr < JSEntryPtrTag > addressForCall ( ArityCheckMode ) override ;
} ;
class NativeDOMJITCode final : public NativeJITCode {
public :
NativeDOMJITCode ( CodeRef < JSEntryPtrTag > , JITType , Intrinsic , const DOMJIT : : Signature * ) ;
2022-10-23 02:55:20 +00:00
~ NativeDOMJITCode ( ) final = default ;
2020-08-29 13:27:11 +00:00
2022-10-23 02:55:20 +00:00
const DOMJIT : : Signature * signature ( ) const final { return m_signature ; }
2020-08-29 13:27:11 +00:00
private :
const DOMJIT : : Signature * m_signature ;
2017-08-12 16:48:01 +00:00
} ;
} // namespace JSC
namespace WTF {
class PrintStream ;
2020-08-29 13:27:11 +00:00
void printInternal ( PrintStream & , JSC : : JITType ) ;
2017-08-12 16:48:01 +00:00
} // namespace WTF