Changeset 44711 in webkit for trunk/JavaScriptCore
- Timestamp:
- Jun 15, 2009, 10:35:32 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r44705 r44711 1 2009-06-15 Gavin Barraclough <[email protected]> 2 3 Reviewed by Sam Weinig. 4 5 Having moved most of their functionality into the RepatchBuffer class, 6 we can simplify the CodeLocation* classes. 7 8 The CodeLocation* classes are currently a tangle of templatey and friendly 9 badness, burried in the middle of AbstractMacroAssembler. Having moved 10 the ability to repatch out into RepatchBufer they are now do-nothing wrappers 11 on CodePtr (MacroAssemblerCodePtr), that only exist to provide type-safety. 12 13 Simplify the code, and move them off into their own header. 14 15 * JavaScriptCore.xcodeproj/project.pbxproj: 16 * assembler/AbstractMacroAssembler.h: 17 (JSC::AbstractMacroAssembler::PatchBuffer::patch): 18 * assembler/CodeLocation.h: Copied from assembler/AbstractMacroAssembler.h. 19 (JSC::CodeLocationCommon::CodeLocationCommon): 20 (JSC::CodeLocationInstruction::CodeLocationInstruction): 21 (JSC::CodeLocationLabel::CodeLocationLabel): 22 (JSC::CodeLocationJump::CodeLocationJump): 23 (JSC::CodeLocationCall::CodeLocationCall): 24 (JSC::CodeLocationNearCall::CodeLocationNearCall): 25 (JSC::CodeLocationDataLabel32::CodeLocationDataLabel32): 26 (JSC::CodeLocationDataLabelPtr::CodeLocationDataLabelPtr): 27 (JSC::CodeLocationCommon::instructionAtOffset): 28 (JSC::CodeLocationCommon::labelAtOffset): 29 (JSC::CodeLocationCommon::jumpAtOffset): 30 (JSC::CodeLocationCommon::callAtOffset): 31 (JSC::CodeLocationCommon::nearCallAtOffset): 32 (JSC::CodeLocationCommon::dataLabelPtrAtOffset): 33 (JSC::CodeLocationCommon::dataLabel32AtOffset): 34 * assembler/MacroAssemblerCodeRef.h: 35 (JSC::MacroAssemblerCodePtr::operator!): 36 * bytecode/CodeBlock.h: 37 (JSC::getStructureStubInfoReturnLocation): 38 (JSC::getCallLinkInfoReturnLocation): 39 (JSC::getMethodCallLinkInfoReturnLocation): 40 * bytecode/Instruction.h: 41 * bytecode/JumpTable.h: 42 (JSC::StringJumpTable::ctiForValue): 43 (JSC::SimpleJumpTable::ctiForValue): 44 * bytecode/StructureStubInfo.h: 45 * bytecompiler/BytecodeGenerator.cpp: 46 (JSC::BytecodeGenerator::emitCatch): 47 * jit/JIT.cpp: 48 (JSC::JIT::privateCompile): 49 * jit/JITStubs.cpp: 50 (JSC::JITStubs::DEFINE_STUB_FUNCTION): 51 (JSC::JITStubs::getPolymorphicAccessStructureListSlot): 52 1 53 2009-06-15 Gavin Barraclough <[email protected]> 2 54 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r44550 r44711 137 137 86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CCEFDD0F413F8900FD7F9E /* JITCode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 138 138 86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; }; 139 86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; }; 139 140 86EAC4950F93E8D1008EC948 /* RegexCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */; }; 140 141 86EAC4960F93E8D1008EC948 /* RegexCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */; }; … … 642 643 86DB645F0F954E9100D7D921 /* ExecutableAllocatorWin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorWin.cpp; sourceTree = "<group>"; }; 643 644 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; }; 645 86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; }; 644 646 86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegexCompiler.cpp; path = yarr/RegexCompiler.cpp; sourceTree = "<group>"; }; 645 647 86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexCompiler.h; path = yarr/RegexCompiler.h; sourceTree = "<group>"; }; … … 1547 1549 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */, 1548 1550 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */, 1551 86E116B00FE75AC800B512BC /* CodeLocation.h */, 1549 1552 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */, 1550 1553 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */, … … 1860 1863 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */, 1861 1864 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */, 1865 86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */, 1862 1866 ); 1863 1867 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r44705 r44711 30 30 31 31 #include <MacroAssemblerCodeRef.h> 32 #include <CodeLocation.h> 32 33 #include <wtf/Noncopyable.h> 33 34 #include <wtf/UnusedParam.h> … … 51 52 class PatchBuffer; 52 53 class RepatchBuffer; 53 class CodeLocationInstruction;54 class CodeLocationLabel;55 class CodeLocationJump;56 class CodeLocationCall;57 class CodeLocationNearCall;58 class CodeLocationDataLabel32;59 class CodeLocationDataLabelPtr;60 54 61 55 typedef typename AssemblerType::RegisterID RegisterID; … … 413 407 414 408 415 // Section 3: MacroAssembler JIT instruction stream handles. 416 // 417 // The MacroAssembler supported facilities to modify a JIT generated 418 // instruction stream after it has been generated (relinking calls and 419 // jumps, and repatching data values). The following types are used 420 // to store handles into the underlying instruction stream, the type 421 // providing semantic information as to what it is that is in the 422 // instruction stream at this point, and thus what operations may be 423 // performed on it. 424 425 426 // CodeLocationCommon: 427 // 428 // Base type for other CodeLocation* types. A postion in the JIT genertaed 429 // instruction stream, without any semantic information. 430 class CodeLocationCommon { 431 friend class RepatchBuffer; 432 433 public: 434 CodeLocationCommon() 435 { 436 } 437 438 // In order to avoid the need to store multiple handles into the 439 // instructions stream, where the code generation is deterministic 440 // and the labels will always be a fixed distance apart, these 441 // methods may be used to recover a handle that has nopw been 442 // retained, based on a known fixed relative offset from one that has. 443 CodeLocationInstruction instructionAtOffset(int offset); 444 CodeLocationLabel labelAtOffset(int offset); 445 CodeLocationJump jumpAtOffset(int offset); 446 CodeLocationCall callAtOffset(int offset); 447 CodeLocationNearCall nearCallAtOffset(int offset); 448 CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset); 449 CodeLocationDataLabel32 dataLabel32AtOffset(int offset); 450 451 protected: 452 explicit CodeLocationCommon(CodePtr location) 453 : m_location(location) 454 { 455 } 456 457 void* dataLocation() { return m_location.dataLocation(); } 458 void* executableAddress() { return m_location.executableAddress(); } 459 460 void reset() 461 { 462 m_location = CodePtr(); 463 } 464 465 private: 466 CodePtr m_location; 467 }; 468 469 // CodeLocationInstruction: 470 // 471 // An arbitrary instruction in the JIT code. 472 class CodeLocationInstruction : public CodeLocationCommon { 473 public: 474 CodeLocationInstruction() 475 { 476 } 477 478 explicit CodeLocationInstruction(void* location) 479 : CodeLocationCommon(CodePtr(location)) 480 { 481 } 482 }; 483 484 // CodeLocationLabel: 485 // 486 // A point in the JIT code maked with a label. 487 class CodeLocationLabel : public CodeLocationCommon { 488 friend class CodeLocationCommon; 489 friend class CodeLocationJump; 490 friend class CodeLocationCall; 491 friend class CodeLocationNearCall; 492 friend class PatchBuffer; 493 friend class RepatchBuffer; 494 495 public: 496 CodeLocationLabel() 497 { 498 } 499 500 void* addressForSwitch() { return this->executableAddress(); } 501 void* addressForExceptionHandler() { return this->executableAddress(); } 502 void* addressForJSR() { return this->executableAddress(); } 503 504 bool operator!() 505 { 506 return !this->executableAddress(); 507 } 508 509 void reset() 510 { 511 CodeLocationCommon::reset(); 512 } 513 514 private: 515 explicit CodeLocationLabel(CodePtr location) 516 : CodeLocationCommon(location) 517 { 518 } 519 520 explicit CodeLocationLabel(void* location) 521 : CodeLocationCommon(CodePtr(location)) 522 { 523 } 524 525 void* getJumpDestination() { return this->executableAddress(); } 526 }; 527 528 // CodeLocationJump: 529 // 530 // A point in the JIT code at which there is a jump instruction. 531 class CodeLocationJump : public CodeLocationCommon { 532 friend class CodeLocationCommon; 533 friend class PatchBuffer; 534 public: 535 CodeLocationJump() 536 { 537 } 538 539 explicit CodeLocationJump(void* location) 540 : CodeLocationCommon(CodePtr(location)) 541 { 542 } 543 }; 544 545 // CodeLocationCall: 546 // 547 // A point in the JIT code at which there is a call instruction. 548 class CodeLocationCall : public CodeLocationCommon { 549 public: 550 CodeLocationCall() 551 { 552 } 553 554 explicit CodeLocationCall(CodePtr location) 555 : CodeLocationCommon(location) 556 { 557 } 558 559 explicit CodeLocationCall(void* location) 560 : CodeLocationCommon(CodePtr(location)) 561 { 562 } 563 564 // This methods returns the value that will be set as the return address 565 // within a function that has been called from this call instruction. 566 void* calleeReturnAddressValue() 567 { 568 return this->executableAddress(); 569 } 570 571 }; 572 573 // CodeLocationNearCall: 574 // 575 // A point in the JIT code at which there is a call instruction with near linkage. 576 class CodeLocationNearCall : public CodeLocationCommon { 577 public: 578 CodeLocationNearCall() 579 { 580 } 581 582 explicit CodeLocationNearCall(CodePtr location) 583 : CodeLocationCommon(location) 584 { 585 } 586 587 explicit CodeLocationNearCall(void* location) 588 : CodeLocationCommon(CodePtr(location)) 589 { 590 } 591 592 // This methods returns the value that will be set as the return address 593 // within a function that has been called from this call instruction. 594 void* calleeReturnAddressValue() 595 { 596 return this->executableAddress(); 597 } 598 }; 599 600 // CodeLocationDataLabel32: 601 // 602 // A point in the JIT code at which there is an int32_t immediate that may be repatched. 603 class CodeLocationDataLabel32 : public CodeLocationCommon { 604 public: 605 CodeLocationDataLabel32() 606 { 607 } 608 609 explicit CodeLocationDataLabel32(void* location) 610 : CodeLocationCommon(CodePtr(location)) 611 { 612 } 613 }; 614 615 // CodeLocationDataLabelPtr: 616 // 617 // A point in the JIT code at which there is a void* immediate that may be repatched. 618 class CodeLocationDataLabelPtr : public CodeLocationCommon { 619 public: 620 CodeLocationDataLabelPtr() 621 { 622 } 623 624 explicit CodeLocationDataLabelPtr(void* location) 625 : CodeLocationCommon(CodePtr(location)) 626 { 627 } 628 }; 629 630 631 // Section 4: PatchBuffer - utility to finalize code generation. 409 // Section 3: PatchBuffer - utility to finalize code generation. 632 410 633 411 static CodePtr trampolineAt(CodeRef ref, Label label) … … 705 483 void patch(DataLabelPtr label, CodeLocationLabel value) 706 484 { 707 AssemblerType::patchPointer(code(), label.m_label, value. getJumpDestination());485 AssemblerType::patchPointer(code(), label.m_label, value.executableAddress()); 708 486 } 709 487 … … 875 653 876 654 877 // Section 5: Misc admin methods655 // Section 4: Misc admin methods 878 656 879 657 size_t size() … … 937 715 }; 938 716 939 940 template <class AssemblerType>941 typename AbstractMacroAssembler<AssemblerType>::CodeLocationInstruction AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::instructionAtOffset(int offset)942 {943 return typename AbstractMacroAssembler::CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset);944 }945 946 template <class AssemblerType>947 typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset)948 {949 return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset);950 }951 952 template <class AssemblerType>953 typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset)954 {955 return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset);956 }957 958 template <class AssemblerType>959 typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset)960 {961 return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);962 }963 964 template <class AssemblerType>965 typename AbstractMacroAssembler<AssemblerType>::CodeLocationNearCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::nearCallAtOffset(int offset)966 {967 return typename AbstractMacroAssembler::CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset);968 }969 970 template <class AssemblerType>971 typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset)972 {973 return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset);974 }975 976 template <class AssemblerType>977 typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset)978 {979 return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset);980 }981 982 717 } // namespace JSC 983 718 -
trunk/JavaScriptCore/assembler/CodeLocation.h
r44705 r44711 1 1 /* 2 * Copyright (C) 200 8Apple Inc. All rights reserved.2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #ifndef AbstractMacroAssembler_h27 #define AbstractMacroAssembler_h26 #ifndef CodeLocation_h 27 #define CodeLocation_h 28 28 29 29 #include <wtf/Platform.h> 30 30 31 31 #include <MacroAssemblerCodeRef.h> 32 #include <wtf/Noncopyable.h>33 #include <wtf/UnusedParam.h>34 32 35 33 #if ENABLE(ASSEMBLER) 36 34 37 // FIXME: keep transitioning this out into MacroAssemblerX86_64.38 #if PLATFORM(X86_64)39 #define REPTACH_OFFSET_CALL_R11 340 #endif41 42 35 namespace JSC { 43 36 44 template <class AssemblerType> 45 class AbstractMacroAssembler { 37 class CodeLocationInstruction; 38 class CodeLocationLabel; 39 class CodeLocationJump; 40 class CodeLocationCall; 41 class CodeLocationNearCall; 42 class CodeLocationDataLabel32; 43 class CodeLocationDataLabelPtr; 44 45 // The CodeLocation* types are all pretty much do-nothing wrappers around 46 // CodePtr (or MacroAssemblerCodePtr, to give it its full name). These 47 // classes only exist to provide type-safety when linking and patching code. 48 // 49 // The one new piece of functionallity introduced by these classes is the 50 // ability to create (or put another way, to re-discover) another CodeLocation 51 // at an offset from one you already know. When patching code to optimize it 52 // we often want to patch a number of instructions that are short, fixed 53 // offsets apart. To reduce memory overhead we will only retain a pointer to 54 // one of the instructions, and we will use the *AtOffset methods provided by 55 // CodeLocationCommon to find the other points in the code to modify. 56 class CodeLocationCommon : public MacroAssemblerCodePtr { 46 57 public: 47 typedef MacroAssemblerCodePtr CodePtr; 48 typedef MacroAssemblerCodeRef CodeRef; 58 CodeLocationInstruction instructionAtOffset(int offset); 59 CodeLocationLabel labelAtOffset(int offset); 60 CodeLocationJump jumpAtOffset(int offset); 61 CodeLocationCall callAtOffset(int offset); 62 CodeLocationNearCall nearCallAtOffset(int offset); 63 CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset); 64 CodeLocationDataLabel32 dataLabel32AtOffset(int offset); 49 65 50 class Jump; 51 class PatchBuffer; 52 class RepatchBuffer; 53 class CodeLocationInstruction; 54 class CodeLocationLabel; 55 class CodeLocationJump; 56 class CodeLocationCall; 57 class CodeLocationNearCall; 58 class CodeLocationDataLabel32; 59 class CodeLocationDataLabelPtr; 60 61 typedef typename AssemblerType::RegisterID RegisterID; 62 typedef typename AssemblerType::FPRegisterID FPRegisterID; 63 typedef typename AssemblerType::JmpSrc JmpSrc; 64 typedef typename AssemblerType::JmpDst JmpDst; 65 66 67 // Section 1: MacroAssembler operand types 68 // 69 // The following types are used as operands to MacroAssembler operations, 70 // describing immediate and memory operands to the instructions to be planted. 71 72 73 enum Scale { 74 TimesOne, 75 TimesTwo, 76 TimesFour, 77 TimesEight, 78 }; 79 80 // Address: 81 // 82 // Describes a simple base-offset address. 83 struct Address { 84 explicit Address(RegisterID base, int32_t offset = 0) 85 : base(base) 86 , offset(offset) 87 { 88 } 89 90 RegisterID base; 91 int32_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(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 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 PLATFORM(ARM_V7) 185 , m_isPointer(false) 186 #endif 187 { 188 } 189 190 #if !PLATFORM(X86_64) 191 explicit Imm32(ImmPtr ptr) 192 : m_value(ptr.asIntptr()) 193 #if PLATFORM(ARM_V7) 194 , m_isPointer(true) 195 #endif 196 { 197 } 198 #endif 199 200 int32_t m_value; 201 #if PLATFORM(ARM_V7) 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 bool m_isPointer; 209 #endif 210 }; 211 212 213 // Section 2: MacroAssembler code buffer handles 214 // 215 // The following types are used to reference items in the code buffer 216 // during JIT code generation. For example, the type Jump is used to 217 // track the location of a jump instruction so that it may later be 218 // linked to a label marking its destination. 219 220 221 // Label: 222 // 223 // A Label records a point in the generated instruction stream, typically such that 224 // it may be used as a destination for a jump. 225 class Label { 226 template<class TemplateAssemblerType> 227 friend class AbstractMacroAssembler; 228 friend class Jump; 229 friend class MacroAssemblerCodeRef; 230 friend class PatchBuffer; 231 232 public: 233 Label() 234 { 235 } 236 237 Label(AbstractMacroAssembler<AssemblerType>* masm) 238 : m_label(masm->m_assembler.label()) 239 { 240 } 241 242 bool isUsed() const { return m_label.isUsed(); } 243 void used() { m_label.used(); } 244 private: 245 JmpDst m_label; 246 }; 247 248 // DataLabelPtr: 249 // 250 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be 251 // patched after the code has been generated. 252 class DataLabelPtr { 253 template<class TemplateAssemblerType> 254 friend class AbstractMacroAssembler; 255 friend class PatchBuffer; 256 public: 257 DataLabelPtr() 258 { 259 } 260 261 DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm) 262 : m_label(masm->m_assembler.label()) 263 { 264 } 265 266 private: 267 JmpDst m_label; 268 }; 269 270 // DataLabel32: 271 // 272 // A DataLabelPtr is used to refer to a location in the code containing a pointer to be 273 // patched after the code has been generated. 274 class DataLabel32 { 275 template<class TemplateAssemblerType> 276 friend class AbstractMacroAssembler; 277 friend class PatchBuffer; 278 public: 279 DataLabel32() 280 { 281 } 282 283 DataLabel32(AbstractMacroAssembler<AssemblerType>* masm) 284 : m_label(masm->m_assembler.label()) 285 { 286 } 287 288 private: 289 JmpDst m_label; 290 }; 291 292 // Call: 293 // 294 // A Call object is a reference to a call instruction that has been planted 295 // into the code buffer - it is typically used to link the call, setting the 296 // relative offset such that when executed it will call to the desired 297 // destination. 298 class Call { 299 template<class TemplateAssemblerType> 300 friend class AbstractMacroAssembler; 301 friend class PatchBuffer; 302 public: 303 enum Flags { 304 None = 0x0, 305 Linkable = 0x1, 306 Near = 0x2, 307 LinkableNear = 0x3, 308 }; 309 310 Call() 311 : m_flags(None) 312 { 313 } 314 315 Call(JmpSrc jmp, Flags flags) 316 : m_jmp(jmp) 317 , m_flags(flags) 318 { 319 } 320 321 bool isFlagSet(Flags flag) 322 { 323 return m_flags & flag; 324 } 325 326 static Call fromTailJump(Jump jump) 327 { 328 return Call(jump.m_jmp, Linkable); 329 } 330 331 private: 332 JmpSrc m_jmp; 333 Flags m_flags; 334 }; 335 336 // Jump: 337 // 338 // A jump object is a reference to a jump instruction that has been planted 339 // into the code buffer - it is typically used to link the jump, setting the 340 // relative offset such that when executed it will jump to the desired 341 // destination. 342 class Jump { 343 template<class TemplateAssemblerType> 344 friend class AbstractMacroAssembler; 345 friend class Call; 346 friend class PatchBuffer; 347 public: 348 Jump() 349 { 350 } 351 352 Jump(JmpSrc jmp) 353 : m_jmp(jmp) 354 { 355 } 356 357 void link(AbstractMacroAssembler<AssemblerType>* masm) 358 { 359 masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label()); 360 } 361 362 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) 363 { 364 masm->m_assembler.linkJump(m_jmp, label.m_label); 365 } 366 367 private: 368 JmpSrc m_jmp; 369 }; 370 371 // JumpList: 372 // 373 // A JumpList is a set of Jump objects. 374 // All jumps in the set will be linked to the same destination. 375 class JumpList { 376 friend class PatchBuffer; 377 378 public: 379 void link(AbstractMacroAssembler<AssemblerType>* masm) 380 { 381 size_t size = m_jumps.size(); 382 for (size_t i = 0; i < size; ++i) 383 m_jumps[i].link(masm); 384 m_jumps.clear(); 385 } 386 387 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) 388 { 389 size_t size = m_jumps.size(); 390 for (size_t i = 0; i < size; ++i) 391 m_jumps[i].linkTo(label, masm); 392 m_jumps.clear(); 393 } 394 395 void append(Jump jump) 396 { 397 m_jumps.append(jump); 398 } 399 400 void append(JumpList& other) 401 { 402 m_jumps.append(other.m_jumps.begin(), other.m_jumps.size()); 403 } 404 405 bool empty() 406 { 407 return !m_jumps.size(); 408 } 409 410 private: 411 Vector<Jump, 16> m_jumps; 412 }; 413 414 415 // Section 3: MacroAssembler JIT instruction stream handles. 416 // 417 // The MacroAssembler supported facilities to modify a JIT generated 418 // instruction stream after it has been generated (relinking calls and 419 // jumps, and repatching data values). The following types are used 420 // to store handles into the underlying instruction stream, the type 421 // providing semantic information as to what it is that is in the 422 // instruction stream at this point, and thus what operations may be 423 // performed on it. 424 425 426 // CodeLocationCommon: 427 // 428 // Base type for other CodeLocation* types. A postion in the JIT genertaed 429 // instruction stream, without any semantic information. 430 class CodeLocationCommon { 431 friend class RepatchBuffer; 432 433 public: 434 CodeLocationCommon() 435 { 436 } 437 438 // In order to avoid the need to store multiple handles into the 439 // instructions stream, where the code generation is deterministic 440 // and the labels will always be a fixed distance apart, these 441 // methods may be used to recover a handle that has nopw been 442 // retained, based on a known fixed relative offset from one that has. 443 CodeLocationInstruction instructionAtOffset(int offset); 444 CodeLocationLabel labelAtOffset(int offset); 445 CodeLocationJump jumpAtOffset(int offset); 446 CodeLocationCall callAtOffset(int offset); 447 CodeLocationNearCall nearCallAtOffset(int offset); 448 CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset); 449 CodeLocationDataLabel32 dataLabel32AtOffset(int offset); 450 451 protected: 452 explicit CodeLocationCommon(CodePtr location) 453 : m_location(location) 454 { 455 } 456 457 void* dataLocation() { return m_location.dataLocation(); } 458 void* executableAddress() { return m_location.executableAddress(); } 459 460 void reset() 461 { 462 m_location = CodePtr(); 463 } 464 465 private: 466 CodePtr m_location; 467 }; 468 469 // CodeLocationInstruction: 470 // 471 // An arbitrary instruction in the JIT code. 472 class CodeLocationInstruction : public CodeLocationCommon { 473 public: 474 CodeLocationInstruction() 475 { 476 } 477 478 explicit CodeLocationInstruction(void* location) 479 : CodeLocationCommon(CodePtr(location)) 480 { 481 } 482 }; 483 484 // CodeLocationLabel: 485 // 486 // A point in the JIT code maked with a label. 487 class CodeLocationLabel : public CodeLocationCommon { 488 friend class CodeLocationCommon; 489 friend class CodeLocationJump; 490 friend class CodeLocationCall; 491 friend class CodeLocationNearCall; 492 friend class PatchBuffer; 493 friend class RepatchBuffer; 494 495 public: 496 CodeLocationLabel() 497 { 498 } 499 500 void* addressForSwitch() { return this->executableAddress(); } 501 void* addressForExceptionHandler() { return this->executableAddress(); } 502 void* addressForJSR() { return this->executableAddress(); } 503 504 bool operator!() 505 { 506 return !this->executableAddress(); 507 } 508 509 void reset() 510 { 511 CodeLocationCommon::reset(); 512 } 513 514 private: 515 explicit CodeLocationLabel(CodePtr location) 516 : CodeLocationCommon(location) 517 { 518 } 519 520 explicit CodeLocationLabel(void* location) 521 : CodeLocationCommon(CodePtr(location)) 522 { 523 } 524 525 void* getJumpDestination() { return this->executableAddress(); } 526 }; 527 528 // CodeLocationJump: 529 // 530 // A point in the JIT code at which there is a jump instruction. 531 class CodeLocationJump : public CodeLocationCommon { 532 friend class CodeLocationCommon; 533 friend class PatchBuffer; 534 public: 535 CodeLocationJump() 536 { 537 } 538 539 explicit CodeLocationJump(void* location) 540 : CodeLocationCommon(CodePtr(location)) 541 { 542 } 543 }; 544 545 // CodeLocationCall: 546 // 547 // A point in the JIT code at which there is a call instruction. 548 class CodeLocationCall : public CodeLocationCommon { 549 public: 550 CodeLocationCall() 551 { 552 } 553 554 explicit CodeLocationCall(CodePtr location) 555 : CodeLocationCommon(location) 556 { 557 } 558 559 explicit CodeLocationCall(void* location) 560 : CodeLocationCommon(CodePtr(location)) 561 { 562 } 563 564 // This methods returns the value that will be set as the return address 565 // within a function that has been called from this call instruction. 566 void* calleeReturnAddressValue() 567 { 568 return this->executableAddress(); 569 } 570 571 }; 572 573 // CodeLocationNearCall: 574 // 575 // A point in the JIT code at which there is a call instruction with near linkage. 576 class CodeLocationNearCall : public CodeLocationCommon { 577 public: 578 CodeLocationNearCall() 579 { 580 } 581 582 explicit CodeLocationNearCall(CodePtr location) 583 : CodeLocationCommon(location) 584 { 585 } 586 587 explicit CodeLocationNearCall(void* location) 588 : CodeLocationCommon(CodePtr(location)) 589 { 590 } 591 592 // This methods returns the value that will be set as the return address 593 // within a function that has been called from this call instruction. 594 void* calleeReturnAddressValue() 595 { 596 return this->executableAddress(); 597 } 598 }; 599 600 // CodeLocationDataLabel32: 601 // 602 // A point in the JIT code at which there is an int32_t immediate that may be repatched. 603 class CodeLocationDataLabel32 : public CodeLocationCommon { 604 public: 605 CodeLocationDataLabel32() 606 { 607 } 608 609 explicit CodeLocationDataLabel32(void* location) 610 : CodeLocationCommon(CodePtr(location)) 611 { 612 } 613 }; 614 615 // CodeLocationDataLabelPtr: 616 // 617 // A point in the JIT code at which there is a void* immediate that may be repatched. 618 class CodeLocationDataLabelPtr : public CodeLocationCommon { 619 public: 620 CodeLocationDataLabelPtr() 621 { 622 } 623 624 explicit CodeLocationDataLabelPtr(void* location) 625 : CodeLocationCommon(CodePtr(location)) 626 { 627 } 628 }; 629 630 631 // Section 4: PatchBuffer - utility to finalize code generation. 632 633 static CodePtr trampolineAt(CodeRef ref, Label label) 66 protected: 67 CodeLocationCommon() 634 68 { 635 return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));636 69 } 637 70 638 // PatchBuffer: 639 // 640 // This class assists in linking code generated by the macro assembler, once code generation 641 // has been completed, and the code has been copied to is final location in memory. At this 642 // time pointers to labels within the code may be resolved, and relative offsets to external 643 // addresses may be fixed. 644 // 645 // Specifically: 646 // * Jump objects may be linked to external targets, 647 // * The address of Jump objects may taken, such that it can later be relinked. 648 // * The return address of a Jump object representing a call may be acquired. 649 // * The address of a Label pointing into the code may be resolved. 650 // * The value referenced by a DataLabel may be fixed. 651 // 652 // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return 653 // address of calls, as opposed to a point that can be used to later relink a Jump - 654 // possibly wrap the later up in an object that can do just that). 655 class PatchBuffer : public Noncopyable { 656 public: 657 // Note: Initialization sequence is significant, since executablePool is a PassRefPtr. 658 // First, executablePool is copied into m_executablePool, then the initialization of 659 // m_code uses m_executablePool, *not* executablePool, since this is no longer valid. 660 PatchBuffer(AbstractMacroAssembler<AssemblerType>* masm, PassRefPtr<ExecutablePool> executablePool) 661 : m_executablePool(executablePool) 662 , m_code(masm->m_assembler.executableCopy(m_executablePool.get())) 663 , m_size(masm->m_assembler.size()) 664 #ifndef NDEBUG 665 , m_completed(false) 666 #endif 667 { 668 } 669 670 ~PatchBuffer() 671 { 672 ASSERT(m_completed); 673 } 674 675 // These methods are used to link or set values at code generation time. 676 677 void link(Call call, FunctionPtr function) 678 { 679 ASSERT(call.isFlagSet(Call::Linkable)); 680 #if PLATFORM(X86_64) 681 if (!call.isFlagSet(Call::Near)) { 682 char* callLocation = reinterpret_cast<char*>(AssemblerType::getRelocatedAddress(code(), call.m_jmp)) - REPTACH_OFFSET_CALL_R11; 683 AssemblerType::patchPointerForCall(callLocation, function.value()); 684 } else 685 #endif 686 AssemblerType::linkCall(code(), call.m_jmp, function.value()); 687 } 688 689 void link(Jump jump, CodeLocationLabel label) 690 { 691 AssemblerType::linkJump(code(), jump.m_jmp, label.dataLocation()); 692 } 693 694 void link(JumpList list, CodeLocationLabel label) 695 { 696 for (unsigned i = 0; i < list.m_jumps.size(); ++i) 697 AssemblerType::linkJump(code(), list.m_jumps[i].m_jmp, label.dataLocation()); 698 } 699 700 void patch(DataLabelPtr label, void* value) 701 { 702 AssemblerType::patchPointer(code(), label.m_label, value); 703 } 704 705 void patch(DataLabelPtr label, CodeLocationLabel value) 706 { 707 AssemblerType::patchPointer(code(), label.m_label, value.getJumpDestination()); 708 } 709 710 // These methods are used to obtain handles to allow the code to be relinked / repatched later. 711 712 CodeLocationCall locationOf(Call call) 713 { 714 ASSERT(call.isFlagSet(Call::Linkable)); 715 ASSERT(!call.isFlagSet(Call::Near)); 716 return CodeLocationCall(AssemblerType::getRelocatedAddress(code(), call.m_jmp)); 717 } 718 719 CodeLocationNearCall locationOfNearCall(Call call) 720 { 721 ASSERT(call.isFlagSet(Call::Linkable)); 722 ASSERT(call.isFlagSet(Call::Near)); 723 return CodeLocationNearCall(AssemblerType::getRelocatedAddress(code(), call.m_jmp)); 724 } 725 726 CodeLocationLabel locationOf(Label label) 727 { 728 return CodeLocationLabel(AssemblerType::getRelocatedAddress(code(), label.m_label)); 729 } 730 731 CodeLocationDataLabelPtr locationOf(DataLabelPtr label) 732 { 733 return CodeLocationDataLabelPtr(AssemblerType::getRelocatedAddress(code(), label.m_label)); 734 } 735 736 CodeLocationDataLabel32 locationOf(DataLabel32 label) 737 { 738 return CodeLocationDataLabel32(AssemblerType::getRelocatedAddress(code(), label.m_label)); 739 } 740 741 // This method obtains the return address of the call, given as an offset from 742 // the start of the code. 743 unsigned returnAddressOffset(Call call) 744 { 745 return AssemblerType::getCallReturnOffset(call.m_jmp); 746 } 747 748 // Upon completion of all patching either 'finalizeCode()' or 'finalizeCodeAddendum()' should be called 749 // once to complete generation of the code. 'finalizeCode()' is suited to situations 750 // where the executable pool must also be retained, the lighter-weight 'finalizeCodeAddendum()' is 751 // suited to adding to an existing allocation. 752 CodeRef finalizeCode() 753 { 754 performFinalization(); 755 756 return CodeRef(m_code, m_executablePool, m_size); 757 } 758 CodeLocationLabel finalizeCodeAddendum() 759 { 760 performFinalization(); 761 762 return CodeLocationLabel(code()); 763 } 764 765 private: 766 // Keep this private! - the underlying code should only be obtained externally via 767 // finalizeCode() or finalizeCodeAddendum(). 768 void* code() 769 { 770 return m_code; 771 } 772 773 void performFinalization() 774 { 775 #ifndef NDEBUG 776 ASSERT(!m_completed); 777 m_completed = true; 778 #endif 779 780 ExecutableAllocator::makeExecutable(code(), m_size); 781 } 782 783 RefPtr<ExecutablePool> m_executablePool; 784 void* m_code; 785 size_t m_size; 786 #ifndef NDEBUG 787 bool m_completed; 788 #endif 789 }; 790 791 class RepatchBuffer { 792 public: 793 RepatchBuffer() 794 { 795 } 796 797 void relink(CodeLocationJump jump, CodeLocationLabel destination) 798 { 799 AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation()); 800 } 801 802 void relink(CodeLocationCall call, CodeLocationLabel destination) 803 { 804 #if PLATFORM(X86_64) 805 repatch(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11), destination.executableAddress()); 806 #else 807 AssemblerType::relinkCall(call.dataLocation(), destination.executableAddress()); 808 #endif 809 } 810 811 void relink(CodeLocationCall call, FunctionPtr destination) 812 { 813 #if PLATFORM(X86_64) 814 repatch(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11), destination.executableAddress()); 815 #else 816 AssemblerType::relinkCall(call.dataLocation(), destination.executableAddress()); 817 #endif 818 } 819 820 void relink(CodeLocationNearCall nearCall, CodePtr destination) 821 { 822 AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress()); 823 } 824 825 void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination) 826 { 827 AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress()); 828 } 829 830 void relink(CodeLocationNearCall nearCall, FunctionPtr destination) 831 { 832 AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress()); 833 } 834 835 void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value) 836 { 837 AssemblerType::repatchInt32(dataLabel32.dataLocation(), value); 838 } 839 840 void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value) 841 { 842 AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value); 843 } 844 845 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 846 { 847 relink(CodeLocationCall(CodePtr(returnAddress)), label); 848 } 849 850 void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 851 { 852 relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 853 } 854 855 void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function) 856 { 857 relink(CodeLocationCall(CodePtr(returnAddress)), function); 858 } 859 860 void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label) 861 { 862 relink(CodeLocationNearCall(CodePtr(returnAddress)), label); 863 } 864 865 void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction) 866 { 867 relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction)); 868 } 869 870 void repatchLoadPtrToLEA(CodeLocationInstruction instruction) 871 { 872 AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation()); 873 } 874 }; 875 876 877 // Section 5: Misc admin methods 878 879 size_t size() 71 CodeLocationCommon(MacroAssemblerCodePtr location) 72 : MacroAssemblerCodePtr(location) 880 73 { 881 return m_assembler.size();882 74 } 883 884 Label label()885 {886 return Label(this);887 }888 889 Label align()890 {891 m_assembler.align(16);892 return Label(this);893 }894 895 ptrdiff_t differenceBetween(Label from, Jump to)896 {897 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);898 }899 900 ptrdiff_t differenceBetween(Label from, Call to)901 {902 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);903 }904 905 ptrdiff_t differenceBetween(Label from, Label to)906 {907 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);908 }909 910 ptrdiff_t differenceBetween(Label from, DataLabelPtr to)911 {912 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);913 }914 915 ptrdiff_t differenceBetween(Label from, DataLabel32 to)916 {917 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);918 }919 920 ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)921 {922 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);923 }924 925 ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to)926 {927 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);928 }929 930 ptrdiff_t differenceBetween(DataLabelPtr from, Call to)931 {932 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);933 }934 935 protected:936 AssemblerType m_assembler;937 75 }; 938 76 77 class CodeLocationInstruction : public CodeLocationCommon { 78 public: 79 CodeLocationInstruction() {} 80 explicit CodeLocationInstruction(MacroAssemblerCodePtr location) 81 : CodeLocationCommon(location) {} 82 explicit CodeLocationInstruction(void* location) 83 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 84 }; 939 85 940 template <class AssemblerType> 941 typename AbstractMacroAssembler<AssemblerType>::CodeLocationInstruction AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::instructionAtOffset(int offset) 86 class CodeLocationLabel : public CodeLocationCommon { 87 public: 88 CodeLocationLabel() {} 89 explicit CodeLocationLabel(MacroAssemblerCodePtr location) 90 : CodeLocationCommon(location) {} 91 explicit CodeLocationLabel(void* location) 92 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 93 }; 94 95 class CodeLocationJump : public CodeLocationCommon { 96 public: 97 CodeLocationJump() {} 98 explicit CodeLocationJump(MacroAssemblerCodePtr location) 99 : CodeLocationCommon(location) {} 100 explicit CodeLocationJump(void* location) 101 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 102 }; 103 104 class CodeLocationCall : public CodeLocationCommon { 105 public: 106 CodeLocationCall() {} 107 explicit CodeLocationCall(MacroAssemblerCodePtr location) 108 : CodeLocationCommon(location) {} 109 explicit CodeLocationCall(void* location) 110 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 111 }; 112 113 class CodeLocationNearCall : public CodeLocationCommon { 114 public: 115 CodeLocationNearCall() {} 116 explicit CodeLocationNearCall(MacroAssemblerCodePtr location) 117 : CodeLocationCommon(location) {} 118 explicit CodeLocationNearCall(void* location) 119 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 120 }; 121 122 class CodeLocationDataLabel32 : public CodeLocationCommon { 123 public: 124 CodeLocationDataLabel32() {} 125 explicit CodeLocationDataLabel32(MacroAssemblerCodePtr location) 126 : CodeLocationCommon(location) {} 127 explicit CodeLocationDataLabel32(void* location) 128 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 129 }; 130 131 class CodeLocationDataLabelPtr : public CodeLocationCommon { 132 public: 133 CodeLocationDataLabelPtr() {} 134 explicit CodeLocationDataLabelPtr(MacroAssemblerCodePtr location) 135 : CodeLocationCommon(location) {} 136 explicit CodeLocationDataLabelPtr(void* location) 137 : CodeLocationCommon(MacroAssemblerCodePtr(location)) {} 138 }; 139 140 inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset) 942 141 { 943 return typename AbstractMacroAssembler::CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset); 142 ASSERT_VALID_CODE_OFFSET(offset); 143 return CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset); 944 144 } 945 145 946 template <class AssemblerType> 947 typename AbstractMacroAssembler<AssemblerType>::CodeLocationLabel AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::labelAtOffset(int offset) 146 inline CodeLocationLabel CodeLocationCommon::labelAtOffset(int offset) 948 147 { 949 return typename AbstractMacroAssembler::CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset); 148 ASSERT_VALID_CODE_OFFSET(offset); 149 return CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset); 950 150 } 951 151 952 template <class AssemblerType> 953 typename AbstractMacroAssembler<AssemblerType>::CodeLocationJump AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::jumpAtOffset(int offset) 152 inline CodeLocationJump CodeLocationCommon::jumpAtOffset(int offset) 954 153 { 955 return typename AbstractMacroAssembler::CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset); 154 ASSERT_VALID_CODE_OFFSET(offset); 155 return CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset); 956 156 } 957 157 958 template <class AssemblerType> 959 typename AbstractMacroAssembler<AssemblerType>::CodeLocationCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::callAtOffset(int offset) 158 inline CodeLocationCall CodeLocationCommon::callAtOffset(int offset) 960 159 { 961 return typename AbstractMacroAssembler::CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset); 160 ASSERT_VALID_CODE_OFFSET(offset); 161 return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset); 962 162 } 963 163 964 template <class AssemblerType> 965 typename AbstractMacroAssembler<AssemblerType>::CodeLocationNearCall AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::nearCallAtOffset(int offset) 164 inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset) 966 165 { 967 return typename AbstractMacroAssembler::CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset); 166 ASSERT_VALID_CODE_OFFSET(offset); 167 return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset); 968 168 } 969 169 970 template <class AssemblerType> 971 typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabelPtr AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabelPtrAtOffset(int offset) 170 inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset) 972 171 { 973 return typename AbstractMacroAssembler::CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset); 172 ASSERT_VALID_CODE_OFFSET(offset); 173 return CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset); 974 174 } 975 175 976 template <class AssemblerType> 977 typename AbstractMacroAssembler<AssemblerType>::CodeLocationDataLabel32 AbstractMacroAssembler<AssemblerType>::CodeLocationCommon::dataLabel32AtOffset(int offset) 176 inline CodeLocationDataLabel32 CodeLocationCommon::dataLabel32AtOffset(int offset) 978 177 { 979 return typename AbstractMacroAssembler::CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset); 178 ASSERT_VALID_CODE_OFFSET(offset); 179 return CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset); 980 180 } 981 181 … … 984 184 #endif // ENABLE(ASSEMBLER) 985 185 986 #endif // AbstractMacroAssembler_h186 #endif // CodeLocation_h -
trunk/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
r44705 r44711 47 47 ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \ 48 48 ASSERT(reinterpret_cast<intptr_t>(ptr) & 1) 49 #define ASSERT_VALID_CODE_OFFSET(offset) \ 50 ASSERT(!(offset & 1)) // Must be multiple of 2. 49 51 #else 50 52 #define ASSERT_VALID_CODE_POINTER(ptr) \ 51 53 ASSERT(ptr) 54 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes! 52 55 #endif 53 56 … … 146 149 #endif 147 150 151 bool operator!() 152 { 153 return !m_value; 154 } 155 148 156 private: 149 157 void* m_value; -
trunk/JavaScriptCore/bytecode/CodeBlock.h
r44705 r44711 60 60 uint32_t scopeDepth; 61 61 #if ENABLE(JIT) 62 MacroAssembler::CodeLocationLabel nativeCode;62 CodeLocationLabel nativeCode; 63 63 #endif 64 64 }; … … 96 96 97 97 unsigned bytecodeIndex; 98 MacroAssembler::CodeLocationNearCall callReturnLocation;99 MacroAssembler::CodeLocationDataLabelPtr hotPathBegin;100 MacroAssembler::CodeLocationNearCall hotPathOther;98 CodeLocationNearCall callReturnLocation; 99 CodeLocationDataLabelPtr hotPathBegin; 100 CodeLocationNearCall hotPathOther; 101 101 CodeBlock* callee; 102 102 unsigned position; … … 112 112 } 113 113 114 MacroAssembler::CodeLocationCall callReturnLocation;115 MacroAssembler::CodeLocationDataLabelPtr structureLabel;114 CodeLocationCall callReturnLocation; 115 CodeLocationDataLabelPtr structureLabel; 116 116 Structure* cachedStructure; 117 117 }; … … 160 160 inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo) 161 161 { 162 return structureStubInfo->callReturnLocation. calleeReturnAddressValue();162 return structureStubInfo->callReturnLocation.executableAddress(); 163 163 } 164 164 165 165 inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo) 166 166 { 167 return callLinkInfo->callReturnLocation. calleeReturnAddressValue();167 return callLinkInfo->callReturnLocation.executableAddress(); 168 168 } 169 169 170 170 inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo) 171 171 { 172 return methodCallLinkInfo->callReturnLocation. calleeReturnAddressValue();172 return methodCallLinkInfo->callReturnLocation.executableAddress(); 173 173 } 174 174 -
trunk/JavaScriptCore/bytecode/Instruction.h
r43855 r44711 39 39 namespace JSC { 40 40 41 // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type MacroAssembler::CodeLocationLabel),41 // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel), 42 42 // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't 43 43 // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best 44 44 // solution for now - will need to something smarter if/when we actually want mixed-mode operation. 45 45 #if ENABLE(JIT) 46 typedef MacroAssembler::CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;46 typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType; 47 47 #else 48 48 typedef void* PolymorphicAccessStructureListStubRoutineType; -
trunk/JavaScriptCore/bytecode/JumpTable.h
r40854 r44711 41 41 int32_t branchOffset; 42 42 #if ENABLE(JIT) 43 MacroAssembler::CodeLocationLabel ctiOffset;43 CodeLocationLabel ctiOffset; 44 44 #endif 45 45 }; … … 49 49 StringOffsetTable offsetTable; 50 50 #if ENABLE(JIT) 51 MacroAssembler::CodeLocationLabel ctiDefault; // FIXME: it should not be necessary to store this.51 CodeLocationLabel ctiDefault; // FIXME: it should not be necessary to store this. 52 52 #endif 53 53 … … 62 62 63 63 #if ENABLE(JIT) 64 inline MacroAssembler::CodeLocationLabel ctiForValue(UString::Rep* value)64 inline CodeLocationLabel ctiForValue(UString::Rep* value) 65 65 { 66 66 StringOffsetTable::const_iterator end = offsetTable.end(); … … 78 78 int32_t min; 79 79 #if ENABLE(JIT) 80 Vector< MacroAssembler::CodeLocationLabel> ctiOffsets;81 MacroAssembler::CodeLocationLabel ctiDefault;80 Vector<CodeLocationLabel> ctiOffsets; 81 CodeLocationLabel ctiDefault; 82 82 #endif 83 83 … … 90 90 91 91 #if ENABLE(JIT) 92 inline MacroAssembler::CodeLocationLabel ctiForValue(int32_t value)92 inline CodeLocationLabel ctiForValue(int32_t value) 93 93 { 94 94 if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size()) -
trunk/JavaScriptCore/bytecode/StructureStubInfo.h
r40846 r44711 145 145 } u; 146 146 147 MacroAssembler::CodeLocationLabel stubRoutine;148 MacroAssembler::CodeLocationCall callReturnLocation;149 MacroAssembler::CodeLocationLabel hotPathBegin;147 CodeLocationLabel stubRoutine; 148 CodeLocationCall callReturnLocation; 149 CodeLocationLabel hotPathBegin; 150 150 }; 151 151 -
trunk/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r44224 r44711 1816 1816 { 1817 1817 #if ENABLE(JIT) 1818 HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, MacroAssembler::CodeLocationLabel() };1818 HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() }; 1819 1819 #else 1820 1820 HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth }; -
trunk/JavaScriptCore/jit/JIT.cpp
r44705 r44711 478 478 // Link absolute addresses for jsr 479 479 for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter) 480 patchBuffer.patch(iter->storeLocation, patchBuffer.locationOf(iter->target). addressForJSR());480 patchBuffer.patch(iter->storeLocation, patchBuffer.locationOf(iter->target).executableAddress()); 481 481 482 482 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) -
trunk/JavaScriptCore/jit/JITStubs.cpp
r44705 r44711 932 932 if (stubInfo->opcodeID == op_get_by_id_self) { 933 933 ASSERT(!stubInfo->stubRoutine); 934 polymorphicStructureList = new PolymorphicAccessStructureList( MacroAssembler::CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);934 polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); 935 935 stubInfo->initGetByIdSelfList(polymorphicStructureList, 2); 936 936 } else { … … 958 958 case op_get_by_id_proto: 959 959 prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure); 960 stubInfo->stubRoutine .reset();960 stubInfo->stubRoutine = CodeLocationLabel(); 961 961 stubInfo->initGetByIdProtoList(prototypeStructureList, 2); 962 962 break; 963 963 case op_get_by_id_chain: 964 964 prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain); 965 stubInfo->stubRoutine .reset();965 stubInfo->stubRoutine = CodeLocationLabel(); 966 966 stubInfo->initGetByIdProtoList(prototypeStructureList, 2); 967 967 break; … … 2334 2334 2335 2335 stackFrame.callFrame = callFrame; 2336 void* catchRoutine = handler->nativeCode. addressForExceptionHandler();2336 void* catchRoutine = handler->nativeCode.executableAddress(); 2337 2337 ASSERT(catchRoutine); 2338 2338 STUB_SET_RETURN_ADDRESS(catchRoutine); … … 2542 2542 2543 2543 if (scrutinee.isInt32Fast()) 2544 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast()). addressForSwitch();2544 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast()).executableAddress(); 2545 2545 else { 2546 2546 double value; 2547 2547 int32_t intValue; 2548 2548 if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value)) 2549 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(intValue). addressForSwitch();2549 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(intValue).executableAddress(); 2550 2550 else 2551 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault. addressForSwitch();2551 return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress(); 2552 2552 } 2553 2553 } … … 2562 2562 CodeBlock* codeBlock = callFrame->codeBlock(); 2563 2563 2564 void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault. addressForSwitch();2564 void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress(); 2565 2565 2566 2566 if (scrutinee.isString()) { 2567 2567 UString::Rep* value = asString(scrutinee)->value().rep(); 2568 2568 if (value->size() == 1) 2569 result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]). addressForSwitch();2569 result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress(); 2570 2570 } 2571 2571 … … 2582 2582 CodeBlock* codeBlock = callFrame->codeBlock(); 2583 2583 2584 void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault. addressForSwitch();2584 void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress(); 2585 2585 2586 2586 if (scrutinee.isString()) { 2587 2587 UString::Rep* value = asString(scrutinee)->value().rep(); 2588 result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value). addressForSwitch();2588 result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress(); 2589 2589 } 2590 2590 … … 2690 2690 2691 2691 stackFrame.callFrame = callFrame; 2692 void* catchRoutine = handler->nativeCode. addressForExceptionHandler();2692 void* catchRoutine = handler->nativeCode.executableAddress(); 2693 2693 ASSERT(catchRoutine); 2694 2694 STUB_SET_RETURN_ADDRESS(catchRoutine);
Note:
See TracChangeset
for help on using the changeset viewer.