JITOperationList.cpp
1 /* 2 * Copyright (C) 2020 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 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. 12 * 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. 24 */ 25 26 #include "config.h" 27 #include "JITOperationList.h" 28 29 #include "Gate.h" 30 #include "LLIntData.h" 31 #include "Opcode.h" 32 33 #if ENABLE(JIT_CAGE) 34 #include <WebKitAdditions/JITCageAdditions.h> 35 #endif 36 37 namespace JSC { 38 39 LazyNeverDestroyed<JITOperationList> jitOperationList; 40 41 #if ENABLE(JIT_OPERATION_VALIDATION) 42 extern const uintptr_t startOfJITOperationsInJSC __asm("section$start$__DATA_CONST$__jsc_ops"); 43 extern const uintptr_t endOfJITOperationsInJSC __asm("section$end$__DATA_CONST$__jsc_ops"); 44 #endif 45 46 void JITOperationList::initialize() 47 { 48 jitOperationList.construct(); 49 } 50 51 #if ENABLE(JIT_OPERATION_VALIDATION) 52 static SUPPRESS_ASAN ALWAYS_INLINE void addPointers(HashMap<void*, void*>& map, const uintptr_t* beginOperations, const uintptr_t* endOperations) 53 { 54 #if ENABLE(JIT_CAGE) 55 if (Options::useJITCage()) { 56 JSC_JIT_CAGED_POINTER_REGISTRATION(); 57 return; 58 } 59 #endif 60 if constexpr (ASSERT_ENABLED) { 61 for (const uintptr_t* current = beginOperations; current != endOperations; ++current) { 62 void* codePtr = removeCodePtrTag(bitwise_cast<void*>(*current)); 63 if (codePtr) 64 map.add(codePtr, WTF::tagNativeCodePtrImpl<OperationPtrTag>(codePtr)); 65 } 66 } 67 } 68 #endif 69 70 void JITOperationList::populatePointersInJavaScriptCore() 71 { 72 #if ENABLE(JIT_OPERATION_VALIDATION) 73 static std::once_flag onceKey; 74 std::call_once(onceKey, [] { 75 if (Options::useJIT()) 76 addPointers(jitOperationList->m_validatedOperations, &startOfJITOperationsInJSC, &endOfJITOperationsInJSC); 77 }); 78 #endif 79 } 80 81 void JITOperationList::populatePointersInJavaScriptCoreForLLInt() 82 { 83 #if ENABLE(JIT_OPERATION_VALIDATION) 84 static std::once_flag onceKey; 85 std::call_once(onceKey, [] { 86 87 #define LLINT_OP(name) \ 88 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(name)), \ 89 bitwise_cast<uintptr_t>(LLInt::getWide16CodeFunctionPtr<CFunctionPtrTag>(name)), \ 90 bitwise_cast<uintptr_t>(LLInt::getWide32CodeFunctionPtr<CFunctionPtrTag>(name)), 91 92 #define LLINT_RETURN_LOCATION(name, ...) \ 93 LLINT_OP(name##_return_location) 94 95 const uintptr_t operations[] = { 96 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_function_for_call_prologue)), 97 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_function_for_construct_prologue)), 98 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_function_for_call_arity_check)), 99 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_function_for_construct_arity_check)), 100 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_eval_prologue)), 101 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_program_prologue)), 102 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_module_program_prologue)), 103 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(wasm_function_prologue)), 104 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(wasm_function_prologue_no_tls)), 105 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_throw_during_call_trampoline)), 106 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(llint_handle_uncaught_exception)), 107 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(checkpoint_osr_exit_trampoline)), 108 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(checkpoint_osr_exit_from_inlined_call_trampoline)), 109 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(normal_osr_exit_trampoline)), 110 bitwise_cast<uintptr_t>(LLInt::getCodeFunctionPtr<CFunctionPtrTag>(fuzzer_return_early_from_loop_hint)), 111 112 LLINT_OP(op_catch) 113 LLINT_OP(llint_generic_return_point) 114 115 LLINT_RETURN_LOCATION(op_get_by_id) 116 LLINT_RETURN_LOCATION(op_get_by_val) 117 LLINT_RETURN_LOCATION(op_put_by_id) 118 LLINT_RETURN_LOCATION(op_put_by_val) 119 120 JSC_JS_GATE_OPCODES(LLINT_RETURN_LOCATION) 121 JSC_WASM_GATE_OPCODES(LLINT_RETURN_LOCATION) 122 }; 123 if (Options::useJIT()) 124 addPointers(jitOperationList->m_validatedOperations, operations, operations + WTF_ARRAY_LENGTH(operations)); 125 #undef LLINT_RETURN_LOCATION 126 }); 127 #endif 128 } 129 130 131 void JITOperationList::populatePointersInEmbedder(const uintptr_t* beginOperations, const uintptr_t* endOperations) 132 { 133 UNUSED_PARAM(beginOperations); 134 UNUSED_PARAM(endOperations); 135 #if ENABLE(JIT_OPERATION_VALIDATION) 136 if (Options::useJIT()) 137 addPointers(jitOperationList->m_validatedOperations, beginOperations, endOperations); 138 #endif 139 } 140 141 } // namespace JSC