barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 1 | /* |
mark.lam@apple.com | 03313a9 | 2018-02-27 07:50:54 +0000 | [diff] [blame] | 2 | * Copyright (C) 2009-2018 Apple Inc. All rights reserved. |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 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 | |
ryanhaddad@apple.com | 22104f5 | 2016-09-28 17:08:17 +0000 | [diff] [blame] | 26 | #pragma once |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 27 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 28 | #if ENABLE(ASSEMBLER) |
| 29 | |
ggaren@apple.com | aa701ef | 2010-10-14 19:19:17 +0000 | [diff] [blame] | 30 | #define DUMP_LINK_STATISTICS 0 |
| 31 | #define DUMP_CODE 0 |
| 32 | |
barraclough@apple.com | b6a00d3 | 2012-01-23 21:08:34 +0000 | [diff] [blame] | 33 | #define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1)) |
| 34 | #define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2)) |
benjamin@webkit.org | 182c19a | 2013-12-23 00:45:25 +0000 | [diff] [blame] | 35 | #define CSS_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-3)) |
barraclough@apple.com | b6a00d3 | 2012-01-23 21:08:34 +0000 | [diff] [blame] | 36 | |
fpizlo@apple.com | 0f25ee8 | 2012-03-01 05:46:20 +0000 | [diff] [blame] | 37 | #include "JITCompilationEffort.h" |
fpizlo@apple.com | 7bbcaab | 2012-02-22 05:23:19 +0000 | [diff] [blame] | 38 | #include "MacroAssembler.h" |
mark.lam@apple.com | de1e15f | 2018-04-30 22:29:21 +0000 | [diff] [blame] | 39 | #include "MacroAssemblerCodeRef.h" |
fpizlo@apple.com | d095b24 | 2012-02-12 03:21:32 +0000 | [diff] [blame] | 40 | #include <wtf/DataLog.h> |
andersca@apple.com | 3d185a8 | 2013-09-07 18:04:57 +0000 | [diff] [blame] | 41 | #include <wtf/FastMalloc.h> |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 42 | #include <wtf/Noncopyable.h> |
| 43 | |
| 44 | namespace JSC { |
| 45 | |
keith_miller@apple.com | 8e7bd48 | 2019-10-01 16:38:26 +0000 | [diff] [blame] | 46 | namespace Wasm { |
| 47 | enum class CompilationMode : uint8_t; |
| 48 | } |
| 49 | |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 50 | class CodeBlock; |
oliver@apple.com | 7e98c92 | 2011-05-27 18:30:08 +0000 | [diff] [blame] | 51 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 52 | // LinkBuffer: |
| 53 | // |
| 54 | // This class assists in linking code generated by the macro assembler, once code generation |
| 55 | // has been completed, and the code has been copied to is final location in memory. At this |
| 56 | // time pointers to labels within the code may be resolved, and relative offsets to external |
| 57 | // addresses may be fixed. |
| 58 | // |
| 59 | // Specifically: |
| 60 | // * Jump objects may be linked to external targets, |
| 61 | // * The address of Jump objects may taken, such that it can later be relinked. |
| 62 | // * The return address of a Call may be acquired. |
| 63 | // * The address of a Label pointing into the code may be resolved. |
| 64 | // * The value referenced by a DataLabel may be set. |
| 65 | // |
ossy@webkit.org | 95c1bc4 | 2011-01-20 16:30:54 +0000 | [diff] [blame] | 66 | class LinkBuffer { |
oliver@apple.com | 90fce82 | 2013-07-25 04:00:13 +0000 | [diff] [blame] | 67 | WTF_MAKE_NONCOPYABLE(LinkBuffer); WTF_MAKE_FAST_ALLOCATED; |
| 68 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 69 | template<PtrTag tag> using CodePtr = MacroAssemblerCodePtr<tag>; |
| 70 | template<PtrTag tag> using CodeRef = MacroAssemblerCodeRef<tag>; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 71 | typedef MacroAssembler::Label Label; |
| 72 | typedef MacroAssembler::Jump Jump; |
barraclough@apple.com | 959b92e | 2012-04-25 00:06:04 +0000 | [diff] [blame] | 73 | typedef MacroAssembler::PatchableJump PatchableJump; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 74 | typedef MacroAssembler::JumpList JumpList; |
| 75 | typedef MacroAssembler::Call Call; |
oliver@apple.com | 2c012fa | 2011-05-17 20:02:41 +0000 | [diff] [blame] | 76 | typedef MacroAssembler::DataLabelCompact DataLabelCompact; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 77 | typedef MacroAssembler::DataLabel32 DataLabel32; |
| 78 | typedef MacroAssembler::DataLabelPtr DataLabelPtr; |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 79 | typedef MacroAssembler::ConvertibleLoadLabel ConvertibleLoadLabel; |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 80 | #if ENABLE(BRANCH_COMPACTION) |
| 81 | typedef MacroAssembler::LinkRecord LinkRecord; |
| 82 | typedef MacroAssembler::JumpLinkType JumpLinkType; |
| 83 | #endif |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 84 | |
| 85 | public: |
sbarati@apple.com | 893729f | 2017-03-29 22:55:53 +0000 | [diff] [blame] | 86 | LinkBuffer(MacroAssembler& macroAssembler, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed) |
fpizlo@apple.com | e6a7f5f | 2011-09-11 05:49:36 +0000 | [diff] [blame] | 87 | : m_size(0) |
fpizlo@apple.com | a26c904 | 2013-10-20 02:07:39 +0000 | [diff] [blame] | 88 | , m_didAllocate(false) |
barraclough@apple.com | e00c8ce | 2011-04-30 23:59:17 +0000 | [diff] [blame] | 89 | #ifndef NDEBUG |
| 90 | , m_completed(false) |
| 91 | #endif |
| 92 | { |
benjamin@webkit.org | f766fd9 | 2014-07-08 04:23:30 +0000 | [diff] [blame] | 93 | linkCode(macroAssembler, ownerUID, effort); |
barraclough@apple.com | e00c8ce | 2011-04-30 23:59:17 +0000 | [diff] [blame] | 94 | } |
| 95 | |
mark.lam@apple.com | de1e15f | 2018-04-30 22:29:21 +0000 | [diff] [blame] | 96 | template<PtrTag tag> |
| 97 | LinkBuffer(MacroAssembler& macroAssembler, MacroAssemblerCodePtr<tag> code, size_t size, JITCompilationEffort effort = JITCompilationMustSucceed, bool shouldPerformBranchCompaction = true) |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 98 | : m_size(size) |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 99 | , m_didAllocate(false) |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 100 | #ifndef NDEBUG |
| 101 | , m_completed(false) |
| 102 | #endif |
rmorisset@apple.com | 4ccbcf1 | 2019-03-12 19:07:04 +0000 | [diff] [blame] | 103 | , m_code(code.template retagged<LinkBufferPtrTag>()) |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 104 | { |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 105 | #if ENABLE(BRANCH_COMPACTION) |
| 106 | m_shouldPerformBranchCompaction = shouldPerformBranchCompaction; |
| 107 | #else |
| 108 | UNUSED_PARAM(shouldPerformBranchCompaction); |
| 109 | #endif |
oliver@apple.com | 89b03a6 | 2016-03-09 00:08:53 +0000 | [diff] [blame] | 110 | linkCode(macroAssembler, 0, effort); |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 111 | } |
| 112 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 113 | ~LinkBuffer() |
| 114 | { |
fpizlo@apple.com | 0f25ee8 | 2012-03-01 05:46:20 +0000 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | bool didFailToAllocate() const |
| 118 | { |
fpizlo@apple.com | a26c904 | 2013-10-20 02:07:39 +0000 | [diff] [blame] | 119 | return !m_didAllocate; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 120 | } |
| 121 | |
fpizlo@apple.com | 0f25ee8 | 2012-03-01 05:46:20 +0000 | [diff] [blame] | 122 | bool isValid() const |
| 123 | { |
| 124 | return !didFailToAllocate(); |
| 125 | } |
| 126 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 127 | // These methods are used to link or set values at code generation time. |
| 128 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 129 | template<PtrTag tag, typename Func, typename = std::enable_if_t<std::is_function<typename std::remove_pointer<Func>::type>::value>> |
| 130 | void link(Call call, Func funcName) |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 131 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 132 | FunctionPtr<tag> function(funcName); |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 133 | link(call, function); |
| 134 | } |
| 135 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 136 | template<PtrTag tag> |
| 137 | void link(Call call, FunctionPtr<tag> function) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 138 | { |
| 139 | ASSERT(call.isFlagSet(Call::Linkable)); |
barraclough@apple.com | 0d15b9e | 2011-05-26 04:12:41 +0000 | [diff] [blame] | 140 | call.m_label = applyOffset(call.m_label); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 141 | MacroAssembler::linkCall(code(), call, function); |
| 142 | } |
| 143 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 144 | template<PtrTag tag> |
| 145 | void link(Call call, CodeLocationLabel<tag> label) |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 146 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 147 | link(call, FunctionPtr<tag>(label)); |
fpizlo@apple.com | 2e7ada0 | 2013-10-23 18:22:09 +0000 | [diff] [blame] | 148 | } |
| 149 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 150 | template<PtrTag tag> |
| 151 | void link(Jump jump, CodeLocationLabel<tag> label) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 152 | { |
barraclough@apple.com | 0d15b9e | 2011-05-26 04:12:41 +0000 | [diff] [blame] | 153 | jump.m_label = applyOffset(jump.m_label); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 154 | MacroAssembler::linkJump(code(), jump, label); |
| 155 | } |
| 156 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 157 | template<PtrTag tag> |
| 158 | void link(const JumpList& list, CodeLocationLabel<tag> label) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 159 | { |
commit-queue@webkit.org | 8f20787 | 2016-04-19 06:54:25 +0000 | [diff] [blame] | 160 | for (const Jump& jump : list.jumps()) |
| 161 | link(jump, label); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | void patch(DataLabelPtr label, void* value) |
| 165 | { |
barraclough@apple.com | 4836c7a | 2011-05-01 22:20:59 +0000 | [diff] [blame] | 166 | AssemblerLabel target = applyOffset(label.m_label); |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 167 | MacroAssembler::linkPointer(code(), target, value); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 168 | } |
| 169 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 170 | template<PtrTag tag> |
| 171 | void patch(DataLabelPtr label, CodeLocationLabel<tag> value) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 172 | { |
barraclough@apple.com | 4836c7a | 2011-05-01 22:20:59 +0000 | [diff] [blame] | 173 | AssemblerLabel target = applyOffset(label.m_label); |
mark.lam@apple.com | 2cd487f | 2017-11-30 23:47:35 +0000 | [diff] [blame] | 174 | MacroAssembler::linkPointer(code(), target, value); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | // These methods are used to obtain handles to allow the code to be relinked / repatched later. |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 178 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 179 | template<PtrTag tag> |
| 180 | CodeLocationLabel<tag> entrypoint() |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 181 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 182 | return CodeLocationLabel<tag>(tagCodePtr<tag>(code())); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 183 | } |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 184 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 185 | template<PtrTag tag> |
| 186 | CodeLocationCall<tag> locationOf(Call call) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 187 | { |
| 188 | ASSERT(call.isFlagSet(Call::Linkable)); |
| 189 | ASSERT(!call.isFlagSet(Call::Near)); |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 190 | return CodeLocationCall<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(call.m_label))); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 191 | } |
| 192 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 193 | template<PtrTag tag> |
| 194 | CodeLocationNearCall<tag> locationOfNearCall(Call call) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 195 | { |
| 196 | ASSERT(call.isFlagSet(Call::Linkable)); |
| 197 | ASSERT(call.isFlagSet(Call::Near)); |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 198 | return CodeLocationNearCall<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(call.m_label)), |
msaboff@apple.com | c15ae7e | 2015-09-16 23:40:35 +0000 | [diff] [blame] | 199 | call.isFlagSet(Call::Tail) ? NearCallMode::Tail : NearCallMode::Regular); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 200 | } |
| 201 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 202 | template<PtrTag tag> |
| 203 | CodeLocationLabel<tag> locationOf(PatchableJump jump) |
barraclough@apple.com | 03571d7 | 2011-11-08 23:45:05 +0000 | [diff] [blame] | 204 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 205 | return CodeLocationLabel<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(jump.m_jump.m_label))); |
barraclough@apple.com | 03571d7 | 2011-11-08 23:45:05 +0000 | [diff] [blame] | 206 | } |
| 207 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 208 | template<PtrTag tag> |
| 209 | CodeLocationLabel<tag> locationOf(Label label) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 210 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 211 | return CodeLocationLabel<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(label.m_label))); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 212 | } |
| 213 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 214 | template<PtrTag tag> |
| 215 | CodeLocationDataLabelPtr<tag> locationOf(DataLabelPtr label) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 216 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 217 | return CodeLocationDataLabelPtr<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(label.m_label))); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 218 | } |
| 219 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 220 | template<PtrTag tag> |
| 221 | CodeLocationDataLabel32<tag> locationOf(DataLabel32 label) |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 222 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 223 | return CodeLocationDataLabel32<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(label.m_label))); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 224 | } |
oliver@apple.com | 2c012fa | 2011-05-17 20:02:41 +0000 | [diff] [blame] | 225 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 226 | template<PtrTag tag> |
| 227 | CodeLocationDataLabelCompact<tag> locationOf(DataLabelCompact label) |
oliver@apple.com | 2c012fa | 2011-05-17 20:02:41 +0000 | [diff] [blame] | 228 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 229 | return CodeLocationDataLabelCompact<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(label.m_label))); |
oliver@apple.com | 2c012fa | 2011-05-17 20:02:41 +0000 | [diff] [blame] | 230 | } |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 231 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 232 | template<PtrTag tag> |
| 233 | CodeLocationConvertibleLoad<tag> locationOf(ConvertibleLoadLabel label) |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 234 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 235 | return CodeLocationConvertibleLoad<tag>(MacroAssembler::getLinkerAddress<tag>(code(), applyOffset(label.m_label))); |
fpizlo@apple.com | d68b1f8 | 2012-07-05 22:55:51 +0000 | [diff] [blame] | 236 | } |
| 237 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 238 | // This method obtains the return address of the call, given as an offset from |
| 239 | // the start of the code. |
| 240 | unsigned returnAddressOffset(Call call) |
| 241 | { |
barraclough@apple.com | 0d15b9e | 2011-05-26 04:12:41 +0000 | [diff] [blame] | 242 | call.m_label = applyOffset(call.m_label); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 243 | return MacroAssembler::getLinkerCallReturnOffset(call); |
| 244 | } |
| 245 | |
barraclough@apple.com | 13b3806 | 2011-11-09 00:43:15 +0000 | [diff] [blame] | 246 | uint32_t offsetOf(Label label) |
| 247 | { |
| 248 | return applyOffset(label.m_label).m_offset; |
| 249 | } |
| 250 | |
oliver@apple.com | ea77149 | 2013-07-25 03:58:38 +0000 | [diff] [blame] | 251 | unsigned offsetOf(PatchableJump jump) |
| 252 | { |
| 253 | return applyOffset(jump.m_jump.m_label).m_offset; |
| 254 | } |
| 255 | |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 256 | // Upon completion of all patching 'FINALIZE_CODE()' should be called once to |
| 257 | // complete generation of the code. Alternatively, call |
| 258 | // finalizeCodeWithoutDisassembly() directly if you have your own way of |
| 259 | // displaying disassembly. |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 260 | |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 261 | template<PtrTag tag> |
| 262 | CodeRef<tag> finalizeCodeWithoutDisassembly() |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 263 | { |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 264 | return finalizeCodeWithoutDisassemblyImpl().template retagged<tag>(); |
| 265 | } |
| 266 | |
| 267 | template<PtrTag tag, typename... Args> |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 268 | CodeRef<tag> finalizeCodeWithDisassembly(bool dumpDisassembly, const char* format, Args... args) |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 269 | { |
guijemont@igalia.com | 65db7e4 | 2018-09-12 15:09:16 +0000 | [diff] [blame] | 270 | ALLOW_NONLITERAL_FORMAT_BEGIN |
| 271 | IGNORE_WARNINGS_BEGIN("format-security") |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 272 | return finalizeCodeWithDisassemblyImpl(dumpDisassembly, format, args...).template retagged<tag>(); |
guijemont@igalia.com | 65db7e4 | 2018-09-12 15:09:16 +0000 | [diff] [blame] | 273 | IGNORE_WARNINGS_END |
| 274 | ALLOW_NONLITERAL_FORMAT_END |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 275 | } |
| 276 | |
| 277 | template<PtrTag tag> |
| 278 | CodePtr<tag> trampolineAt(Label label) |
| 279 | { |
| 280 | return CodePtr<tag>(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label))); |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 281 | } |
| 282 | |
barraclough@apple.com | 9cb663d | 2011-04-15 00:25:59 +0000 | [diff] [blame] | 283 | void* debugAddress() |
| 284 | { |
mark.lam@apple.com | de1e15f | 2018-04-30 22:29:21 +0000 | [diff] [blame] | 285 | return m_code.dataLocation(); |
barraclough@apple.com | 9cb663d | 2011-04-15 00:25:59 +0000 | [diff] [blame] | 286 | } |
benjamin@webkit.org | f6de077 | 2014-07-15 23:59:14 +0000 | [diff] [blame] | 287 | |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 288 | size_t size() const { return m_size; } |
fpizlo@apple.com | 32622c9 | 2015-03-24 05:37:19 +0000 | [diff] [blame] | 289 | |
| 290 | bool wasAlreadyDisassembled() const { return m_alreadyDisassembled; } |
| 291 | void didAlreadyDisassemble() { m_alreadyDisassembled = true; } |
barraclough@apple.com | 9cb663d | 2011-04-15 00:25:59 +0000 | [diff] [blame] | 292 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 293 | private: |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 294 | JS_EXPORT_PRIVATE CodeRef<LinkBufferPtrTag> finalizeCodeWithoutDisassemblyImpl(); |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 295 | JS_EXPORT_PRIVATE CodeRef<LinkBufferPtrTag> finalizeCodeWithDisassemblyImpl(bool dumpDisassembly, const char* format, ...) WTF_ATTRIBUTE_PRINTF(3, 4); |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 296 | |
fpizlo@apple.com | 00593b2 | 2014-02-22 19:55:12 +0000 | [diff] [blame] | 297 | #if ENABLE(BRANCH_COMPACTION) |
| 298 | int executableOffsetFor(int location) |
| 299 | { |
guijemont@igalia.com | 99ff59a | 2018-06-20 17:16:21 +0000 | [diff] [blame] | 300 | // Returning 0 in this case works because at location < |
| 301 | // sizeof(int32_t), no compaction could have happened before this |
| 302 | // point as the assembler could not have placed a branch instruction |
| 303 | // within this space that required compaction. |
| 304 | if (location < static_cast<int>(sizeof(int32_t))) |
fpizlo@apple.com | 00593b2 | 2014-02-22 19:55:12 +0000 | [diff] [blame] | 305 | return 0; |
benjamin@webkit.org | f6de077 | 2014-07-15 23:59:14 +0000 | [diff] [blame] | 306 | return bitwise_cast<int32_t*>(m_assemblerStorage.buffer())[location / sizeof(int32_t) - 1]; |
fpizlo@apple.com | 00593b2 | 2014-02-22 19:55:12 +0000 | [diff] [blame] | 307 | } |
| 308 | #endif |
| 309 | |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 310 | template <typename T> T applyOffset(T src) |
| 311 | { |
| 312 | #if ENABLE(BRANCH_COMPACTION) |
fpizlo@apple.com | 00593b2 | 2014-02-22 19:55:12 +0000 | [diff] [blame] | 313 | src.m_offset -= executableOffsetFor(src.m_offset); |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 314 | #endif |
| 315 | return src; |
| 316 | } |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 317 | |
barraclough@apple.com | b6a00d3 | 2012-01-23 21:08:34 +0000 | [diff] [blame] | 318 | // Keep this private! - the underlying code should only be obtained externally via finalizeCode(). |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 319 | void* code() |
| 320 | { |
mark.lam@apple.com | de1e15f | 2018-04-30 22:29:21 +0000 | [diff] [blame] | 321 | return m_code.dataLocation(); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 322 | } |
fpizlo@apple.com | a26c904 | 2013-10-20 02:07:39 +0000 | [diff] [blame] | 323 | |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 324 | void allocate(MacroAssembler&, void* ownerUID, JITCompilationEffort); |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 325 | |
benjamin@webkit.org | f766fd9 | 2014-07-08 04:23:30 +0000 | [diff] [blame] | 326 | JS_EXPORT_PRIVATE void linkCode(MacroAssembler&, void* ownerUID, JITCompilationEffort); |
dbates@webkit.org | 98f0de0 | 2013-10-15 22:16:39 +0000 | [diff] [blame] | 327 | #if ENABLE(BRANCH_COMPACTION) |
| 328 | template <typename InstructionType> |
benjamin@webkit.org | f766fd9 | 2014-07-08 04:23:30 +0000 | [diff] [blame] | 329 | void copyCompactAndLinkCode(MacroAssembler&, void* ownerUID, JITCompilationEffort); |
dbates@webkit.org | 98f0de0 | 2013-10-15 22:16:39 +0000 | [diff] [blame] | 330 | #endif |
oliver@apple.com | 2d5480d | 2010-08-10 03:19:19 +0000 | [diff] [blame] | 331 | |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 332 | void performFinalization(); |
ggaren@apple.com | aa701ef | 2010-10-14 19:19:17 +0000 | [diff] [blame] | 333 | |
| 334 | #if DUMP_LINK_STATISTICS |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 335 | static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize); |
ggaren@apple.com | aa701ef | 2010-10-14 19:19:17 +0000 | [diff] [blame] | 336 | #endif |
| 337 | |
| 338 | #if DUMP_CODE |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 339 | static void dumpCode(void* code, size_t); |
ggaren@apple.com | aa701ef | 2010-10-14 19:19:17 +0000 | [diff] [blame] | 340 | #endif |
| 341 | |
fpizlo@apple.com | e6a7f5f | 2011-09-11 05:49:36 +0000 | [diff] [blame] | 342 | RefPtr<ExecutableMemoryHandle> m_executableMemory; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 343 | size_t m_size; |
commit-queue@webkit.org | f2566dc | 2012-02-10 23:01:54 +0000 | [diff] [blame] | 344 | #if ENABLE(BRANCH_COMPACTION) |
benjamin@webkit.org | f6de077 | 2014-07-15 23:59:14 +0000 | [diff] [blame] | 345 | AssemblerData m_assemblerStorage; |
sbarati@apple.com | b5bee81 | 2016-06-19 19:42:18 +0000 | [diff] [blame] | 346 | bool m_shouldPerformBranchCompaction { true }; |
commit-queue@webkit.org | f2566dc | 2012-02-10 23:01:54 +0000 | [diff] [blame] | 347 | #endif |
fpizlo@apple.com | a26c904 | 2013-10-20 02:07:39 +0000 | [diff] [blame] | 348 | bool m_didAllocate; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 349 | #ifndef NDEBUG |
barraclough@apple.com | ce1490e | 2010-08-26 23:21:24 +0000 | [diff] [blame] | 350 | bool m_completed; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 351 | #endif |
fpizlo@apple.com | 32622c9 | 2015-03-24 05:37:19 +0000 | [diff] [blame] | 352 | bool m_alreadyDisassembled { false }; |
rmorisset@apple.com | 4ccbcf1 | 2019-03-12 19:07:04 +0000 | [diff] [blame] | 353 | MacroAssemblerCodePtr<LinkBufferPtrTag> m_code; |
fpizlo@apple.com | 6e69796 | 2015-10-12 17:56:26 +0000 | [diff] [blame] | 354 | Vector<RefPtr<SharedTask<void(LinkBuffer&)>>> m_linkTasks; |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 355 | }; |
| 356 | |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 357 | #if OS(LINUX) |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 358 | #define FINALIZE_CODE_IF(condition, linkBufferReference, resultPtrTag, ...) \ |
fpizlo@apple.com | 12c1839 | 2012-06-27 23:16:10 +0000 | [diff] [blame] | 359 | (UNLIKELY((condition)) \ |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 360 | ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>(true, __VA_ARGS__) \ |
| 361 | : (UNLIKELY(JSC::Options::logJITCodeForPerf()) \ |
| 362 | ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>(false, __VA_ARGS__) \ |
| 363 | : (linkBufferReference).finalizeCodeWithoutDisassembly<resultPtrTag>())) |
| 364 | #else |
| 365 | #define FINALIZE_CODE_IF(condition, linkBufferReference, resultPtrTag, ...) \ |
| 366 | (UNLIKELY((condition)) \ |
| 367 | ? (linkBufferReference).finalizeCodeWithDisassembly<resultPtrTag>(true, __VA_ARGS__) \ |
mark.lam@apple.com | de0dba7 | 2018-04-18 03:31:09 +0000 | [diff] [blame] | 368 | : (linkBufferReference).finalizeCodeWithoutDisassembly<resultPtrTag>()) |
yusukesuzuki@slowstart.org | 8735b84 | 2018-10-05 19:59:04 +0000 | [diff] [blame] | 369 | #endif |
fpizlo@apple.com | 12c1839 | 2012-06-27 23:16:10 +0000 | [diff] [blame] | 370 | |
mark.lam@apple.com | ee3c410 | 2015-10-14 18:57:07 +0000 | [diff] [blame] | 371 | bool shouldDumpDisassemblyFor(CodeBlock*); |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 372 | |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 373 | #define FINALIZE_CODE_FOR(codeBlock, linkBufferReference, resultPtrTag, ...) \ |
| 374 | FINALIZE_CODE_IF((shouldDumpDisassemblyFor(codeBlock) || Options::asyncDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__) |
msaboff@apple.com | 9589433 | 2014-01-29 19:18:54 +0000 | [diff] [blame] | 375 | |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 376 | // Use this to finalize code, like so: |
| 377 | // |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 378 | // CodeRef code = FINALIZE_CODE(linkBuffer, tag, "my super thingy number %d", number); |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 379 | // |
| 380 | // Which, in disassembly mode, will print: |
| 381 | // |
| 382 | // Generated JIT code for my super thingy number 42: |
| 383 | // Code at [0x123456, 0x234567]: |
| 384 | // 0x123456: mov $0, 0 |
| 385 | // 0x12345a: ret |
| 386 | // |
| 387 | // ... and so on. |
| 388 | // |
mark.lam@apple.com | 03313a9 | 2018-02-27 07:50:54 +0000 | [diff] [blame] | 389 | // Note that the format string and print arguments are only evaluated when dumpDisassembly |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 390 | // is true, so you can hide expensive disassembly-only computations inside there. |
| 391 | |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 392 | #define FINALIZE_CODE(linkBufferReference, resultPtrTag, ...) \ |
| 393 | FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__) |
fpizlo@apple.com | 2adf527 | 2012-06-20 01:33:30 +0000 | [diff] [blame] | 394 | |
mark.lam@apple.com | e1fc7a0 | 2018-03-14 20:05:37 +0000 | [diff] [blame] | 395 | #define FINALIZE_DFG_CODE(linkBufferReference, resultPtrTag, ...) \ |
| 396 | FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpDFGDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__) |
fpizlo@apple.com | 57fb54d | 2012-09-21 23:29:30 +0000 | [diff] [blame] | 397 | |
yusukesuzuki@slowstart.org | e8dd310 | 2018-08-21 03:29:32 +0000 | [diff] [blame] | 398 | #define FINALIZE_REGEXP_CODE(linkBufferReference, resultPtrTag, dataLogFArgumentsForHeading) \ |
| 399 | FINALIZE_CODE_IF(JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpRegExpDisassembly(), linkBufferReference, resultPtrTag, dataLogFArgumentsForHeading) |
| 400 | |
keith_miller@apple.com | 8e7bd48 | 2019-10-01 16:38:26 +0000 | [diff] [blame] | 401 | bool shouldDumpDisassemblyFor(Wasm::CompilationMode); |
| 402 | |
| 403 | #define FINALIZE_WASM_CODE(linkBufferReference, resultPtrTag, ...) \ |
| 404 | FINALIZE_CODE_IF((JSC::Options::asyncDisassembly() || JSC::Options::dumpDisassembly() || Options::dumpWasmDisassembly()), linkBufferReference, resultPtrTag, __VA_ARGS__) |
| 405 | |
| 406 | #define FINALIZE_WASM_CODE_FOR_MODE(mode, linkBufferReference, resultPtrTag, ...) \ |
| 407 | FINALIZE_CODE_IF(shouldDumpDisassemblyFor(mode), linkBufferReference, resultPtrTag, __VA_ARGS__) |
| 408 | |
| 409 | |
| 410 | |
barraclough@apple.com | ba92ede | 2009-07-22 00:37:03 +0000 | [diff] [blame] | 411 | } // namespace JSC |
| 412 | |
| 413 | #endif // ENABLE(ASSEMBLER) |