OpenCoverage

LinkBuffer.h

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/3rdparty/masm/assembler/LinkBuffer.h
Source codeSwitch to Preprocessed file
LineSourceCount
1/*-
2 * Copyright (C) 2009, 2010, 2012 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#ifndef LinkBuffer_h-
27#define LinkBuffer_h-
28-
29#if ENABLE(ASSEMBLER)-
30-
31#define DUMP_LINK_STATISTICS 0-
32#define DUMP_CODE 0-
33-
34#define GLOBAL_THUNK_ID reinterpret_cast<void*>(static_cast<intptr_t>(-1))-
35#define REGEXP_CODE_ID reinterpret_cast<void*>(static_cast<intptr_t>(-2))-
36-
37#include "JITCompilationEffort.h"-
38#include "MacroAssembler.h"-
39#include "Options.h"-
40#include <wtf/DataLog.h>-
41#include <wtf/Noncopyable.h>-
42-
43namespace JSC {-
44-
45class JSGlobalData;-
46-
47template <typename T>-
48struct DefaultExecutableOffsetCalculator {-
49 template <typename Assembler>-
50 static T applyOffset(Assembler *, T src) { return src; }
executed 1224 times by 10 tests: return src;
Executed by:
  • tst_ecmascripttests
  • tst_qjsengine
  • tst_qqmlecmascript
  • tst_qqmllistmodelworkerscript
  • tst_qqmlxmlhttprequest
  • tst_qquickanimationcontroller
  • tst_qquicklayouts
  • tst_qquicktextinput
  • tst_qquickworkerscript
  • tst_testfiltering
1224
51};-
52-
53// LinkBuffer:-
54//-
55// This class assists in linking code generated by the macro assembler, once code generation-
56// has been completed, and the code has been copied to is final location in memory. At this-
57// time pointers to labels within the code may be resolved, and relative offsets to external-
58// addresses may be fixed.-
59//-
60// Specifically:-
61// * Jump objects may be linked to external targets,-
62// * The address of Jump objects may taken, such that it can later be relinked.-
63// * The return address of a Call may be acquired.-
64// * The address of a Label pointing into the code may be resolved.-
65// * The value referenced by a DataLabel may be set.-
66//-
67template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>-
68class LinkBufferBase {-
69 WTF_MAKE_NONCOPYABLE(LinkBufferBase);-
70 typedef MacroAssemblerCodeRef CodeRef;-
71 typedef MacroAssemblerCodePtr CodePtr;-
72 typedef typename MacroAssembler::Label Label;-
73 typedef typename MacroAssembler::Jump Jump;-
74 typedef typename MacroAssembler::PatchableJump PatchableJump;-
75 typedef typename MacroAssembler::JumpList JumpList;-
76 typedef typename MacroAssembler::Call Call;-
77 typedef typename MacroAssembler::DataLabelCompact DataLabelCompact;-
78 typedef typename MacroAssembler::DataLabel32 DataLabel32;-
79 typedef typename MacroAssembler::DataLabelPtr DataLabelPtr;-
80 typedef typename MacroAssembler::ConvertibleLoadLabel ConvertibleLoadLabel;-
81-
82public:-
83 LinkBufferBase(JSGlobalData& globalData, MacroAssembler* masm, JITCompilationEffort effort = JITCompilationMustSucceed)-
84 : m_size(0)-
85 , m_code(0)-
86 , m_assembler(masm)-
87 , m_globalData(&globalData)-
88#ifndef NDEBUG-
89 , m_completed(false)-
90 , m_effort(effort)-
91#endif-
92 {-
93#ifdef NDEBUG-
94 UNUSED_PARAM(effort)-
95#endif-
96 // Simon: Moved this to the sub-classes linkCode(ownerUID, effort);-
97 }
executed 1161222 times by 153 tests: end of block
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1161222
98-
99 ~LinkBufferBase()-
100 {-
101 ASSERT(m_completed || (!m_executableMemory && m_effort == JITCompilationCanFail));-
102 }
executed 1164529 times by 153 tests: end of block
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1164529
103 -
104 bool didFailToAllocate() const-
105 {-
106 return !m_executableMemory;
executed 1163931 times by 153 tests: return !m_executableMemory;
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1163931
107 }-
108-
109 bool isValid() const-
110 {-
111 return !didFailToAllocate();
executed 1163921 times by 153 tests: return !didFailToAllocate();
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1163921
112 }-
113 -
114 // These methods are used to link or set values at code generation time.-
115-
116 void link(Call call, FunctionPtr function)-
117 {-
118 ASSERT(call.isFlagSet(Call::Linkable));-
119 call.m_label = applyOffset(call.m_label);-
120 MacroAssembler::linkCall(code(), call, function);-
121 }
never executed: end of block
0
122 -
123 void link(Jump jump, CodeLocationLabel label)-
124 {-
125 jump.m_label = applyOffset(jump.m_label);-
126 MacroAssembler::linkJump(code(), jump, label);-
127 }
never executed: end of block
0
128-
129 void link(JumpList list, CodeLocationLabel label)-
130 {-
131 for (unsigned i = 0; i < list.m_jumps.size(); ++i)
i < list.m_jumps.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
132 link(list.m_jumps[i], label);
never executed: link(list.m_jumps[i], label);
0
133 }
never executed: end of block
0
134-
135 void patch(DataLabelPtr label, void* value)-
136 {-
137 AssemblerLabel target = applyOffset(label.m_label);-
138 MacroAssembler::linkPointer(code(), target, value);-
139 }
never executed: end of block
0
140-
141 void patch(DataLabelPtr label, CodeLocationLabel value)-
142 {-
143 AssemblerLabel target = applyOffset(label.m_label);-
144 MacroAssembler::linkPointer(code(), target, value.executableAddress());-
145 }
executed 612 times by 10 tests: end of block
Executed by:
  • tst_ecmascripttests
  • tst_qjsengine
  • tst_qqmlecmascript
  • tst_qqmllistmodelworkerscript
  • tst_qqmlxmlhttprequest
  • tst_qquickanimationcontroller
  • tst_qquicklayouts
  • tst_qquicktextinput
  • tst_qquickworkerscript
  • tst_testfiltering
612
146-
147 // These methods are used to obtain handles to allow the code to be relinked / repatched later.-
148-
149 CodeLocationCall locationOf(Call call)-
150 {-
151 ASSERT(call.isFlagSet(Call::Linkable));-
152 ASSERT(!call.isFlagSet(Call::Near));-
153 return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
never executed: return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
0
154 }-
155-
156 CodeLocationNearCall locationOfNearCall(Call call)-
157 {-
158 ASSERT(call.isFlagSet(Call::Linkable));-
159 ASSERT(call.isFlagSet(Call::Near));-
160 return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
never executed: return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
0
161 }-
162-
163 CodeLocationLabel locationOf(PatchableJump jump)-
164 {-
165 return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(jump.m_jump.m_label)));
never executed: return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(jump.m_jump.m_label)));
0
166 }-
167-
168 CodeLocationLabel locationOf(Label label)-
169 {-
170 return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
executed 612 times by 10 tests: return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
Executed by:
  • tst_ecmascripttests
  • tst_qjsengine
  • tst_qqmlecmascript
  • tst_qqmllistmodelworkerscript
  • tst_qqmlxmlhttprequest
  • tst_qquickanimationcontroller
  • tst_qquicklayouts
  • tst_qquicktextinput
  • tst_qquickworkerscript
  • tst_testfiltering
612
171 }-
172-
173 CodeLocationDataLabelPtr locationOf(DataLabelPtr label)-
174 {-
175 return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
never executed: return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
0
176 }-
177-
178 CodeLocationDataLabel32 locationOf(DataLabel32 label)-
179 {-
180 return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
never executed: return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
0
181 }-
182 -
183 CodeLocationDataLabelCompact locationOf(DataLabelCompact label)-
184 {-
185 return CodeLocationDataLabelCompact(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
never executed: return CodeLocationDataLabelCompact(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
0
186 }-
187-
188 CodeLocationConvertibleLoad locationOf(ConvertibleLoadLabel label)-
189 {-
190 return CodeLocationConvertibleLoad(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
never executed: return CodeLocationConvertibleLoad(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label)));
0
191 }-
192-
193 // This method obtains the return address of the call, given as an offset from-
194 // the start of the code.-
195 unsigned returnAddressOffset(Call call)-
196 {-
197 call.m_label = applyOffset(call.m_label);-
198 return MacroAssembler::getLinkerCallReturnOffset(call);
never executed: return MacroAssembler::getLinkerCallReturnOffset(call);
0
199 }-
200-
201 uint32_t offsetOf(Label label)-
202 {-
203 return applyOffset(label.m_label).m_offset;
never executed: return applyOffset(label.m_label).m_offset;
0
204 }-
205-
206 // Upon completion of all patching 'FINALIZE_CODE()' should be called once to-
207 // complete generation of the code. Alternatively, call-
208 // finalizeCodeWithoutDisassembly() directly if you have your own way of-
209 // displaying disassembly.-
210 -
211 inline CodeRef finalizeCodeWithoutDisassembly();-
212 inline CodeRef finalizeCodeWithDisassembly(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);-
213-
214 CodePtr trampolineAt(Label label)-
215 {-
216 return CodePtr(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label)));
never executed: return CodePtr(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label)));
0
217 }-
218-
219 void* debugAddress()-
220 {-
221 return m_code;
never executed: return m_code;
0
222 }-
223 -
224 size_t debugSize()-
225 {-
226 return m_size;
never executed: return m_size;
0
227 }-
228-
229private:-
230 template <typename T> T applyOffset(T src)-
231 {-
232 return ExecutableOffsetCalculator<T>::applyOffset(m_assembler, src);
executed 1224 times by 10 tests: return ExecutableOffsetCalculator<T>::applyOffset(m_assembler, src);
Executed by:
  • tst_ecmascripttests
  • tst_qjsengine
  • tst_qqmlecmascript
  • tst_qqmllistmodelworkerscript
  • tst_qqmlxmlhttprequest
  • tst_qquickanimationcontroller
  • tst_qquicklayouts
  • tst_qquicktextinput
  • tst_qquickworkerscript
  • tst_testfiltering
1224
233 }-
234 -
235protected:-
236 // Keep this private! - the underlying code should only be obtained externally via finalizeCode().-
237 void* code()-
238 {-
239 return m_code;
executed 2329074 times by 153 tests: return m_code;
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
2329074
240 }-
241-
242 inline void linkCode(void* ownerUID, JITCompilationEffort);-
243-
244 inline void performFinalization();-
245-
246#if DUMP_LINK_STATISTICS-
247 static void dumpLinkStatistics(void* code, size_t initialSize, size_t finalSize);-
248#endif-
249 -
250#if DUMP_CODE-
251 static void dumpCode(void* code, size_t);-
252#endif-
253 -
254 RefPtr<ExecutableMemoryHandle> m_executableMemory;-
255 size_t m_size;-
256 void* m_code;-
257 MacroAssembler* m_assembler;-
258 JSGlobalData* m_globalData;-
259protected:-
260#ifndef NDEBUG-
261 bool m_completed;-
262 JITCompilationEffort m_effort;-
263#endif-
264};-
265-
266#define FINALIZE_CODE_IF(condition, linkBufferReference, dataLogFArgumentsForHeading) \-
267 (UNLIKELY((condition)) \-
268 ? ((linkBufferReference).finalizeCodeWithDisassembly dataLogFArgumentsForHeading) \-
269 : (linkBufferReference).finalizeCodeWithoutDisassembly())-
270-
271// Use this to finalize code, like so:-
272//-
273// CodeRef code = FINALIZE_CODE(linkBuffer, ("my super thingy number %d", number));-
274//-
275// Which, in disassembly mode, will print:-
276//-
277// Generated JIT code for my super thingy number 42:-
278// Code at [0x123456, 0x234567]:-
279// 0x123456: mov $0, 0-
280// 0x12345a: ret-
281//-
282// ... and so on.-
283//-
284// Note that the dataLogFArgumentsForHeading are only evaluated when showDisassembly-
285// is true, so you can hide expensive disassembly-only computations inside there.-
286-
287#define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading) \-
288 FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)-
289-
290#define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading) \-
291 FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)-
292-
293-
294template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>-
295inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithoutDisassembly()-
296{-
297 performFinalization();-
298-
299 return CodeRef(m_executableMemory);
executed 1164557 times by 153 tests: return CodeRef(m_executableMemory);
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1164557
300}-
301-
302template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>-
303inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::CodeRef LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::finalizeCodeWithDisassembly(const char* format, ...)-
304{-
305 ASSERT(Options::showDisassembly() || Options::showDFGDisassembly());-
306-
307 CodeRef result = finalizeCodeWithoutDisassembly();-
308-
309 dataLogF("Generated JIT code for ");-
310 va_list argList;-
311 va_start(argList, format);-
312 WTF::dataLogFV(format, argList);-
313 va_end(argList);-
314 dataLogF(":\n");-
315-
316 dataLogF(-
317#if OS(WINDOWS)-
318 " Code at [0x%p, 0x%p):\n",-
319#else-
320 " Code at [%p, %p):\n",-
321#endif-
322 result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());-
323 disassemble(result.code(), m_size, " ", WTF::dataFile());-
324-
325 return result;
never executed: return result;
0
326}-
327-
328template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>-
329inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::linkCode(void* ownerUID, JITCompilationEffort effort)-
330{-
331 UNUSED_PARAM(ownerUID)-
332 UNUSED_PARAM(effort)-
333 ASSERT(!m_code);-
334 m_executableMemory = m_assembler->m_assembler.executableCopy(*m_globalData, ownerUID, effort);-
335 if (!m_executableMemory)
!m_executableMemoryDescription
TRUEnever evaluated
FALSEevaluated 1163911 times by 153 tests
Evaluated by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
0-1163911
336 return;
never executed: return;
0
337 m_code = m_executableMemory->start();-
338 m_size = m_assembler->m_assembler.codeSize();-
339 ASSERT(m_code);-
340}
executed 1163909 times by 153 tests: end of block
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1163909
341-
342template <typename MacroAssembler, template <typename T> class ExecutableOffsetCalculator>-
343inline void LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::performFinalization()-
344{-
345 // NOTE: This function is specialized in LinkBuffer<MacroAssemblerARMv7>-
346#ifndef NDEBUG-
347 ASSERT(!m_completed);-
348 ASSERT(isValid());-
349 m_completed = true;-
350#endif-
351-
352 ASSERT(m_size <= INT_MAX);-
353 MacroAssembler::cacheFlush(code(), m_size);-
354 ExecutableAllocator::makeExecutable(code(), static_cast<int>(m_size));-
355}
executed 1164580 times by 153 tests: end of block
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1164580
356-
357template <typename MacroAssembler>-
358class LinkBuffer : public LinkBufferBase<MacroAssembler, DefaultExecutableOffsetCalculator>-
359{-
360public:-
361 LinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)-
362 : LinkBufferBase<MacroAssembler, DefaultExecutableOffsetCalculator>(globalData, masm, effort)-
363 {-
364 this->linkCode(ownerUID, effort);-
365 }
executed 1163976 times by 153 tests: end of block
Executed by:
  • tst_bindingdependencyapi
  • tst_drawingmodes
  • tst_ecmascripttests
  • tst_examples
  • tst_flickableinterop
  • tst_multipointtoucharea_interop
  • tst_parserstress
  • tst_qjsengine
  • tst_qjsonbinding
  • tst_qjsvalue
  • tst_qjsvalueiterator
  • tst_qmlcachegen
  • tst_qmldiskcache
  • tst_qqmlapplicationengine
  • tst_qqmlbinding
  • tst_qqmlcomponent
  • tst_qqmlconnections
  • tst_qqmlconsole
  • tst_qqmlcontext
  • tst_qqmldebugclient
  • tst_qqmldebugjs
  • tst_qqmldebuglocal
  • tst_qqmldebugservice
  • tst_qqmlecmascript
  • tst_qqmlenginecleanup
  • ...
1163976
366};-
367-
368#if CPU(ARM_THUMB2) || CPU(ARM64) || defined(V4_BOOTSTRAP)-
369-
370template <typename T>-
371struct BranchCompactingExecutableOffsetCalculator {-
372 template <typename Assembler>-
373 static T applyOffset(Assembler *as, T src) {-
374 src.m_offset -= as->executableOffsetFor(src.m_offset);-
375 return src;-
376 }-
377};-
378-
379template <typename MacroAssembler>-
380class BranchCompactingLinkBuffer : public LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>-
381{-
382public:-
383 BranchCompactingLinkBuffer(JSGlobalData& globalData, MacroAssembler* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)-
384 : LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>(globalData, masm, effort)-
385 {-
386 linkCode(ownerUID, effort);-
387 }-
388-
389 inline void performFinalization();-
390-
391 inline void linkCode(void* ownerUID, JITCompilationEffort);-
392-
393private:-
394 using Base = LinkBufferBase<MacroAssembler, BranchCompactingExecutableOffsetCalculator>;-
395#ifndef NDEBUG-
396 using Base::m_completed;-
397#endif-
398 using Base::isValid;-
399 using Base::code;-
400 using Base::m_code;-
401 using Base::m_size;-
402 using Base::m_assembler;-
403 using Base::m_executableMemory;-
404 using Base::m_globalData;-
405-
406 using LinkRecord = typename MacroAssembler::LinkRecord;-
407 using JumpLinkType = typename MacroAssembler::JumpLinkType;-
408-
409 size_t m_initialSize = 0;-
410};-
411-
412template <typename MacroAssembler>-
413inline void BranchCompactingLinkBuffer<MacroAssembler>::performFinalization()-
414{-
415#ifndef NDEBUG-
416 ASSERT(!m_completed);-
417 ASSERT(isValid());-
418 this->m_completed = true;-
419#endif-
420-
421 MacroAssembler::cacheFlush(code(), m_size);-
422 ExecutableAllocator::makeExecutable(code(), m_initialSize);-
423}-
424-
425template <typename MacroAssembler>-
426inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, JITCompilationEffort effort)-
427{-
428 UNUSED_PARAM(ownerUID)-
429 UNUSED_PARAM(effort)-
430 ASSERT(!m_code);-
431 m_initialSize = m_assembler->m_assembler.codeSize();-
432 m_executableMemory = m_globalData->executableAllocator.allocate(*m_globalData, m_initialSize, ownerUID, effort);-
433 if (!m_executableMemory)-
434 return;-
435 m_code = (uint8_t*)m_executableMemory->start();-
436 ASSERT(m_code);-
437 ExecutableAllocator::makeWritable(m_code, m_initialSize);-
438 uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode();-
439 uint8_t* outData = reinterpret_cast<uint8_t*>(m_code);-
440 int readPtr = 0;-
441 int writePtr = 0;-
442 Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink = m_assembler->jumpsToLink();-
443 unsigned jumpCount = unsigned(jumpsToLink.size());-
444 for (unsigned i = 0; i < jumpCount; ++i) {-
445 int offset = readPtr - writePtr;-
446 ASSERT(!(offset & 1));-
447-
448 // Copy the instructions from the last jump to the current one.-
449 unsigned regionSize = unsigned(jumpsToLink[i].from() - readPtr);-
450 uint16_t* copySource = reinterpret_cast_ptr<uint16_t*>(inData + readPtr);-
451 uint16_t* copyEnd = reinterpret_cast_ptr<uint16_t*>(inData + readPtr + regionSize);-
452 uint16_t* copyDst = reinterpret_cast_ptr<uint16_t*>(outData + writePtr);-
453 ASSERT(!(regionSize % 2));-
454 ASSERT(!(readPtr % 2));-
455 ASSERT(!(writePtr % 2));-
456 while (copySource != copyEnd)-
457 *copyDst++ = *copySource++;-
458 m_assembler->recordLinkOffsets(readPtr, jumpsToLink[i].from(), offset);-
459 readPtr += regionSize;-
460 writePtr += regionSize;-
461-
462 // Calculate absolute address of the jump target, in the case of backwards-
463 // branches we need to be precise, forward branches we are pessimistic-
464 const uint8_t* target;-
465 if (jumpsToLink[i].to() >= jumpsToLink[i].from())-
466 target = outData + jumpsToLink[i].to() - offset; // Compensate for what we have collapsed so far-
467 else-
468 target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());-
469-
470 JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], outData + writePtr, target);-
471 // Compact branch if we can...-
472 if (m_assembler->canCompact(jumpsToLink[i].type())) {-
473 // Step back in the write stream-
474 int32_t delta = m_assembler->jumpSizeDelta(jumpsToLink[i].type(), jumpLinkType);-
475 if (delta) {-
476 writePtr -= delta;-
477 m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr);-
478 }-
479 }-
480 jumpsToLink[i].setFrom(writePtr);-
481 }-
482 // Copy everything after the last jump-
483 memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr);-
484 m_assembler->recordLinkOffsets(readPtr, unsigned(m_initialSize), readPtr - writePtr);-
485-
486 for (unsigned i = 0; i < jumpCount; ++i) {-
487 uint8_t* location = outData + jumpsToLink[i].from();-
488 uint8_t* target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to());-
489 m_assembler->link(jumpsToLink[i], location, target);-
490 }-
491-
492 jumpsToLink.clear();-
493 m_size = writePtr + m_initialSize - readPtr;-
494 m_executableMemory->shrink(m_size);-
495}-
496-
497#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)-
498template <>-
499class LinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>> : public BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>>-
500{-
501public:-
502 LinkBuffer(JSGlobalData& globalData, JSC::MacroAssembler<MacroAssemblerARMv7>* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)-
503 : BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>>(globalData, masm, ownerUID, effort)-
504 {}-
505};-
506#endif-
507-
508#if CPU(ARM64) || defined(V4_BOOTSTRAP)-
509template <>-
510class LinkBuffer<JSC::MacroAssembler<MacroAssemblerARM64>> : public BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARM64>>-
511{-
512public:-
513 LinkBuffer(JSGlobalData& globalData, JSC::MacroAssembler<MacroAssemblerARM64>* masm, void* ownerUID, JITCompilationEffort effort = JITCompilationMustSucceed)-
514 : BranchCompactingLinkBuffer<JSC::MacroAssembler<JSC::MacroAssemblerARM64>>(globalData, masm, ownerUID, effort)-
515 {}-
516};-
517#endif-
518-
519#endif-
520-
521} // namespace JSC-
522-
523#endif // ENABLE(ASSEMBLER)-
524-
525#endif // LinkBuffer_h-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.0