source: webkit/trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h@ 73307

Last change on this file since 73307 was 73307, checked in by [email protected], 14 years ago

2010-12-03 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough

Changes to significantly reduce branches to branches in JIT'ed
parentheses backtrack processing. The changes include the following:

  • Taking the backtracking processing out of line and adding it as code at the end of the JIT'ed routine.
  • Allow backtracks to be direct via an indirect branch for an address pushed onto the stack. If the use of an indirect branch is from a conditional jump, then we emit a trampoline at the end of the routine.
  • Propogate backtracks instead of adding trampolines. Backtracks are propogated to where they are used. This change also eliminated trampoline branch code that aren't used.
  • Added global expression state to keep track of parentheses tail code and indirect branches. Other changes made to support these changes.
  • Split invertOrCapture flag on Patterns to two separate flags. Added getters for these flags. Rippled these changes to both the JIT and interpreter code.
  • Split BacktrackDestination out off TermGenerationState struct. This is done to hold references to a backtrack for later code generation. https://bugs.webkit.org/show_bug.cgi?id=50295
  • assembler/ARMAssembler.h: (JSC::ARMAssembler::JmpDst::isSet):
  • assembler/ARMv7Assembler.h: (JSC::ARMv7Assembler::JmpDst::isSet):
  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::Label::isSet): (JSC::AbstractMacroAssembler::DataLabelPtr::isUsed): (JSC::AbstractMacroAssembler::DataLabelPtr::used): (JSC::AbstractMacroAssembler::JumpList::clear):
  • assembler/MIPSAssembler.h: (JSC::MIPSAssembler::JmpDst::isSet):
  • assembler/X86Assembler.h: (JSC::X86Assembler::JmpDst::isSet):
  • yarr/RegexCompiler.cpp: (JSC::Yarr::RegexPatternConstructor::atomParenthesesSubpatternBegin): (JSC::Yarr::RegexPatternConstructor::atomParentheticalAssertionBegin): (JSC::Yarr::RegexPatternConstructor::atomBackReference): (JSC::Yarr::RegexPatternConstructor::setupAlternativeBeginTerms):
  • yarr/RegexInterpreter.cpp: (JSC::Yarr::ByteCompiler::atomParenthesesOnceBegin): (JSC::Yarr::ByteCompiler::atomParenthesesTerminalBegin): (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternBegin): (JSC::Yarr::ByteCompiler::atomParentheticalAssertionBegin): (JSC::Yarr::ByteCompiler::atomParentheticalAssertionEnd): (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternEnd): (JSC::Yarr::ByteCompiler::atomParenthesesOnceEnd): (JSC::Yarr::ByteCompiler::atomParenthesesTerminalEnd): (JSC::Yarr::ByteCompiler::emitDisjunction):
  • yarr/RegexInterpreter.h: (JSC::Yarr::ByteTerm::ByteTerm): (JSC::Yarr::ByteTerm::BackReference): (JSC::Yarr::ByteTerm::invert): (JSC::Yarr::ByteTerm::capture):
  • yarr/RegexJIT.cpp: (JSC::Yarr::RegexGenerator::IndirectJumpEntry::IndirectJumpEntry): (JSC::Yarr::RegexGenerator::IndirectJumpEntry::addJump): (JSC::Yarr::RegexGenerator::GenerationState::GenerationState): (JSC::Yarr::RegexGenerator::GenerationState::addIndirectJumpEntry): (JSC::Yarr::RegexGenerator::GenerationState::emitIndirectJumpTable): (JSC::Yarr::RegexGenerator::GenerationState::addParenthesesTail): (JSC::Yarr::RegexGenerator::GenerationState::emitParenthesesTail): (JSC::Yarr::RegexGenerator::GenerationState::addJumpToNextInteration): (JSC::Yarr::RegexGenerator::GenerationState::addJumpsToNextInteration): (JSC::Yarr::RegexGenerator::GenerationState::addDataLabelToNextIteration): (JSC::Yarr::RegexGenerator::GenerationState::linkToNextIteration): (JSC::Yarr::RegexGenerator::BacktrackDestination::BacktrackDestination): (JSC::Yarr::RegexGenerator::BacktrackDestination::clear): (JSC::Yarr::RegexGenerator::BacktrackDestination::clearDataLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::haveDestination): (JSC::Yarr::RegexGenerator::BacktrackDestination::isStackOffset): (JSC::Yarr::RegexGenerator::BacktrackDestination::isLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::isJumpList): (JSC::Yarr::RegexGenerator::BacktrackDestination::haveDataLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::copyTarget): (JSC::Yarr::RegexGenerator::BacktrackDestination::copyTo): (JSC::Yarr::RegexGenerator::BacktrackDestination::addBacktrackJump): (JSC::Yarr::RegexGenerator::BacktrackDestination::setStackOffset): (JSC::Yarr::RegexGenerator::BacktrackDestination::setLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::setNextBacktrackLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackToLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackJumpList): (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackSourceLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::setDataLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::setSubDataLabelPtr): (JSC::Yarr::RegexGenerator::BacktrackDestination::linkToNextBacktrack): (JSC::Yarr::RegexGenerator::BacktrackDestination::getStackOffset): (JSC::Yarr::RegexGenerator::BacktrackDestination::getLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::getBacktrackJumps): (JSC::Yarr::RegexGenerator::BacktrackDestination::getDataLabel): (JSC::Yarr::RegexGenerator::BacktrackDestination::jumpToBacktrack): (JSC::Yarr::RegexGenerator::BacktrackDestination::linkDataLabelToHereIfExists): (JSC::Yarr::RegexGenerator::BacktrackDestination::plantJumpToBacktrackIfExists): (JSC::Yarr::RegexGenerator::BacktrackDestination::linkAlternativeBacktracks): (JSC::Yarr::RegexGenerator::BacktrackDestination::linkAlternativeBacktracksTo): (JSC::Yarr::RegexGenerator::TermGenerationState::TermGenerationState): (JSC::Yarr::RegexGenerator::TermGenerationState::resetAlternative): (JSC::Yarr::RegexGenerator::TermGenerationState::isLastAlternative): (JSC::Yarr::RegexGenerator::TermGenerationState::clearBacktrack): (JSC::Yarr::RegexGenerator::TermGenerationState::jumpToBacktrack): (JSC::Yarr::RegexGenerator::TermGenerationState::plantJumpToBacktrackIfExists): (JSC::Yarr::RegexGenerator::TermGenerationState::linkDataLabelToBacktrackIfExists): (JSC::Yarr::RegexGenerator::TermGenerationState::addBacktrackJump): (JSC::Yarr::RegexGenerator::TermGenerationState::setDataLabelPtr): (JSC::Yarr::RegexGenerator::TermGenerationState::setBackTrackStackOffset): (JSC::Yarr::RegexGenerator::TermGenerationState::setBacktrackLabel): (JSC::Yarr::RegexGenerator::TermGenerationState::linkAlternativeBacktracks): (JSC::Yarr::RegexGenerator::TermGenerationState::linkAlternativeBacktracksTo): (JSC::Yarr::RegexGenerator::TermGenerationState::setBacktrackLink): (JSC::Yarr::RegexGenerator::TermGenerationState::chainBacktracks): (JSC::Yarr::RegexGenerator::TermGenerationState::chainBacktrackJumps): (JSC::Yarr::RegexGenerator::TermGenerationState::getBacktrackDestination): (JSC::Yarr::RegexGenerator::TermGenerationState::propagateBacktrackingFrom): (JSC::Yarr::RegexGenerator::ParenthesesTail::ParenthesesTail): (JSC::Yarr::RegexGenerator::ParenthesesTail::processBacktracks): (JSC::Yarr::RegexGenerator::ParenthesesTail::setNextIteration): (JSC::Yarr::RegexGenerator::ParenthesesTail::generateCode): (JSC::Yarr::RegexGenerator::generateAssertionBOL): (JSC::Yarr::RegexGenerator::generateAssertionEOL): (JSC::Yarr::RegexGenerator::generateAssertionWordBoundary): (JSC::Yarr::RegexGenerator::generatePatternCharacterSingle): (JSC::Yarr::RegexGenerator::generatePatternCharacterPair): (JSC::Yarr::RegexGenerator::generatePatternCharacterFixed): (JSC::Yarr::RegexGenerator::generatePatternCharacterGreedy): (JSC::Yarr::RegexGenerator::generatePatternCharacterNonGreedy): (JSC::Yarr::RegexGenerator::generateCharacterClassSingle): (JSC::Yarr::RegexGenerator::generateCharacterClassFixed): (JSC::Yarr::RegexGenerator::generateCharacterClassGreedy): (JSC::Yarr::RegexGenerator::generateCharacterClassNonGreedy): (JSC::Yarr::RegexGenerator::generateParenthesesDisjunction): (JSC::Yarr::RegexGenerator::generateParenthesesSingle): (JSC::Yarr::RegexGenerator::generateParenthesesGreedyNoBacktrack): (JSC::Yarr::RegexGenerator::generateParentheticalAssertion): (JSC::Yarr::RegexGenerator::generateDisjunction): (JSC::Yarr::RegexGenerator::compile):
  • yarr/RegexPattern.h: (JSC::Yarr::PatternTerm::PatternTerm): (JSC::Yarr::PatternTerm::invert): (JSC::Yarr::PatternTerm::capture):

2010-12-03 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough

Added new tests to support changes to Regexp JIT code handling
of parentheses. Tests focused on backtracking and nested
subexpressions.
https://bugs.webkit.org/show_bug.cgi?id=50295

  • fast/regex/parentheses-expected.txt: Added.
  • fast/regex/parentheses.html: Added.
  • fast/regex/script-tests/parentheses.js: Added.
File size: 14.8 KB
Line 
1/*
2 * Copyright (C) 2008 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 AbstractMacroAssembler_h
27#define AbstractMacroAssembler_h
28
29#include "CodeLocation.h"
30#include "MacroAssemblerCodeRef.h"
31#include <wtf/Noncopyable.h>
32#include <wtf/UnusedParam.h>
33
34#if ENABLE(ASSEMBLER)
35
36namespace JSC {
37
38class LinkBuffer;
39class RepatchBuffer;
40
41template <class AssemblerType>
42class AbstractMacroAssembler {
43public:
44 typedef AssemblerType AssemblerType_T;
45
46 typedef MacroAssemblerCodePtr CodePtr;
47 typedef MacroAssemblerCodeRef CodeRef;
48
49 class Jump;
50
51 typedef typename AssemblerType::RegisterID RegisterID;
52 typedef typename AssemblerType::JmpSrc JmpSrc;
53 typedef typename AssemblerType::JmpDst JmpDst;
54
55
56 // Section 1: MacroAssembler operand types
57 //
58 // The following types are used as operands to MacroAssembler operations,
59 // describing immediate and memory operands to the instructions to be planted.
60
61
62 enum Scale {
63 TimesOne,
64 TimesTwo,
65 TimesFour,
66 TimesEight,
67 };
68
69 // Address:
70 //
71 // Describes a simple base-offset address.
72 struct Address {
73 explicit Address(RegisterID base, int32_t offset = 0)
74 : base(base)
75 , offset(offset)
76 {
77 }
78
79 RegisterID base;
80 int32_t offset;
81 };
82
83 struct ExtendedAddress {
84 explicit ExtendedAddress(RegisterID base, intptr_t offset = 0)
85 : base(base)
86 , offset(offset)
87 {
88 }
89
90 RegisterID base;
91 intptr_t offset;
92 };
93
94 // ImplicitAddress:
95 //
96 // This class is used for explicit 'load' and 'store' operations
97 // (as opposed to situations in which a memory operand is provided
98 // to a generic operation, such as an integer arithmetic instruction).
99 //
100 // In the case of a load (or store) operation we want to permit
101 // addresses to be implicitly constructed, e.g. the two calls:
102 //
103 // load32(Address(addrReg), destReg);
104 // load32(addrReg, destReg);
105 //
106 // Are equivalent, and the explicit wrapping of the Address in the former
107 // is unnecessary.
108 struct ImplicitAddress {
109 ImplicitAddress(RegisterID base)
110 : base(base)
111 , offset(0)
112 {
113 }
114
115 ImplicitAddress(Address address)
116 : base(address.base)
117 , offset(address.offset)
118 {
119 }
120
121 RegisterID base;
122 int32_t offset;
123 };
124
125 // BaseIndex:
126 //
127 // Describes a complex addressing mode.
128 struct BaseIndex {
129 BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
130 : base(base)
131 , index(index)
132 , scale(scale)
133 , offset(offset)
134 {
135 }
136
137 RegisterID base;
138 RegisterID index;
139 Scale scale;
140 int32_t offset;
141 };
142
143 // AbsoluteAddress:
144 //
145 // Describes an memory operand given by a pointer. For regular load & store
146 // operations an unwrapped void* will be used, rather than using this.
147 struct AbsoluteAddress {
148 explicit AbsoluteAddress(void* ptr)
149 : m_ptr(ptr)
150 {
151 }
152
153 void* m_ptr;
154 };
155
156 // ImmPtr:
157 //
158 // A pointer sized immediate operand to an instruction - this is wrapped
159 // in a class requiring explicit construction in order to differentiate
160 // from pointers used as absolute addresses to memory operations
161 struct ImmPtr {
162 explicit ImmPtr(const void* value)
163 : m_value(value)
164 {
165 }
166
167 intptr_t asIntptr()
168 {
169 return reinterpret_cast<intptr_t>(m_value);
170 }
171
172 const void* m_value;
173 };
174
175 // Imm32:
176 //
177 // A 32bit immediate operand to an instruction - this is wrapped in a
178 // class requiring explicit construction in order to prevent RegisterIDs
179 // (which are implemented as an enum) from accidentally being passed as
180 // immediate values.
181 struct Imm32 {
182 explicit Imm32(int32_t value)
183 : m_value(value)
184#if CPU(ARM) || CPU(MIPS)
185 , m_isPointer(false)
186#endif
187 {
188 }
189
190#if !CPU(X86_64)
191 explicit Imm32(ImmPtr ptr)
192 : m_value(ptr.asIntptr())
193#if CPU(ARM) || CPU(MIPS)
194 , m_isPointer(true)
195#endif
196 {
197 }
198#endif
199
200 int32_t m_value;
201#if CPU(ARM) || CPU(MIPS)
202 // We rely on being able to regenerate code to recover exception handling
203 // information. Since ARMv7 supports 16-bit immediates there is a danger
204 // that if pointer values change the layout of the generated code will change.
205 // To avoid this problem, always generate pointers (and thus Imm32s constructed
206 // from ImmPtrs) with a code sequence that is able to represent any pointer
207 // value - don't use a more compact form in these cases.
208 // Same for MIPS.
209 bool m_isPointer;
210#endif
211 };
212
213
214 // Section 2: MacroAssembler code buffer handles
215 //
216 // The following types are used to reference items in the code buffer
217 // during JIT code generation. For example, the type Jump is used to
218 // track the location of a jump instruction so that it may later be
219 // linked to a label marking its destination.
220
221
222 // Label:
223 //
224 // A Label records a point in the generated instruction stream, typically such that
225 // it may be used as a destination for a jump.
226 class Label {
227 template<class TemplateAssemblerType>
228 friend class AbstractMacroAssembler;
229 friend class Jump;
230 friend class MacroAssemblerCodeRef;
231 friend class LinkBuffer;
232
233 public:
234 Label()
235 {
236 }
237
238 Label(AbstractMacroAssembler<AssemblerType>* masm)
239 : m_label(masm->m_assembler.label())
240 {
241 }
242
243 bool isUsed() const { return m_label.isUsed(); }
244 bool isSet() const { return m_label.isSet(); }
245 void used() { m_label.used(); }
246 private:
247 JmpDst m_label;
248 };
249
250 // DataLabelPtr:
251 //
252 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
253 // patched after the code has been generated.
254 class DataLabelPtr {
255 template<class TemplateAssemblerType>
256 friend class AbstractMacroAssembler;
257 friend class LinkBuffer;
258 public:
259 DataLabelPtr()
260 {
261 }
262
263 DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
264 : m_label(masm->m_assembler.label())
265 {
266 }
267
268 bool isSet() const { return m_label.isSet(); }
269
270 private:
271 JmpDst m_label;
272 };
273
274 // DataLabel32:
275 //
276 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
277 // patched after the code has been generated.
278 class DataLabel32 {
279 template<class TemplateAssemblerType>
280 friend class AbstractMacroAssembler;
281 friend class LinkBuffer;
282 public:
283 DataLabel32()
284 {
285 }
286
287 DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
288 : m_label(masm->m_assembler.label())
289 {
290 }
291
292 private:
293 JmpDst m_label;
294 };
295
296 // Call:
297 //
298 // A Call object is a reference to a call instruction that has been planted
299 // into the code buffer - it is typically used to link the call, setting the
300 // relative offset such that when executed it will call to the desired
301 // destination.
302 class Call {
303 template<class TemplateAssemblerType>
304 friend class AbstractMacroAssembler;
305
306 public:
307 enum Flags {
308 None = 0x0,
309 Linkable = 0x1,
310 Near = 0x2,
311 LinkableNear = 0x3,
312 };
313
314 Call()
315 : m_flags(None)
316 {
317 }
318
319 Call(JmpSrc jmp, Flags flags)
320 : m_jmp(jmp)
321 , m_flags(flags)
322 {
323 }
324
325 bool isFlagSet(Flags flag)
326 {
327 return m_flags & flag;
328 }
329
330 static Call fromTailJump(Jump jump)
331 {
332 return Call(jump.m_jmp, Linkable);
333 }
334
335 JmpSrc m_jmp;
336 private:
337 Flags m_flags;
338 };
339
340 // Jump:
341 //
342 // A jump object is a reference to a jump instruction that has been planted
343 // into the code buffer - it is typically used to link the jump, setting the
344 // relative offset such that when executed it will jump to the desired
345 // destination.
346 class Jump {
347 template<class TemplateAssemblerType>
348 friend class AbstractMacroAssembler;
349 friend class Call;
350 friend class LinkBuffer;
351 public:
352 Jump()
353 {
354 }
355
356 Jump(JmpSrc jmp)
357 : m_jmp(jmp)
358 {
359 }
360
361 void link(AbstractMacroAssembler<AssemblerType>* masm)
362 {
363 masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
364 }
365
366 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
367 {
368 masm->m_assembler.linkJump(m_jmp, label.m_label);
369 }
370
371 private:
372 JmpSrc m_jmp;
373 };
374
375 // JumpList:
376 //
377 // A JumpList is a set of Jump objects.
378 // All jumps in the set will be linked to the same destination.
379 class JumpList {
380 friend class LinkBuffer;
381
382 public:
383 typedef Vector<Jump, 16> JumpVector;
384
385 void link(AbstractMacroAssembler<AssemblerType>* masm)
386 {
387 size_t size = m_jumps.size();
388 for (size_t i = 0; i < size; ++i)
389 m_jumps[i].link(masm);
390 m_jumps.clear();
391 }
392
393 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
394 {
395 size_t size = m_jumps.size();
396 for (size_t i = 0; i < size; ++i)
397 m_jumps[i].linkTo(label, masm);
398 m_jumps.clear();
399 }
400
401 void append(Jump jump)
402 {
403 m_jumps.append(jump);
404 }
405
406 void append(JumpList& other)
407 {
408 m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
409 }
410
411 bool empty()
412 {
413 return !m_jumps.size();
414 }
415
416 void clear()
417 {
418 m_jumps.clear();
419 }
420
421 const JumpVector& jumps() { return m_jumps; }
422
423 private:
424 JumpVector m_jumps;
425 };
426
427
428 // Section 3: Misc admin methods
429 size_t size()
430 {
431 return m_assembler.size();
432 }
433
434 Label label()
435 {
436 return Label(this);
437 }
438
439 Label align()
440 {
441 m_assembler.align(16);
442 return Label(this);
443 }
444
445 ptrdiff_t differenceBetween(Label from, Jump to)
446 {
447 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
448 }
449
450 ptrdiff_t differenceBetween(Label from, Call to)
451 {
452 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
453 }
454
455 ptrdiff_t differenceBetween(Label from, Label to)
456 {
457 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
458 }
459
460 ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
461 {
462 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
463 }
464
465 ptrdiff_t differenceBetween(Label from, DataLabel32 to)
466 {
467 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
468 }
469
470 ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
471 {
472 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
473 }
474
475 ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to)
476 {
477 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
478 }
479
480 ptrdiff_t differenceBetween(DataLabelPtr from, Call to)
481 {
482 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
483 }
484
485 void beginUninterruptedSequence() { }
486 void endUninterruptedSequence() { }
487
488protected:
489 AssemblerType m_assembler;
490
491 friend class LinkBuffer;
492 friend class RepatchBuffer;
493
494 static void linkJump(void* code, Jump jump, CodeLocationLabel target)
495 {
496 AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation());
497 }
498
499 static void linkPointer(void* code, typename AssemblerType::JmpDst label, void* value)
500 {
501 AssemblerType::linkPointer(code, label, value);
502 }
503
504 static void* getLinkerAddress(void* code, typename AssemblerType::JmpSrc label)
505 {
506 return AssemblerType::getRelocatedAddress(code, label);
507 }
508
509 static void* getLinkerAddress(void* code, typename AssemblerType::JmpDst label)
510 {
511 return AssemblerType::getRelocatedAddress(code, label);
512 }
513
514 static unsigned getLinkerCallReturnOffset(Call call)
515 {
516 return AssemblerType::getCallReturnOffset(call.m_jmp);
517 }
518
519 static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination)
520 {
521 AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation());
522 }
523
524 static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination)
525 {
526 AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
527 }
528
529 static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value)
530 {
531 AssemblerType::repatchInt32(dataLabel32.dataLocation(), value);
532 }
533
534 static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value)
535 {
536 AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
537 }
538
539 static void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
540 {
541 AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
542 }
543};
544
545} // namespace JSC
546
547#endif // ENABLE(ASSEMBLER)
548
549#endif // AbstractMacroAssembler_h
Note: See TracBrowser for help on using the repository browser.