Changeset 220807 in webkit for trunk/Source/JavaScriptCore/assembler/testmasm.cpp
- Timestamp:
- Aug 16, 2017, 1:38:57 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/assembler/testmasm.cpp
r220744 r220807 64 64 namespace { 65 65 66 using CPUState = MacroAssembler::CPUState; 67 66 68 StaticLock crashLock; 67 69 … … 268 270 // to validate that the probe preserves register values. 269 271 unsigned probeCallCount = 0; 270 MacroAssembler::CPUState originalState;272 CPUState originalState; 271 273 272 274 compileAndRun<void>([&] (CCallHelpers& jit) { … … 348 350 { 349 351 unsigned probeCallCount = 0; 350 MacroAssembler::CPUState originalState;352 CPUState originalState; 351 353 void* originalSP { nullptr }; 352 354 void* modifiedSP { nullptr }; … … 509 511 } 510 512 513 struct FillStackData { 514 CPUState originalState; 515 void* originalSP { nullptr }; 516 void* newSP { nullptr }; 517 uintptr_t modifiedFlags { 0 }; 518 MacroAssembler::SPRegisterID flagsSPR; 519 }; 520 521 static void fillStack(ProbeContext* context) 522 { 523 auto& cpu = context->cpu; 524 525 FillStackData& data = *reinterpret_cast<FillStackData*>(context->initializeStackArg); 526 CPUState& originalState = data.originalState; 527 void*& originalSP = data.originalSP; 528 void*& newSP = data.newSP; 529 uintptr_t& modifiedFlags = data.modifiedFlags; 530 MacroAssembler::SPRegisterID& flagsSPR = data.flagsSPR; 531 532 CHECK_EQ(reinterpret_cast<void*>(context->initializeStackFunction), reinterpret_cast<void*>(fillStack)); 533 CHECK_EQ(cpu.sp(), newSP); 534 535 // Verify that the probe has put the ProbeContext out of harm's way. 536 CHECK_EQ((reinterpret_cast<void*>(context + 1) <= cpu.sp()), true); 537 538 // Verify the CPU state. 539 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { 540 if (isFP(id)) { 541 CHECK_EQ(cpu.gpr(id), originalState.gpr(id)); 542 continue; 543 } 544 if (isSpecialGPR(id)) 545 continue; 546 CHECK_EQ(cpu.gpr(id), testWord(id)); 547 } 548 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 549 CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id)); 550 CHECK_EQ(cpu.spr(flagsSPR), modifiedFlags); 551 552 // Fill the stack with values. 553 uintptr_t* p = reinterpret_cast<uintptr_t*>(newSP); 554 int count = 0; 555 while (p < reinterpret_cast<uintptr_t*>(originalSP)) 556 *p++ = testWord(count++); 557 }; 558 559 void testProbeModifiesStackWithCallback() 560 { 561 unsigned probeCallCount = 0; 562 FillStackData data; 563 CPUState& originalState = data.originalState; 564 void*& originalSP = data.originalSP; 565 void*& newSP = data.newSP; 566 uintptr_t& modifiedFlags = data.modifiedFlags; 567 size_t numberOfExtraEntriesToWrite = 10; // ARM64 requires that this be 2 word aligned. 568 MacroAssembler::SPRegisterID& flagsSPR = data.flagsSPR; 569 570 #if CPU(X86) || CPU(X86_64) 571 flagsSPR = X86Registers::eflags; 572 uintptr_t flagsMask = 0xc5; 573 #elif CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) 574 flagsSPR = ARMRegisters::apsr; 575 uintptr_t flagsMask = 0xf0000000; 576 #elif CPU(ARM64) 577 flagsSPR = ARM64Registers::nzcv; 578 uintptr_t flagsMask = 0xf0000000; 579 #endif 580 581 compileAndRun<void>([&] (CCallHelpers& jit) { 582 jit.emitFunctionPrologue(); 583 584 // Write expected values into the registers. 585 jit.probe([&] (ProbeContext* context) { 586 auto& cpu = context->cpu; 587 probeCallCount++; 588 589 // Preserve the original CPU state. 590 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { 591 originalState.gpr(id) = cpu.gpr(id); 592 if (isSpecialGPR(id)) 593 continue; 594 cpu.gpr(id) = testWord(static_cast<int>(id)); 595 } 596 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) { 597 originalState.fpr(id) = cpu.fpr(id); 598 cpu.fpr(id) = bitwise_cast<double>(testWord64(id)); 599 } 600 originalState.spr(flagsSPR) = cpu.spr(flagsSPR); 601 modifiedFlags = originalState.spr(flagsSPR) ^ flagsMask; 602 cpu.spr(flagsSPR) = modifiedFlags; 603 604 CHECK_EQ(reinterpret_cast<void*>(context->initializeStackFunction), 0); 605 606 // Prepare for initializeStack callback. 607 context->initializeStackFunction = fillStack; 608 context->initializeStackArg = &data; 609 610 // Ensure that we'll be writing over the regions of the stack where the ProbeContext is. 611 originalSP = cpu.sp(); 612 newSP = reinterpret_cast<uintptr_t*>(context) - numberOfExtraEntriesToWrite; 613 cpu.sp() = newSP; 614 }); 615 616 // Validate that the registers and stack have the expected values. 617 jit.probe([&] (ProbeContext* context) { 618 auto& cpu = context->cpu; 619 probeCallCount++; 620 621 // Validate the register values. 622 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { 623 if (isFP(id)) { 624 CHECK_EQ(cpu.gpr(id), originalState.gpr(id)); 625 continue; 626 } 627 if (isSpecialGPR(id)) 628 continue; 629 CHECK_EQ(cpu.gpr(id), testWord(id)); 630 } 631 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 632 CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id)); 633 CHECK_EQ(cpu.spr(flagsSPR), modifiedFlags); 634 CHECK_EQ(cpu.sp(), newSP); 635 636 // Validate the stack with values. 637 uintptr_t* p = reinterpret_cast<uintptr_t*>(newSP); 638 int count = 0; 639 while (p < reinterpret_cast<uintptr_t*>(originalSP)) 640 CHECK_EQ(*p++, testWord(count++)); 641 }); 642 643 // Restore the original state. 644 jit.probe([&] (ProbeContext* context) { 645 auto& cpu = context->cpu; 646 probeCallCount++; 647 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { 648 if (isSpecialGPR(id)) 649 continue; 650 cpu.gpr(id) = originalState.gpr(id); 651 } 652 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 653 cpu.fpr(id) = originalState.fpr(id); 654 cpu.spr(flagsSPR) = originalState.spr(flagsSPR); 655 cpu.sp() = originalSP; 656 }); 657 658 jit.emitFunctionEpilogue(); 659 jit.ret(); 660 }); 661 662 CHECK_EQ(probeCallCount, 3); 663 } 664 511 665 #define RUN(test) do { \ 512 666 if (!shouldRun(#test)) \ … … 541 695 RUN(testProbeModifiesStackPointerToNBytesBelowSP()); 542 696 RUN(testProbeModifiesProgramCounter()); 697 RUN(testProbeModifiesStackWithCallback()); 543 698 544 699 if (tasks.isEmpty())
Note:
See TracChangeset
for help on using the changeset viewer.