js/src/assembler/assembler/AbstractMacroAssembler.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 *
michael@0 4 * ***** BEGIN LICENSE BLOCK *****
michael@0 5 * Copyright (C) 2008 Apple Inc. All rights reserved.
michael@0 6 *
michael@0 7 * Redistribution and use in source and binary forms, with or without
michael@0 8 * modification, are permitted provided that the following conditions
michael@0 9 * are met:
michael@0 10 * 1. Redistributions of source code must retain the above copyright
michael@0 11 * notice, this list of conditions and the following disclaimer.
michael@0 12 * 2. Redistributions in binary form must reproduce the above copyright
michael@0 13 * notice, this list of conditions and the following disclaimer in the
michael@0 14 * documentation and/or other materials provided with the distribution.
michael@0 15 *
michael@0 16 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
michael@0 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
michael@0 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
michael@0 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
michael@0 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
michael@0 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
michael@0 23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
michael@0 24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 27 *
michael@0 28 * ***** END LICENSE BLOCK ***** */
michael@0 29
michael@0 30 #ifndef assembler_assembler_AbstractMacroAssembler_h
michael@0 31 #define assembler_assembler_AbstractMacroAssembler_h
michael@0 32
michael@0 33 #include "assembler/wtf/Platform.h"
michael@0 34 #include "assembler/assembler/MacroAssemblerCodeRef.h"
michael@0 35 #include "assembler/assembler/CodeLocation.h"
michael@0 36
michael@0 37 #if ENABLE_ASSEMBLER
michael@0 38
michael@0 39 namespace JSC {
michael@0 40
michael@0 41 class LinkBuffer;
michael@0 42 class RepatchBuffer;
michael@0 43
michael@0 44 template <class AssemblerType>
michael@0 45 class AbstractMacroAssembler {
michael@0 46 public:
michael@0 47 typedef AssemblerType AssemblerType_T;
michael@0 48
michael@0 49 typedef MacroAssemblerCodePtr CodePtr;
michael@0 50 typedef MacroAssemblerCodeRef CodeRef;
michael@0 51
michael@0 52 class Jump;
michael@0 53
michael@0 54 typedef typename AssemblerType::RegisterID RegisterID;
michael@0 55 typedef typename AssemblerType::FPRegisterID FPRegisterID;
michael@0 56 typedef typename AssemblerType::JmpSrc JmpSrc;
michael@0 57 typedef typename AssemblerType::JmpDst JmpDst;
michael@0 58
michael@0 59 #ifdef DEBUG
michael@0 60 void setSpewPath(bool isOOLPath)
michael@0 61 {
michael@0 62 m_assembler.isOOLPath = isOOLPath;
michael@0 63 }
michael@0 64 #endif
michael@0 65
michael@0 66 // Section 1: MacroAssembler operand types
michael@0 67 //
michael@0 68 // The following types are used as operands to MacroAssembler operations,
michael@0 69 // describing immediate and memory operands to the instructions to be planted.
michael@0 70
michael@0 71
michael@0 72 enum Scale {
michael@0 73 TimesOne,
michael@0 74 TimesTwo,
michael@0 75 TimesFour,
michael@0 76 TimesEight
michael@0 77 };
michael@0 78
michael@0 79 // Address:
michael@0 80 //
michael@0 81 // Describes a simple base-offset address.
michael@0 82 struct Address {
michael@0 83 explicit Address() {}
michael@0 84
michael@0 85 explicit Address(RegisterID base, int32_t offset = 0)
michael@0 86 : base(base)
michael@0 87 , offset(offset)
michael@0 88 {
michael@0 89 }
michael@0 90
michael@0 91 RegisterID base;
michael@0 92 int32_t offset;
michael@0 93 };
michael@0 94
michael@0 95 struct ExtendedAddress {
michael@0 96 explicit ExtendedAddress(RegisterID base, intptr_t offset = 0)
michael@0 97 : base(base)
michael@0 98 , offset(offset)
michael@0 99 {
michael@0 100 }
michael@0 101
michael@0 102 RegisterID base;
michael@0 103 intptr_t offset;
michael@0 104 };
michael@0 105
michael@0 106 // ImplicitAddress:
michael@0 107 //
michael@0 108 // This class is used for explicit 'load' and 'store' operations
michael@0 109 // (as opposed to situations in which a memory operand is provided
michael@0 110 // to a generic operation, such as an integer arithmetic instruction).
michael@0 111 //
michael@0 112 // In the case of a load (or store) operation we want to permit
michael@0 113 // addresses to be implicitly constructed, e.g. the two calls:
michael@0 114 //
michael@0 115 // load32(Address(addrReg), destReg);
michael@0 116 // load32(addrReg, destReg);
michael@0 117 //
michael@0 118 // Are equivalent, and the explicit wrapping of the Address in the former
michael@0 119 // is unnecessary.
michael@0 120 struct ImplicitAddress {
michael@0 121 ImplicitAddress(RegisterID base)
michael@0 122 : base(base)
michael@0 123 , offset(0)
michael@0 124 {
michael@0 125 }
michael@0 126
michael@0 127 ImplicitAddress(Address address)
michael@0 128 : base(address.base)
michael@0 129 , offset(address.offset)
michael@0 130 {
michael@0 131 }
michael@0 132
michael@0 133 RegisterID base;
michael@0 134 int32_t offset;
michael@0 135 };
michael@0 136
michael@0 137 // BaseIndex:
michael@0 138 //
michael@0 139 // Describes a complex addressing mode.
michael@0 140 struct BaseIndex {
michael@0 141 BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
michael@0 142 : base(base)
michael@0 143 , index(index)
michael@0 144 , scale(scale)
michael@0 145 , offset(offset)
michael@0 146 {
michael@0 147 }
michael@0 148
michael@0 149 RegisterID base;
michael@0 150 RegisterID index;
michael@0 151 Scale scale;
michael@0 152 int32_t offset;
michael@0 153 };
michael@0 154
michael@0 155 // AbsoluteAddress:
michael@0 156 //
michael@0 157 // Describes an memory operand given by a pointer. For regular load & store
michael@0 158 // operations an unwrapped void* will be used, rather than using this.
michael@0 159 struct AbsoluteAddress {
michael@0 160 explicit AbsoluteAddress(const void* ptr)
michael@0 161 : m_ptr(ptr)
michael@0 162 {
michael@0 163 }
michael@0 164
michael@0 165 const void* m_ptr;
michael@0 166 };
michael@0 167
michael@0 168 // TrustedImmPtr:
michael@0 169 //
michael@0 170 // A pointer sized immediate operand to an instruction - this is wrapped
michael@0 171 // in a class requiring explicit construction in order to differentiate
michael@0 172 // from pointers used as absolute addresses to memory operations
michael@0 173 struct TrustedImmPtr {
michael@0 174 explicit TrustedImmPtr(const void* value)
michael@0 175 : m_value(value)
michael@0 176 {
michael@0 177 }
michael@0 178
michael@0 179 intptr_t asIntptr()
michael@0 180 {
michael@0 181 return reinterpret_cast<intptr_t>(m_value);
michael@0 182 }
michael@0 183
michael@0 184 const void* m_value;
michael@0 185 };
michael@0 186
michael@0 187 struct ImmPtr : public TrustedImmPtr {
michael@0 188 explicit ImmPtr(const void* value)
michael@0 189 : TrustedImmPtr(value)
michael@0 190 {
michael@0 191 }
michael@0 192 };
michael@0 193
michael@0 194 // TrustedImm32:
michael@0 195 //
michael@0 196 // A 32bit immediate operand to an instruction - this is wrapped in a
michael@0 197 // class requiring explicit construction in order to prevent RegisterIDs
michael@0 198 // (which are implemented as an enum) from accidentally being passed as
michael@0 199 // immediate values.
michael@0 200 struct TrustedImm32 {
michael@0 201 explicit TrustedImm32(int32_t value)
michael@0 202 : m_value(value)
michael@0 203 #if WTF_CPU_ARM || WTF_CPU_MIPS
michael@0 204 , m_isPointer(false)
michael@0 205 #endif
michael@0 206 {
michael@0 207 }
michael@0 208
michael@0 209 #if !WTF_CPU_X86_64
michael@0 210 explicit TrustedImm32(TrustedImmPtr ptr)
michael@0 211 : m_value(ptr.asIntptr())
michael@0 212 #if WTF_CPU_ARM || WTF_CPU_MIPS
michael@0 213 , m_isPointer(true)
michael@0 214 #endif
michael@0 215 {
michael@0 216 }
michael@0 217 #endif
michael@0 218
michael@0 219 int32_t m_value;
michael@0 220 #if WTF_CPU_ARM || WTF_CPU_MIPS
michael@0 221 // We rely on being able to regenerate code to recover exception handling
michael@0 222 // information. Since ARMv7 supports 16-bit immediates there is a danger
michael@0 223 // that if pointer values change the layout of the generated code will change.
michael@0 224 // To avoid this problem, always generate pointers (and thus Imm32s constructed
michael@0 225 // from ImmPtrs) with a code sequence that is able to represent any pointer
michael@0 226 // value - don't use a more compact form in these cases.
michael@0 227 // Same for MIPS.
michael@0 228 bool m_isPointer;
michael@0 229 #endif
michael@0 230 };
michael@0 231
michael@0 232
michael@0 233 struct Imm32 : public TrustedImm32 {
michael@0 234 explicit Imm32(int32_t value)
michael@0 235 : TrustedImm32(value)
michael@0 236 {
michael@0 237 }
michael@0 238 #if !WTF_CPU_X86_64
michael@0 239 explicit Imm32(TrustedImmPtr ptr)
michael@0 240 : TrustedImm32(ptr)
michael@0 241 {
michael@0 242 }
michael@0 243 #endif
michael@0 244 };
michael@0 245
michael@0 246 struct ImmDouble {
michael@0 247 union {
michael@0 248 struct {
michael@0 249 #if WTF_CPU_BIG_ENDIAN || WTF_CPU_MIDDLE_ENDIAN
michael@0 250 uint32_t msb, lsb;
michael@0 251 #else
michael@0 252 uint32_t lsb, msb;
michael@0 253 #endif
michael@0 254 } s;
michael@0 255 uint64_t u64;
michael@0 256 double d;
michael@0 257 } u;
michael@0 258
michael@0 259 explicit ImmDouble(double d) {
michael@0 260 u.d = d;
michael@0 261 }
michael@0 262 };
michael@0 263
michael@0 264 // Section 2: MacroAssembler code buffer handles
michael@0 265 //
michael@0 266 // The following types are used to reference items in the code buffer
michael@0 267 // during JIT code generation. For example, the type Jump is used to
michael@0 268 // track the location of a jump instruction so that it may later be
michael@0 269 // linked to a label marking its destination.
michael@0 270
michael@0 271
michael@0 272 // Label:
michael@0 273 //
michael@0 274 // A Label records a point in the generated instruction stream, typically such that
michael@0 275 // it may be used as a destination for a jump.
michael@0 276 class Label {
michael@0 277 template<class TemplateAssemblerType>
michael@0 278 friend class AbstractMacroAssembler;
michael@0 279 friend class Jump;
michael@0 280 friend class MacroAssemblerCodeRef;
michael@0 281 friend class LinkBuffer;
michael@0 282
michael@0 283 public:
michael@0 284 Label()
michael@0 285 {
michael@0 286 }
michael@0 287
michael@0 288 Label(AbstractMacroAssembler<AssemblerType>* masm)
michael@0 289 : m_label(masm->m_assembler.label())
michael@0 290 {
michael@0 291 }
michael@0 292
michael@0 293 bool isUsed() const { return m_label.isUsed(); }
michael@0 294 void used() { m_label.used(); }
michael@0 295 bool isSet() const { return m_label.isValid(); }
michael@0 296 private:
michael@0 297 JmpDst m_label;
michael@0 298 };
michael@0 299
michael@0 300 // DataLabelPtr:
michael@0 301 //
michael@0 302 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
michael@0 303 // patched after the code has been generated.
michael@0 304 class DataLabelPtr {
michael@0 305 template<class TemplateAssemblerType>
michael@0 306 friend class AbstractMacroAssembler;
michael@0 307 friend class LinkBuffer;
michael@0 308 public:
michael@0 309 DataLabelPtr()
michael@0 310 {
michael@0 311 }
michael@0 312
michael@0 313 DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
michael@0 314 : m_label(masm->m_assembler.label())
michael@0 315 {
michael@0 316 }
michael@0 317
michael@0 318 bool isSet() const { return m_label.isValid(); }
michael@0 319
michael@0 320 private:
michael@0 321 JmpDst m_label;
michael@0 322 };
michael@0 323
michael@0 324 // DataLabel32:
michael@0 325 //
michael@0 326 // A DataLabel32 is used to refer to a location in the code containing a
michael@0 327 // 32-bit constant to be patched after the code has been generated.
michael@0 328 class DataLabel32 {
michael@0 329 template<class TemplateAssemblerType>
michael@0 330 friend class AbstractMacroAssembler;
michael@0 331 friend class LinkBuffer;
michael@0 332 public:
michael@0 333 DataLabel32()
michael@0 334 {
michael@0 335 }
michael@0 336
michael@0 337 DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
michael@0 338 : m_label(masm->m_assembler.label())
michael@0 339 {
michael@0 340 }
michael@0 341
michael@0 342 private:
michael@0 343 JmpDst m_label;
michael@0 344 };
michael@0 345
michael@0 346 // Call:
michael@0 347 //
michael@0 348 // A Call object is a reference to a call instruction that has been planted
michael@0 349 // into the code buffer - it is typically used to link the call, setting the
michael@0 350 // relative offset such that when executed it will call to the desired
michael@0 351 // destination.
michael@0 352 class Call {
michael@0 353 template<class TemplateAssemblerType>
michael@0 354 friend class AbstractMacroAssembler;
michael@0 355
michael@0 356 public:
michael@0 357 enum Flags {
michael@0 358 None = 0x0,
michael@0 359 Linkable = 0x1,
michael@0 360 Near = 0x2,
michael@0 361 LinkableNear = 0x3
michael@0 362 };
michael@0 363
michael@0 364 Call()
michael@0 365 : m_flags(None)
michael@0 366 {
michael@0 367 }
michael@0 368
michael@0 369 Call(JmpSrc jmp, Flags flags)
michael@0 370 : m_jmp(jmp)
michael@0 371 , m_flags(flags)
michael@0 372 {
michael@0 373 }
michael@0 374
michael@0 375 bool isFlagSet(Flags flag)
michael@0 376 {
michael@0 377 return !!(m_flags & flag);
michael@0 378 }
michael@0 379
michael@0 380 static Call fromTailJump(Jump jump)
michael@0 381 {
michael@0 382 return Call(jump.m_jmp, Linkable);
michael@0 383 }
michael@0 384
michael@0 385 JmpSrc m_jmp;
michael@0 386 private:
michael@0 387 Flags m_flags;
michael@0 388 };
michael@0 389
michael@0 390 // Jump:
michael@0 391 //
michael@0 392 // A jump object is a reference to a jump instruction that has been planted
michael@0 393 // into the code buffer - it is typically used to link the jump, setting the
michael@0 394 // relative offset such that when executed it will jump to the desired
michael@0 395 // destination.
michael@0 396 class Jump {
michael@0 397 template<class TemplateAssemblerType>
michael@0 398 friend class AbstractMacroAssembler;
michael@0 399 friend class Call;
michael@0 400 friend class LinkBuffer;
michael@0 401 public:
michael@0 402 Jump()
michael@0 403 {
michael@0 404 }
michael@0 405
michael@0 406 Jump(JmpSrc jmp)
michael@0 407 : m_jmp(jmp)
michael@0 408 {
michael@0 409 }
michael@0 410
michael@0 411 void link(AbstractMacroAssembler<AssemblerType>* masm) const
michael@0 412 {
michael@0 413 masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
michael@0 414 }
michael@0 415
michael@0 416 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
michael@0 417 {
michael@0 418 masm->m_assembler.linkJump(m_jmp, label.m_label);
michael@0 419 }
michael@0 420
michael@0 421 bool isSet() const { return m_jmp.isSet(); }
michael@0 422
michael@0 423 private:
michael@0 424 JmpSrc m_jmp;
michael@0 425 };
michael@0 426
michael@0 427 // JumpList:
michael@0 428 //
michael@0 429 // A JumpList is a set of Jump objects.
michael@0 430 // All jumps in the set will be linked to the same destination.
michael@0 431 class JumpList {
michael@0 432 friend class LinkBuffer;
michael@0 433
michael@0 434 public:
michael@0 435 typedef js::Vector<Jump, 16 ,js::SystemAllocPolicy > JumpVector;
michael@0 436
michael@0 437 JumpList() {}
michael@0 438
michael@0 439 JumpList(const JumpList &other)
michael@0 440 {
michael@0 441 m_jumps.appendAll(other.m_jumps);
michael@0 442 }
michael@0 443
michael@0 444 JumpList &operator=(const JumpList &other)
michael@0 445 {
michael@0 446 m_jumps.clear();
michael@0 447 m_jumps.append(other.m_jumps);
michael@0 448 return *this;
michael@0 449 }
michael@0 450
michael@0 451 void link(AbstractMacroAssembler<AssemblerType>* masm)
michael@0 452 {
michael@0 453 size_t size = m_jumps.length();
michael@0 454 for (size_t i = 0; i < size; ++i)
michael@0 455 m_jumps[i].link(masm);
michael@0 456 m_jumps.clear();
michael@0 457 }
michael@0 458
michael@0 459 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
michael@0 460 {
michael@0 461 size_t size = m_jumps.length();
michael@0 462 for (size_t i = 0; i < size; ++i)
michael@0 463 m_jumps[i].linkTo(label, masm);
michael@0 464 m_jumps.clear();
michael@0 465 }
michael@0 466
michael@0 467 void append(Jump jump)
michael@0 468 {
michael@0 469 m_jumps.append(jump);
michael@0 470 }
michael@0 471
michael@0 472 void append(const JumpList& other)
michael@0 473 {
michael@0 474 m_jumps.append(other.m_jumps.begin(), other.m_jumps.length());
michael@0 475 }
michael@0 476
michael@0 477 void clear()
michael@0 478 {
michael@0 479 m_jumps.clear();
michael@0 480 }
michael@0 481
michael@0 482 bool empty()
michael@0 483 {
michael@0 484 return !m_jumps.length();
michael@0 485 }
michael@0 486
michael@0 487 const JumpVector& jumps() const { return m_jumps; }
michael@0 488
michael@0 489 private:
michael@0 490 JumpVector m_jumps;
michael@0 491 };
michael@0 492
michael@0 493
michael@0 494 // Section 3: Misc admin methods
michael@0 495
michael@0 496 static CodePtr trampolineAt(CodeRef ref, Label label)
michael@0 497 {
michael@0 498 return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));
michael@0 499 }
michael@0 500
michael@0 501 size_t size()
michael@0 502 {
michael@0 503 return m_assembler.size();
michael@0 504 }
michael@0 505
michael@0 506 unsigned char *buffer()
michael@0 507 {
michael@0 508 return m_assembler.buffer();
michael@0 509 }
michael@0 510
michael@0 511 bool oom()
michael@0 512 {
michael@0 513 return m_assembler.oom();
michael@0 514 }
michael@0 515
michael@0 516 void executableCopy(void* buffer)
michael@0 517 {
michael@0 518 ASSERT(!oom());
michael@0 519 m_assembler.executableCopy(buffer);
michael@0 520 }
michael@0 521
michael@0 522 Label label()
michael@0 523 {
michael@0 524 return Label(this);
michael@0 525 }
michael@0 526
michael@0 527 DataLabel32 dataLabel32()
michael@0 528 {
michael@0 529 return DataLabel32(this);
michael@0 530 }
michael@0 531
michael@0 532 Label align()
michael@0 533 {
michael@0 534 m_assembler.align(16);
michael@0 535 return Label(this);
michael@0 536 }
michael@0 537
michael@0 538 ptrdiff_t differenceBetween(Label from, Jump to)
michael@0 539 {
michael@0 540 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
michael@0 541 }
michael@0 542
michael@0 543 ptrdiff_t differenceBetween(Label from, Call to)
michael@0 544 {
michael@0 545 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
michael@0 546 }
michael@0 547
michael@0 548 ptrdiff_t differenceBetween(Label from, Label to)
michael@0 549 {
michael@0 550 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 551 }
michael@0 552
michael@0 553 ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
michael@0 554 {
michael@0 555 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 556 }
michael@0 557
michael@0 558 ptrdiff_t differenceBetween(Label from, DataLabel32 to)
michael@0 559 {
michael@0 560 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 561 }
michael@0 562
michael@0 563 ptrdiff_t differenceBetween(DataLabel32 from, Label to)
michael@0 564 {
michael@0 565 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 566 }
michael@0 567
michael@0 568 ptrdiff_t differenceBetween(DataLabelPtr from, Label to)
michael@0 569 {
michael@0 570 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 571 }
michael@0 572
michael@0 573 ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
michael@0 574 {
michael@0 575 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
michael@0 576 }
michael@0 577
michael@0 578 ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to)
michael@0 579 {
michael@0 580 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
michael@0 581 }
michael@0 582
michael@0 583 ptrdiff_t differenceBetween(DataLabelPtr from, Call to)
michael@0 584 {
michael@0 585 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
michael@0 586 }
michael@0 587
michael@0 588 protected:
michael@0 589 AssemblerType m_assembler;
michael@0 590
michael@0 591 friend class LinkBuffer;
michael@0 592 friend class RepatchBuffer;
michael@0 593
michael@0 594 static void linkJump(void* code, Jump jump, CodeLocationLabel target)
michael@0 595 {
michael@0 596 AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation());
michael@0 597 }
michael@0 598
michael@0 599 static void linkPointer(void* code, typename AssemblerType::JmpDst label, void* value)
michael@0 600 {
michael@0 601 AssemblerType::linkPointer(code, label, value);
michael@0 602 }
michael@0 603
michael@0 604 static void* getLinkerAddress(void* code, typename AssemblerType::JmpSrc label)
michael@0 605 {
michael@0 606 return AssemblerType::getRelocatedAddress(code, label);
michael@0 607 }
michael@0 608
michael@0 609 static void* getLinkerAddress(void* code, typename AssemblerType::JmpDst label)
michael@0 610 {
michael@0 611 return AssemblerType::getRelocatedAddress(code, label);
michael@0 612 }
michael@0 613
michael@0 614 static unsigned getLinkerCallReturnOffset(Call call)
michael@0 615 {
michael@0 616 return AssemblerType::getCallReturnOffset(call.m_jmp);
michael@0 617 }
michael@0 618
michael@0 619 static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination)
michael@0 620 {
michael@0 621 AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation());
michael@0 622 }
michael@0 623
michael@0 624 static bool canRepatchJump(CodeLocationJump jump, CodeLocationLabel destination)
michael@0 625 {
michael@0 626 return AssemblerType::canRelinkJump(jump.dataLocation(), destination.dataLocation());
michael@0 627 }
michael@0 628
michael@0 629 static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination)
michael@0 630 {
michael@0 631 AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
michael@0 632 }
michael@0 633
michael@0 634 static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value)
michael@0 635 {
michael@0 636 AssemblerType::repatchInt32(dataLabel32.dataLocation(), value);
michael@0 637 }
michael@0 638
michael@0 639 static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value)
michael@0 640 {
michael@0 641 AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
michael@0 642 }
michael@0 643
michael@0 644 static void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
michael@0 645 {
michael@0 646 AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
michael@0 647 }
michael@0 648
michael@0 649 static void repatchLEAToLoadPtr(CodeLocationInstruction instruction)
michael@0 650 {
michael@0 651 AssemblerType::repatchLEAToLoadPtr(instruction.dataLocation());
michael@0 652 }
michael@0 653 };
michael@0 654
michael@0 655 } // namespace JSC
michael@0 656
michael@0 657 #endif // ENABLE(ASSEMBLER)
michael@0 658
michael@0 659 #endif /* assembler_assembler_AbstractMacroAssembler_h */

mercurial