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

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

2009-02-19 Gavin Barraclough <[email protected]>

Reviewed by Oliver Hunt.

Fix for x86-64. Where the JavaScriptCore text segment lies outside
a 2gb range of the heap containing JIT generated code, callbacks
from JIT code to the stub functions in Interpreter will be incorrectly
linked.

No performance impact on Sunspider, 1% regression on v8-tests,
due to a 3% regression on richards.

  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::Call::Call): (JSC::AbstractMacroAssembler::Jump::link): (JSC::AbstractMacroAssembler::Jump::linkTo): (JSC::AbstractMacroAssembler::CodeLocationJump::relink): (JSC::AbstractMacroAssembler::CodeLocationCall::relink): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction): (JSC::AbstractMacroAssembler::PatchBuffer::link): (JSC::AbstractMacroAssembler::PatchBuffer::linkTailRecursive): (JSC::AbstractMacroAssembler::differenceBetween):
  • assembler/MacroAssembler.h: (JSC::MacroAssembler::tailRecursiveCall): (JSC::MacroAssembler::makeTailRecursiveCall):
  • assembler/MacroAssemblerX86.h: (JSC::MacroAssemblerX86::call):
  • assembler/MacroAssemblerX86Common.h:
  • assembler/MacroAssemblerX86_64.h: (JSC::MacroAssemblerX86_64::call): (JSC::MacroAssemblerX86_64::moveWithPatch): (JSC::MacroAssemblerX86_64::branchPtrWithPatch): (JSC::MacroAssemblerX86_64::storePtrWithPatch):
  • assembler/X86Assembler.h: (JSC::X86Assembler::jmp_r): (JSC::X86Assembler::linkJump): (JSC::X86Assembler::patchJump): (JSC::X86Assembler::patchCall): (JSC::X86Assembler::linkCall): (JSC::X86Assembler::patchAddress):
  • interpreter/Interpreter.cpp: (JSC::Interpreter::tryCTICachePutByID):
  • jit/JIT.cpp: (JSC::JIT::privateCompile): (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate): (JSC::JIT::compileBinaryArithOp):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompileGetByIdSelf): (JSC::JIT::privateCompilePutByIdReplace):
File size: 24.6 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 <wtf/Platform.h>
30
31#if ENABLE(ASSEMBLER)
32
33namespace JSC {
34
35template <class AssemblerType>
36class AbstractMacroAssembler {
37public:
38 class Jump;
39 class PatchBuffer;
40 class CodeLocationLabel;
41 class CodeLocationJump;
42 class CodeLocationCall;
43 class CodeLocationDataLabel32;
44 class CodeLocationDataLabelPtr;
45
46 typedef typename AssemblerType::RegisterID RegisterID;
47 typedef typename AssemblerType::JmpSrc JmpSrc;
48 typedef typename AssemblerType::JmpDst JmpDst;
49
50
51 // Section 1: MacroAssembler operand types
52 //
53 // The following types are used as operands to MacroAssembler operations,
54 // describing immediate and memory operands to the instructions to be planted.
55
56
57 enum Scale {
58 TimesOne,
59 TimesTwo,
60 TimesFour,
61 TimesEight,
62 };
63
64 // Address:
65 //
66 // Describes a simple base-offset address.
67 struct Address {
68 explicit Address(RegisterID base, int32_t offset = 0)
69 : base(base)
70 , offset(offset)
71 {
72 }
73
74 RegisterID base;
75 int32_t offset;
76 };
77
78 // ImplicitAddress:
79 //
80 // This class is used for explicit 'load' and 'store' operations
81 // (as opposed to situations in which a memory operand is provided
82 // to a generic operation, such as an integer arithmetic instruction).
83 //
84 // In the case of a load (or store) operation we want to permit
85 // addresses to be implicitly constructed, e.g. the two calls:
86 //
87 // load32(Address(addrReg), destReg);
88 // load32(addrReg, destReg);
89 //
90 // Are equivalent, and the explicit wrapping of the Address in the former
91 // is unnecessary.
92 struct ImplicitAddress {
93 ImplicitAddress(RegisterID base)
94 : base(base)
95 , offset(0)
96 {
97 }
98
99 ImplicitAddress(Address address)
100 : base(address.base)
101 , offset(address.offset)
102 {
103 }
104
105 RegisterID base;
106 int32_t offset;
107 };
108
109 // BaseIndex:
110 //
111 // Describes a complex addressing mode.
112 struct BaseIndex {
113 BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
114 : base(base)
115 , index(index)
116 , scale(scale)
117 , offset(offset)
118 {
119 }
120
121 RegisterID base;
122 RegisterID index;
123 Scale scale;
124 int32_t offset;
125 };
126
127 // AbsoluteAddress:
128 //
129 // Describes an memory operand given by a pointer. For regular load & store
130 // operations an unwrapped void* will be used, rather than using this.
131 struct AbsoluteAddress {
132 explicit AbsoluteAddress(void* ptr)
133 : m_ptr(ptr)
134 {
135 }
136
137 void* m_ptr;
138 };
139
140 // ImmPtr:
141 //
142 // A pointer sized immediate operand to an instruction - this is wrapped
143 // in a class requiring explicit construction in order to differentiate
144 // from pointers used as absolute addresses to memory operations
145 struct ImmPtr {
146 explicit ImmPtr(void* value)
147 : m_value(value)
148 {
149 }
150
151 intptr_t asIntptr()
152 {
153 return reinterpret_cast<intptr_t>(m_value);
154 }
155
156 void* m_value;
157 };
158
159 // Imm32:
160 //
161 // A 32bit immediate operand to an instruction - this is wrapped in a
162 // class requiring explicit construction in order to prevent RegisterIDs
163 // (which are implemented as an enum) from accidentally being passed as
164 // immediate values.
165 struct Imm32 {
166 explicit Imm32(int32_t value)
167 : m_value(value)
168 {
169 }
170
171#if !PLATFORM(X86_64)
172 explicit Imm32(ImmPtr ptr)
173 : m_value(ptr.asIntptr())
174 {
175 }
176#endif
177
178 int32_t m_value;
179 };
180
181
182 // Section 2: MacroAssembler code buffer handles
183 //
184 // The following types are used to reference items in the code buffer
185 // during JIT code generation. For example, the type Jump is used to
186 // track the location of a jump instruction so that it may later be
187 // linked to a label marking its destination.
188
189
190 // Label:
191 //
192 // A Label records a point in the generated instruction stream, typically such that
193 // it may be used as a destination for a jump.
194 class Label {
195 friend class Jump;
196 template<class AssemblerType_T>
197 friend class AbstractMacroAssembler;
198 friend class PatchBuffer;
199 public:
200 Label()
201 {
202 }
203
204 Label(AbstractMacroAssembler<AssemblerType>* masm)
205 : m_label(masm->m_assembler.label())
206 {
207 }
208
209 private:
210 JmpDst m_label;
211 };
212
213 // DataLabelPtr:
214 //
215 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
216 // patched after the code has been generated.
217 class DataLabelPtr {
218 template<class AssemblerType_T>
219 friend class AbstractMacroAssembler;
220 friend class PatchBuffer;
221 public:
222 DataLabelPtr()
223 {
224 }
225
226 DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
227 : m_label(masm->m_assembler.label())
228 {
229 }
230
231 private:
232 JmpDst m_label;
233 };
234
235 // DataLabel32:
236 //
237 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
238 // patched after the code has been generated.
239 class DataLabel32 {
240 template<class AssemblerType_T>
241 friend class AbstractMacroAssembler;
242 friend class PatchBuffer;
243 public:
244 DataLabel32()
245 {
246 }
247
248 DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
249 : m_label(masm->m_assembler.label())
250 {
251 }
252
253 private:
254 JmpDst m_label;
255 };
256
257 // Call:
258 //
259 // A Call object is a reference to a call instruction that has been planted
260 // into the code buffer - it is typically used to link the call, setting the
261 // relative offset such that when executed it will call to the desired
262 // destination.
263 class Call {
264 friend class PatchBuffer;
265 template<class AssemblerType_T>
266 friend class AbstractMacroAssembler;
267 public:
268 enum Flags {
269 None = 0x0,
270 Linkable = 0x1,
271 Near = 0x2,
272 LinkableNear = 0x3,
273 };
274
275 Call()
276 : m_flags(None)
277 {
278 }
279
280 Call(JmpSrc jmp, Flags flags)
281 : m_jmp(jmp)
282 , m_flags(flags)
283 {
284 }
285
286 bool isFlagSet(Flags flag)
287 {
288 return m_flags & flag;
289 }
290
291 static Call fromTailJump(Jump jump)
292 {
293 return Call(jump.m_jmp, Linkable);
294 }
295
296 private:
297 JmpSrc m_jmp;
298 Flags m_flags;
299 };
300
301 // Jump:
302 //
303 // A jump object is a reference to a jump instruction that has been planted
304 // into the code buffer - it is typically used to link the jump, setting the
305 // relative offset such that when executed it will jump to the desired
306 // destination.
307 class Jump {
308 friend class PatchBuffer;
309 template<class AssemblerType_T>
310 friend class AbstractMacroAssembler;
311 friend class Call;
312 public:
313 Jump()
314 {
315 }
316
317 Jump(JmpSrc jmp)
318 : m_jmp(jmp)
319 {
320 }
321
322 void link(AbstractMacroAssembler<AssemblerType>* masm)
323 {
324 masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
325 }
326
327 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
328 {
329 masm->m_assembler.linkJump(m_jmp, label.m_label);
330 }
331
332 private:
333 JmpSrc m_jmp;
334 };
335
336 // JumpList:
337 //
338 // A JumpList is a set of Jump objects.
339 // All jumps in the set will be linked to the same destination.
340 class JumpList {
341 friend class PatchBuffer;
342
343 public:
344 void link(AbstractMacroAssembler<AssemblerType>* masm)
345 {
346 size_t size = m_jumps.size();
347 for (size_t i = 0; i < size; ++i)
348 m_jumps[i].link(masm);
349 m_jumps.clear();
350 }
351
352 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
353 {
354 size_t size = m_jumps.size();
355 for (size_t i = 0; i < size; ++i)
356 m_jumps[i].linkTo(label, masm);
357 m_jumps.clear();
358 }
359
360 void append(Jump jump)
361 {
362 m_jumps.append(jump);
363 }
364
365 void append(JumpList& other)
366 {
367 m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
368 }
369
370 bool empty()
371 {
372 return !m_jumps.size();
373 }
374
375 private:
376 Vector<Jump, 16> m_jumps;
377 };
378
379
380 // Section 3: MacroAssembler JIT instruction stream handles.
381 //
382 // The MacroAssembler supported facilities to modify a JIT generated
383 // instruction stream after it has been generated (relinking calls and
384 // jumps, and repatching data values). The following types are used
385 // to store handles into the underlying instruction stream, the type
386 // providing semantic information as to what it is that is in the
387 // instruction stream at this point, and thus what operations may be
388 // performed on it.
389
390
391 // CodeLocationCommon:
392 //
393 // Base type for other CodeLocation* types. A postion in the JIT genertaed
394 // instruction stream, without any semantic information.
395 class CodeLocationCommon {
396 public:
397 CodeLocationCommon()
398 : m_location(0)
399 {
400 }
401
402 // In order to avoid the need to store multiple handles into the
403 // instructions stream, where the code generation is deterministic
404 // and the labels will always be a fixed distance apart, these
405 // methods may be used to recover a handle that has nopw been
406 // retained, based on a known fixed relative offset from one that has.
407 CodeLocationLabel labelAtOffset(int offset);
408 CodeLocationJump jumpAtOffset(int offset);
409 CodeLocationCall callAtOffset(int offset);
410 CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
411 CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
412
413 operator bool() { return m_location; }
414 void reset() { m_location = 0; }
415
416 protected:
417 explicit CodeLocationCommon(void* location)
418 : m_location(location)
419 {
420 }
421
422 void* m_location;
423 };
424
425 // CodeLocationLabel:
426 //
427 // A point in the JIT code maked with a label.
428 class CodeLocationLabel : public CodeLocationCommon {
429 friend class CodeLocationCommon;
430 friend class CodeLocationJump;
431 friend class PatchBuffer;
432 public:
433 CodeLocationLabel()
434 {
435 }
436
437 void* addressForSwitch() { return this->m_location; }
438 void* addressForExceptionHandler() { return this->m_location; }
439 void* addressForJSR() { return this->m_location; }
440
441 private:
442 explicit CodeLocationLabel(void* location)
443 : CodeLocationCommon(location)
444 {
445 }
446
447 void* getJumpDestination() { return this->m_location; }
448 };
449
450 // CodeLocationJump:
451 //
452 // A point in the JIT code at which there is a jump instruction.
453 class CodeLocationJump : public CodeLocationCommon {
454 friend class CodeLocationCommon;
455 friend class PatchBuffer;
456 public:
457 CodeLocationJump()
458 {
459 }
460
461 void relink(CodeLocationLabel destination)
462 {
463 AssemblerType::patchJump(reinterpret_cast<intptr_t>(this->m_location), destination.m_location);
464 }
465
466 private:
467 explicit CodeLocationJump(void* location)
468 : CodeLocationCommon(location)
469 {
470 }
471 };
472
473 // CodeLocationCall:
474 //
475 // A point in the JIT code at which there is a call instruction.
476 class CodeLocationCall : public CodeLocationCommon {
477 friend class CodeLocationCommon;
478 friend class PatchBuffer;
479 public:
480 CodeLocationCall()
481 {
482 }
483
484 template<typename FunctionSig>
485 void relink(FunctionSig* function)
486 {
487 AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
488 }
489
490 // This methods returns the value that will be set as the return address
491 // within a function that has been called from this call instruction.
492 void* calleeReturnAddressValue()
493 {
494 return this->m_location;
495 }
496
497 private:
498 explicit CodeLocationCall(void* location)
499 : CodeLocationCommon(location)
500 {
501 }
502 };
503
504 // CodeLocationNearCall:
505 //
506 // A point in the JIT code at which there is a call instruction with near linkage.
507 class CodeLocationNearCall : public CodeLocationCommon {
508 friend class CodeLocationCommon;
509 friend class PatchBuffer;
510 public:
511 CodeLocationNearCall()
512 {
513 }
514
515 template<typename FunctionSig>
516 void relink(FunctionSig* function)
517 {
518 AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));
519 }
520
521 // This methods returns the value that will be set as the return address
522 // within a function that has been called from this call instruction.
523 void* calleeReturnAddressValue()
524 {
525 return this->m_location;
526 }
527
528 private:
529 explicit CodeLocationNearCall(void* location)
530 : CodeLocationCommon(location)
531 {
532 }
533 };
534
535 // CodeLocationDataLabel32:
536 //
537 // A point in the JIT code at which there is an int32_t immediate that may be repatched.
538 class CodeLocationDataLabel32 : public CodeLocationCommon {
539 friend class CodeLocationCommon;
540 friend class PatchBuffer;
541 public:
542 CodeLocationDataLabel32()
543 {
544 }
545
546 void repatch(int32_t value)
547 {
548 AssemblerType::patchImmediate(reinterpret_cast<intptr_t>(this->m_location), value);
549 }
550
551 private:
552 explicit CodeLocationDataLabel32(void* location)
553 : CodeLocationCommon(location)
554 {
555 }
556 };
557
558 // CodeLocationDataLabelPtr:
559 //
560 // A point in the JIT code at which there is a void* immediate that may be repatched.
561 class CodeLocationDataLabelPtr : public CodeLocationCommon {
562 friend class CodeLocationCommon;
563 friend class PatchBuffer;
564 public:
565 CodeLocationDataLabelPtr()
566 {
567 }
568
569 void repatch(void* value)
570 {
571 AssemblerType::patchPointer(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<intptr_t>(value));
572 }
573
574 private:
575 explicit CodeLocationDataLabelPtr(void* location)
576 : CodeLocationCommon(location)
577 {
578 }
579 };
580
581 // ProcessorReturnAddress:
582 //
583 // This class can be used to relink a call identified by its return address.
584 class ProcessorReturnAddress {
585 public:
586 ProcessorReturnAddress(void* location)
587 : m_location(location)
588 {
589 }
590
591 template<typename FunctionSig>
592 void relinkCallerToFunction(FunctionSig* newCalleeFunction)
593 {
594 AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
595 }
596
597 template<typename FunctionSig>
598 void relinkNearCallerToFunction(FunctionSig* newCalleeFunction)
599 {
600 AssemblerType::patchCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction));
601 }
602
603 operator void*()
604 {
605 return m_location;
606 }
607
608 private:
609 void* m_location;
610 };
611
612
613 // Section 4: The patch buffer - utility to finalize code generation.
614
615
616 // PatchBuffer:
617 //
618 // This class assists in linking code generated by the macro assembler, once code generation
619 // has been completed, and the code has been copied to is final location in memory. At this
620 // time pointers to labels within the code may be resolved, and relative offsets to external
621 // addresses may be fixed.
622 //
623 // Specifically:
624 // * Jump objects may be linked to external targets,
625 // * The address of Jump objects may taken, such that it can later be relinked.
626 // * The return address of a Jump object representing a call may be acquired.
627 // * The address of a Label pointing into the code may be resolved.
628 // * The value referenced by a DataLabel may be fixed.
629 //
630 // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
631 // address of calls, as opposed to a point that can be used to later relink a Jump -
632 // possibly wrap the later up in an object that can do just that).
633 class PatchBuffer {
634 public:
635 PatchBuffer(void* code)
636 : m_code(code)
637 {
638 }
639
640 CodeLocationLabel entry()
641 {
642 return CodeLocationLabel(m_code);
643 }
644
645 void* trampolineAt(Label label)
646 {
647 return AssemblerType::getRelocatedAddress(m_code, label.m_label);
648 }
649
650 // These methods are used to link or set values at code generation time.
651
652 template<typename FunctionSig>
653 void link(Call call, FunctionSig* function)
654 {
655 ASSERT(call.isFlagSet(Call::Linkable));
656#if PLATFORM(X86_64)
657 if (call.isFlagSet(Call::Near)) {
658 AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function));
659 } else {
660 intptr_t callLocation = reinterpret_cast<intptr_t>(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
661 AssemblerType::patchMacroAssemblerCall(callLocation, reinterpret_cast<void*>(function));
662 }
663#else
664 AssemblerType::linkCall(m_code, call.m_jmp, reinterpret_cast<void*>(function));
665#endif
666 }
667
668 template<typename FunctionSig>
669 void linkTailRecursive(Jump jump, FunctionSig* function)
670 {
671 AssemblerType::linkJump(m_code, jump.m_jmp, reinterpret_cast<void*>(function));
672 }
673
674 template<typename FunctionSig>
675 void linkTailRecursive(JumpList list, FunctionSig* function)
676 {
677 for (unsigned i = 0; i < list.m_jumps.size(); ++i) {
678 AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, reinterpret_cast<void*>(function));
679 }
680 }
681
682 void link(Jump jump, CodeLocationLabel label)
683 {
684 AssemblerType::linkJump(m_code, jump.m_jmp, label.m_location);
685 }
686
687 void link(JumpList list, CodeLocationLabel label)
688 {
689 for (unsigned i = 0; i < list.m_jumps.size(); ++i)
690 AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, label.m_location);
691 }
692
693 void patch(DataLabelPtr label, void* value)
694 {
695 AssemblerType::patchAddress(m_code, label.m_label, value);
696 }
697
698 // These methods are used to obtain handles to allow the code to be relinked / repatched later.
699
700 CodeLocationCall locationOf(Call call)
701 {
702 ASSERT(call.isFlagSet(Call::Linkable));
703 ASSERT(!call.isFlagSet(Call::Near));
704 return CodeLocationCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
705 }
706
707 CodeLocationNearCall locationOfNearCall(Call call)
708 {
709 ASSERT(call.isFlagSet(Call::Linkable));
710 ASSERT(call.isFlagSet(Call::Near));
711 return CodeLocationNearCall(AssemblerType::getRelocatedAddress(m_code, call.m_jmp));
712 }
713
714 CodeLocationLabel locationOf(Label label)
715 {
716 return CodeLocationLabel(AssemblerType::getRelocatedAddress(m_code, label.m_label));
717 }
718
719 CodeLocationDataLabelPtr locationOf(DataLabelPtr label)
720 {
721 return CodeLocationDataLabelPtr(AssemblerType::getRelocatedAddress(m_code, label.m_label));
722 }
723
724 CodeLocationDataLabel32 locationOf(DataLabel32 label)
725 {
726 return CodeLocationDataLabel32(AssemblerType::getRelocatedAddress(m_code, label.m_label));
727 }
728
729 // This method obtains the return address of the call, given as an offset from
730 // the start of the code.
731 unsigned returnAddressOffset(Call call)
732 {
733 return AssemblerType::getCallReturnOffset(call.m_jmp);
734 }
735
736 private:
737 void* m_code;
738 };
739
740
741 // Section 5: Misc admin methods
742
743 size_t size()
744 {
745 return m_assembler.size();
746 }
747
748 void* copyCode(ExecutablePool* allocator)
749 {
750 return m_assembler.executableCopy(allocator);
751 }
752
753 Label label()
754 {
755 return Label(this);
756 }
757
758 Label align()
759 {
760 m_assembler.align(16);
761 return Label(this);
762 }
763
764 ptrdiff_t differenceBetween(Label from, Jump to)
765 {
766 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
767 }
768
769 ptrdiff_t differenceBetween(Label from, Call to)
770 {
771 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
772 }
773
774 ptrdiff_t differenceBetween(Label from, Label to)
775 {
776 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
777 }
778
779 ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
780 {
781 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
782 }
783
784 ptrdiff_t differenceBetween(Label from, DataLabel32 to)
785 {
786 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
787 }
788
789 ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
790 {
791 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
792 }
793
794 ptrdiff_t differenceBetween(DataLabelPtr from, Call to)
795 {
796 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
797 }
798
799protected:
800 AssemblerType m_assembler;
801};
802
803
804template <class AssemblerType>
805typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset)
806{
807 return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(m_location) + offset);
808}
809
810template <class AssemblerType>
811typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset)
812{
813 return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(m_location) + offset);
814}
815
816template <class AssemblerType>
817typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset)
818{
819 return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(m_location) + offset);
820}
821
822template <class AssemblerType>
823typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset)
824{
825 return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(m_location) + offset);
826}
827
828template <class AssemblerType>
829typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset)
830{
831 return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(m_location) + offset);
832}
833
834
835} // namespace JSC
836
837#endif // ENABLE(ASSEMBLER)
838
839#endif // AbstractMacroAssembler_h
Note: See TracBrowser for help on using the repository browser.