Changeset 41089 in webkit for trunk/JavaScriptCore/assembler
- Timestamp:
- Feb 19, 2009, 2:51:40 PM (16 years ago)
- Location:
- trunk/JavaScriptCore/assembler
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r40879 r41089 266 266 friend class AbstractMacroAssembler; 267 267 public: 268 enum Flags { 269 None = 0x0, 270 Linkable = 0x1, 271 Near = 0x2, 272 LinkableNear = 0x3, 273 }; 274 268 275 Call() 269 { 270 } 271 272 Call(JmpSrc jmp, bool isRelative) 276 : m_flags(None) 277 { 278 } 279 280 Call(JmpSrc jmp, Flags flags) 273 281 : m_jmp(jmp) 274 #ifndef NDEBUG 275 , isRelative(isRelative) 276 #endif 277 { 278 #ifdef NDEBUG 279 #pragma unused(isRelative) 280 #endif 281 } 282 283 void link(AbstractMacroAssembler<AssemblerType>* masm) 284 { 285 ASSERT(isRelative); 286 masm->m_assembler.link(m_jmp, masm->m_assembler.label()); 287 } 288 289 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) 290 { 291 ASSERT(isRelative); 292 masm->m_assembler.link(m_jmp, label.m_label); 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); 293 294 } 294 295 295 296 private: 296 297 JmpSrc m_jmp; 297 #ifndef NDEBUG 298 bool isRelative; 299 #endif 298 Flags m_flags; 300 299 }; 301 300 … … 310 309 template<class AssemblerType_T> 311 310 friend class AbstractMacroAssembler; 311 friend class Call; 312 312 public: 313 313 Jump() … … 322 322 void link(AbstractMacroAssembler<AssemblerType>* masm) 323 323 { 324 masm->m_assembler.link (m_jmp, masm->m_assembler.label());324 masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label()); 325 325 } 326 326 327 327 void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) 328 328 { 329 masm->m_assembler.link (m_jmp, label.m_label);329 masm->m_assembler.linkJump(m_jmp, label.m_label); 330 330 } 331 331 … … 461 461 void relink(CodeLocationLabel destination) 462 462 { 463 AssemblerType::patch BranchOffset(reinterpret_cast<intptr_t>(this->m_location), destination.m_location);463 AssemblerType::patchJump(reinterpret_cast<intptr_t>(this->m_location), destination.m_location); 464 464 } 465 465 … … 485 485 void relink(FunctionSig* function) 486 486 { 487 AssemblerType::patch BranchOffset(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function));487 AssemblerType::patchMacroAssemblerCall(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(function)); 488 488 } 489 489 … … 502 502 }; 503 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 504 535 // CodeLocationDataLabel32: 505 536 // … … 561 592 void relinkCallerToFunction(FunctionSig* newCalleeFunction) 562 593 { 563 AssemblerType::patchBranchOffset(reinterpret_cast<intptr_t>(this->m_location), reinterpret_cast<void*>(newCalleeFunction)); 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)); 564 601 } 565 602 … … 616 653 void link(Call call, FunctionSig* function) 617 654 { 618 AssemblerType::link(m_code, call.m_jmp, reinterpret_cast<void*>(function)); 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 619 666 } 620 667 … … 622 669 void linkTailRecursive(Jump jump, FunctionSig* function) 623 670 { 624 AssemblerType::link (m_code, jump.m_jmp, reinterpret_cast<void*>(function));671 AssemblerType::linkJump(m_code, jump.m_jmp, reinterpret_cast<void*>(function)); 625 672 } 626 673 … … 628 675 void linkTailRecursive(JumpList list, FunctionSig* function) 629 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 { 630 689 for (unsigned i = 0; i < list.m_jumps.size(); ++i) 631 AssemblerType::link(m_code, list.m_jumps[i].m_jmp, reinterpret_cast<void*>(function)); 632 } 633 634 void link(Jump jump, CodeLocationLabel label) 635 { 636 AssemblerType::link(m_code, jump.m_jmp, label.m_location); 637 } 638 639 void link(JumpList list, CodeLocationLabel label) 640 { 641 for (unsigned i = 0; i < list.m_jumps.size(); ++i) 642 AssemblerType::link(m_code, list.m_jumps[i].m_jmp, label.m_location); 690 AssemblerType::linkJump(m_code, list.m_jumps[i].m_jmp, label.m_location); 643 691 } 644 692 … … 652 700 CodeLocationCall locationOf(Call call) 653 701 { 654 ASSERT(call.isRelative); 702 ASSERT(call.isFlagSet(Call::Linkable)); 703 ASSERT(!call.isFlagSet(Call::Near)); 655 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)); 656 712 } 657 713 … … 732 788 733 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) 734 795 { 735 796 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); -
trunk/JavaScriptCore/assembler/MacroAssemblerX86.h
r40660 r41089 44 44 using MacroAssemblerX86Common::store32; 45 45 using MacroAssemblerX86Common::branch32; 46 using MacroAssemblerX86Common::call; 46 47 47 48 void add32(Imm32 imm, RegisterID src, RegisterID dest) … … 82 83 } 83 84 85 Call call() 86 { 87 return Call(m_assembler.call(), Call::Linkable); 88 } 89 90 Call tailRecursiveCall() 91 { 92 return Call::fromTailJump(jump()); 93 } 94 95 Call makeTailRecursiveCall(Jump oldJump) 96 { 97 return Call::fromTailJump(oldJump); 98 } 99 100 84 101 Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) 85 102 { -
trunk/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r40963 r41089 530 530 } 531 531 532 Call call()533 { 534 return Call(m_assembler.call(), true);532 Call nearCall() 533 { 534 return Call(m_assembler.call(), Call::LinkableNear); 535 535 } 536 536 537 537 Call call(RegisterID target) 538 538 { 539 return Call(m_assembler.call(target), false);539 return Call(m_assembler.call(target), Call::None); 540 540 } 541 541 -
trunk/JavaScriptCore/assembler/MacroAssemblerX86_64.h
r40660 r41089 46 46 using MacroAssemblerX86Common::load32; 47 47 using MacroAssemblerX86Common::store32; 48 using MacroAssemblerX86Common::call; 48 49 49 50 void add32(Imm32 imm, AbsoluteAddress address) … … 78 79 } 79 80 81 Call call() 82 { 83 DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister); 84 Call result = Call(m_assembler.call(scratchRegister), Call::Linkable); 85 ASSERT(differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11); 86 return result; 87 } 88 89 Call tailRecursiveCall() 90 { 91 DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister); 92 Jump newJump = Jump(m_assembler.jmp_r(scratchRegister)); 93 ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11); 94 return Call::fromTailJump(newJump); 95 } 96 97 Call makeTailRecursiveCall(Jump oldJump) 98 { 99 oldJump.link(this); 100 DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister); 101 Jump newJump = Jump(m_assembler.jmp_r(scratchRegister)); 102 ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11); 103 return Call::fromTailJump(newJump); 104 } 80 105 81 106 … … 327 352 } 328 353 354 DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest) 355 { 356 m_assembler.movq_i64r(initialValue.asIntptr(), dest); 357 return DataLabelPtr(this); 358 } 359 329 360 Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) 330 361 { 331 m_assembler.movq_i64r(initialRightValue.asIntptr(), scratchRegister); 332 dataLabel = DataLabelPtr(this); 362 dataLabel = moveWithPatch(initialRightValue, scratchRegister); 333 363 return branchPtr(cond, left, scratchRegister); 334 364 } … … 336 366 Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) 337 367 { 338 m_assembler.movq_i64r(initialRightValue.asIntptr(), scratchRegister); 339 dataLabel = DataLabelPtr(this); 368 dataLabel = moveWithPatch(initialRightValue, scratchRegister); 340 369 return branchPtr(cond, left, scratchRegister); 341 370 } … … 343 372 DataLabelPtr storePtrWithPatch(Address address) 344 373 { 345 m_assembler.movq_i64r(0, scratchRegister); 346 DataLabelPtr label(this); 374 DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister); 347 375 storePtr(scratchRegister, address); 348 376 return label; -
trunk/JavaScriptCore/assembler/X86Assembler.h
r41051 r41089 42 42 inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; } 43 43 inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; } 44 45 #define REPTACH_OFFSET_CALL_R11 3 44 46 #endif 45 47 … … 997 999 } 998 1000 999 void jmp_r(RegisterID dst) 1001 // Return a JmpSrc so we have a label to the jump, so we can use this 1002 // To make a tail recursive call on x86-64. The MacroAssembler 1003 // really shouldn't wrap this as a Jump, since it can't be linked. :-/ 1004 JmpSrc jmp_r(RegisterID dst) 1000 1005 { 1001 1006 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst); 1007 return JmpSrc(m_formatter.size()); 1002 1008 } 1003 1009 … … 1225 1231 // Linking & patching: 1226 1232 1227 void link (JmpSrc from, JmpDst to)1233 void linkJump(JmpSrc from, JmpDst to) 1228 1234 { 1229 1235 ASSERT(to.m_offset != -1); … … 1233 1239 } 1234 1240 1235 static void patchAddress(void* code, JmpDst position, void* value) 1236 { 1237 ASSERT(position.m_offset != -1); 1238 1239 reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value; 1240 } 1241 1242 static void link(void* code, JmpSrc from, void* to) 1241 static void linkJump(void* code, JmpSrc from, void* to) 1243 1242 { 1244 1243 ASSERT(from.m_offset != -1); … … 1248 1247 } 1249 1248 1250 static unsigned getCallReturnOffset(JmpSrc call) 1251 { 1252 ASSERT(call.m_offset >= 0); 1253 return call.m_offset; 1254 } 1255 1256 static void* getRelocatedAddress(void* code, JmpSrc jump) 1257 { 1258 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset); 1259 } 1260 1261 static void* getRelocatedAddress(void* code, JmpDst destination) 1262 { 1263 ASSERT(destination.m_offset != -1); 1264 1265 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset); 1266 } 1267 1268 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst) 1269 { 1270 return dst.m_offset - src.m_offset; 1271 } 1272 1273 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst) 1274 { 1275 return dst.m_offset - src.m_offset; 1276 } 1277 1278 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst) 1279 { 1280 return dst.m_offset - src.m_offset; 1281 } 1282 1283 static void patchImmediate(intptr_t where, int32_t value) 1284 { 1285 reinterpret_cast<int32_t*>(where)[-1] = value; 1286 } 1287 1288 static void patchPointer(intptr_t where, intptr_t value) 1289 { 1290 reinterpret_cast<intptr_t*>(where)[-1] = value; 1291 } 1292 1293 static void patchBranchOffset(intptr_t where, void* destination) 1249 static void patchJump(intptr_t where, void* destination) 1294 1250 { 1295 1251 intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; 1296 1252 ASSERT(offset == static_cast<int32_t>(offset)); 1297 1253 reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); 1254 } 1255 1256 #if PLATFORM(X86_64) 1257 // FIXME: transition these functions out of here - the assembler 1258 // shouldn't know that that this is mov/call pair using r11. :-/ 1259 static void patchMacroAssemblerCall(intptr_t where, void* destination) 1260 { 1261 patchAddress(reinterpret_cast<void*>(where - REPTACH_OFFSET_CALL_R11), JmpDst(0), destination); 1262 } 1263 #else 1264 static void patchMacroAssemblerCall(intptr_t where, void* destination) 1265 { 1266 intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; 1267 ASSERT(offset == static_cast<int32_t>(offset)); 1268 reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); 1269 } 1270 #endif 1271 1272 void linkCall(JmpSrc from, JmpDst to) 1273 { 1274 ASSERT(to.m_offset != -1); 1275 ASSERT(from.m_offset != -1); 1276 1277 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset; 1278 } 1279 1280 static void linkCall(void* code, JmpSrc from, void* to) 1281 { 1282 ASSERT(from.m_offset != -1); 1283 ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset); 1284 ASSERT(linkOffset == static_cast<int>(linkOffset)); 1285 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset; 1286 } 1287 1288 static void patchCall(intptr_t where, void* destination) 1289 { 1290 intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; 1291 ASSERT(offset == static_cast<int32_t>(offset)); 1292 reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); 1293 } 1294 1295 static void patchAddress(void* code, JmpDst position, void* value) 1296 { 1297 ASSERT(position.m_offset != -1); 1298 1299 reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value; 1300 } 1301 1302 static unsigned getCallReturnOffset(JmpSrc call) 1303 { 1304 ASSERT(call.m_offset >= 0); 1305 return call.m_offset; 1306 } 1307 1308 static void* getRelocatedAddress(void* code, JmpSrc jump) 1309 { 1310 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset); 1311 } 1312 1313 static void* getRelocatedAddress(void* code, JmpDst destination) 1314 { 1315 ASSERT(destination.m_offset != -1); 1316 1317 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset); 1318 } 1319 1320 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst) 1321 { 1322 return dst.m_offset - src.m_offset; 1323 } 1324 1325 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst) 1326 { 1327 return dst.m_offset - src.m_offset; 1328 } 1329 1330 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst) 1331 { 1332 return dst.m_offset - src.m_offset; 1333 } 1334 1335 static void patchImmediate(intptr_t where, int32_t value) 1336 { 1337 reinterpret_cast<int32_t*>(where)[-1] = value; 1338 } 1339 1340 static void patchPointer(intptr_t where, intptr_t value) 1341 { 1342 reinterpret_cast<intptr_t*>(where)[-1] = value; 1298 1343 } 1299 1344
Note:
See TracChangeset
for help on using the changeset viewer.