Changeset 220744 in webkit


Ignore:
Timestamp:
Aug 15, 2017 9:42:41 AM (7 years ago)
Author:
mark.lam@apple.com
Message:

Update testmasm to use new CPUState APIs.
https://bugs.webkit.org/show_bug.cgi?id=175573

Reviewed by Keith Miller.

  1. Applied convenience CPUState accessors to minimize casting.
  2. Converted the CHECK macro to CHECK_EQ to get more friendly failure debugging messages.
  3. Removed the CHECK_DOUBLE_BITWISE_EQ macro. We can just use CHECK_EQ now since casting is (mostly) no longer an issue.
  4. Replaced the use of testDoubleWord(id) with bitwise_cast<double>(testWord64(id)) to make it clear that we're comparing against the bit values of testWord64(id).
  5. Added a "Completed N tests" message at the end of running all tests. This makes it easy to tell at a glance that testmasm completed successfully versus when it crashed midway in a test. The number of tests also serves as a quick checksum to confirm that we ran the number of tests we expected.
  • assembler/testmasm.cpp:

(WTF::printInternal):
(JSC::testSimple):
(JSC::testProbeReadsArgumentRegisters):
(JSC::testProbeWritesArgumentRegisters):
(JSC::testProbePreservesGPRS):
(JSC::testProbeModifiesStackPointer):
(JSC::testProbeModifiesProgramCounter):
(JSC::run):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r220735 r220744  
     12017-08-15  Mark Lam  <mark.lam@apple.com>
     2
     3        Update testmasm to use new CPUState APIs.
     4        https://bugs.webkit.org/show_bug.cgi?id=175573
     5
     6        Reviewed by Keith Miller.
     7
     8        1. Applied convenience CPUState accessors to minimize casting.
     9        2. Converted the CHECK macro to CHECK_EQ to get more friendly failure debugging
     10           messages.
     11        3. Removed the CHECK_DOUBLE_BITWISE_EQ macro.  We can just use CHECK_EQ now since
     12           casting is (mostly) no longer an issue.
     13        4. Replaced the use of testDoubleWord(id) with bitwise_cast<double>(testWord64(id))
     14           to make it clear that we're comparing against the bit values of testWord64(id).
     15        5. Added a "Completed N tests" message at the end of running all tests.
     16           This makes it easy to tell at a glance that testmasm completed successfully
     17           versus when it crashed midway in a test.  The number of tests also serves as
     18           a quick checksum to confirm that we ran the number of tests we expected.
     19
     20        * assembler/testmasm.cpp:
     21        (WTF::printInternal):
     22        (JSC::testSimple):
     23        (JSC::testProbeReadsArgumentRegisters):
     24        (JSC::testProbeWritesArgumentRegisters):
     25        (JSC::testProbePreservesGPRS):
     26        (JSC::testProbeModifiesStackPointer):
     27        (JSC::testProbeModifiesProgramCounter):
     28        (JSC::run):
     29
    1302017-08-14  Keith Miller  <keith_miller@apple.com>
    231
  • trunk/Source/JavaScriptCore/assembler/testmasm.cpp

    r220579 r220744  
    5151#if ENABLE(JIT)
    5252
     53namespace WTF {
     54
     55static void printInternal(PrintStream& out, void* value)
     56{
     57    out.printf("%p", value);
     58}
     59
     60} // namespace WTF
     61
    5362using namespace JSC;
    5463
     
    7281#define testWord(x) testWord32(x)
    7382#endif
    74 #define testDoubleWord(x) static_cast<double>(testWord(x))
    7583
    7684// Nothing fancy for now; we just use the existing WTF assertion machinery.
    77 #define CHECK(x) do {                                                   \
    78         if (!!(x))                                                      \
     85#define CHECK_EQ(_actual, _expected) do {                               \
     86        if ((_actual) == (_expected))                                   \
    7987            break;                                                      \
    8088        crashLock.lock();                                               \
    81         WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
     89        dataLog("FAILED while testing " #_actual ": expected: ", _expected, ", actual: ", _actual, "\n"); \
     90        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, "CHECK_EQ("#_actual ", " #_expected ")"); \
    8291        CRASH();                                                        \
    8392    } while (false)
    84 
    85 #define CHECK_DOUBLE_BITWISE_EQ(a, b) \
    86     CHECK(bitwise_cast<uint64_t>(a) == bitwise_cast<uint64_t>(a))
    8793
    8894bool isPC(MacroAssembler::RegisterID id)
     
    140146void testSimple()
    141147{
    142     CHECK(compileAndRun<int>([] (CCallHelpers& jit) {
     148    CHECK_EQ(compileAndRun<int>([] (CCallHelpers& jit) {
    143149        jit.emitFunctionPrologue();
    144150        jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
    145151        jit.emitFunctionEpilogue();
    146152        jit.ret();
    147     }) == 42);
     153    }), 42);
    148154}
    149155
     
    171177
    172178        jit.probe([&] (ProbeContext* context) {
     179            auto& cpu = context->cpu;
    173180            probeWasCalled = true;
    174             CHECK(context->gpr(GPRInfo::argumentGPR0) == testWord(0));
    175             CHECK(context->gpr(GPRInfo::argumentGPR1) == testWord(1));
    176             CHECK(context->gpr(GPRInfo::argumentGPR2) == testWord(2));
    177             CHECK(context->gpr(GPRInfo::argumentGPR3) == testWord(3));
    178 
    179             CHECK_DOUBLE_BITWISE_EQ(context->fpr(FPRInfo::fpRegT0), static_cast<double>(testWord32(0)));
    180             CHECK_DOUBLE_BITWISE_EQ(context->fpr(FPRInfo::fpRegT1),  static_cast<double>(testWord32(1)));
     181            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR0), testWord(0));
     182            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR1), testWord(1));
     183            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR2), testWord(2));
     184            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR3), testWord(3));
     185
     186            CHECK_EQ(cpu.fpr(FPRInfo::fpRegT0), testWord32(0));
     187            CHECK_EQ(cpu.fpr(FPRInfo::fpRegT1), testWord32(1));
    181188        });
    182189        jit.emitFunctionEpilogue();
    183190        jit.ret();
    184191    });
    185     CHECK(probeWasCalled);
     192    CHECK_EQ(probeWasCalled, true);
    186193}
    187194
     
    212219        // Write expected values.
    213220        jit.probe([&] (ProbeContext* context) {
    214             probeCallCount++;
    215             context->gpr(GPRInfo::argumentGPR0) = testWord(0);
    216             context->gpr(GPRInfo::argumentGPR1) = testWord(1);
    217             context->gpr(GPRInfo::argumentGPR2) = testWord(2);
    218             context->gpr(GPRInfo::argumentGPR3) = testWord(3);
     221            auto& cpu = context->cpu;
     222            probeCallCount++;
     223            cpu.gpr(GPRInfo::argumentGPR0) = testWord(0);
     224            cpu.gpr(GPRInfo::argumentGPR1) = testWord(1);
     225            cpu.gpr(GPRInfo::argumentGPR2) = testWord(2);
     226            cpu.gpr(GPRInfo::argumentGPR3) = testWord(3);
    219227           
    220             context->fpr(FPRInfo::fpRegT0) = testWord32(0);
    221             context->fpr(FPRInfo::fpRegT1) = testWord32(1);
     228            cpu.fpr(FPRInfo::fpRegT0) = bitwise_cast<double>(testWord64(0));
     229            cpu.fpr(FPRInfo::fpRegT1) = bitwise_cast<double>(testWord64(1));
    222230        });
    223231
    224232        // Validate that expected values were written.
    225233        jit.probe([&] (ProbeContext* context) {
    226             probeCallCount++;
    227             CHECK(context->gpr(GPRInfo::argumentGPR0) == testWord(0));
    228             CHECK(context->gpr(GPRInfo::argumentGPR1) == testWord(1));
    229             CHECK(context->gpr(GPRInfo::argumentGPR2) == testWord(2));
    230             CHECK(context->gpr(GPRInfo::argumentGPR3) == testWord(3));
    231 
    232             CHECK_DOUBLE_BITWISE_EQ(context->fpr(FPRInfo::fpRegT0), static_cast<double>(testWord32(0)));
    233             CHECK_DOUBLE_BITWISE_EQ(context->fpr(FPRInfo::fpRegT1), static_cast<double>(testWord32(1)));
     234            auto& cpu = context->cpu;
     235            probeCallCount++;
     236            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR0), testWord(0));
     237            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR1), testWord(1));
     238            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR2), testWord(2));
     239            CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR3), testWord(3));
     240
     241            CHECK_EQ(cpu.fpr<uint64_t>(FPRInfo::fpRegT0), testWord64(0));
     242            CHECK_EQ(cpu.fpr<uint64_t>(FPRInfo::fpRegT1), testWord64(1));
    234243        });
    235244
     
    237246        jit.ret();
    238247    });
    239     CHECK(probeCallCount == 2);
     248    CHECK_EQ(probeCallCount, 2);
    240249}
    241250
     
    266275        // Write expected values into the registers (except for sp, fp, and pc).
    267276        jit.probe([&] (ProbeContext* context) {
    268             probeCallCount++;
    269             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    270                 originalState.gpr(id) = context->gpr(id);
    271                 if (isSpecialGPR(id))
    272                     continue;
    273                 context->gpr(id) = testWord(static_cast<int>(id));
     277            auto& cpu = context->cpu;
     278            probeCallCount++;
     279            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     280                originalState.gpr(id) = cpu.gpr(id);
     281                if (isSpecialGPR(id))
     282                    continue;
     283                cpu.gpr(id) = testWord(static_cast<int>(id));
    274284            }
    275285            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) {
    276                 originalState.fpr(id) = context->fpr(id);
    277                 context->fpr(id) = testDoubleWord(id);
     286                originalState.fpr(id) = cpu.fpr(id);
     287                cpu.fpr(id) = bitwise_cast<double>(testWord64(id));
    278288            }
    279289        });
     
    282292        jit.probe([&] (ProbeContext*) {
    283293            probeCallCount++;
    284             CHECK(testFunctionToTrashGPRs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) == 10);
    285             CHECK(testFunctionToTrashFPRs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) == 10);
     294            CHECK_EQ(testFunctionToTrashGPRs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 10);
     295            CHECK_EQ(testFunctionToTrashFPRs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 10);
    286296        });
    287297
    288298        // Validate that the registers have the expected values.
    289299        jit.probe([&] (ProbeContext* context) {
     300            auto& cpu = context->cpu;
    290301            probeCallCount++;
    291302            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    292303                if (isSP(id) || isFP(id)) {
    293                     CHECK(context->gpr(id) == originalState.gpr(id));
     304                    CHECK_EQ(cpu.gpr(id), originalState.gpr(id));
    294305                    continue;
    295306                }
    296307                if (isSpecialGPR(id))
    297308                    continue;
    298                 CHECK(context->gpr(id) == testWord(id));
     309                CHECK_EQ(cpu.gpr(id), testWord(id));
    299310            }
    300311            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    301                 CHECK_DOUBLE_BITWISE_EQ(context->fpr(id), testDoubleWord(id));
     312                CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id));
    302313        });
    303314
    304315        // Restore the original state.
    305316        jit.probe([&] (ProbeContext* context) {
    306             probeCallCount++;
    307             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    308                 if (isSpecialGPR(id))
    309                     continue;
    310                 context->gpr(id) = originalState.gpr(id);
     317            auto& cpu = context->cpu;
     318            probeCallCount++;
     319            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     320                if (isSpecialGPR(id))
     321                    continue;
     322                cpu.gpr(id) = originalState.gpr(id);
    311323            }
    312324            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    313                 context->fpr(id) = originalState.fpr(id);
     325                cpu.fpr(id) = originalState.fpr(id);
    314326        });
    315327
    316328        // Validate that the original state was restored.
    317329        jit.probe([&] (ProbeContext* context) {
    318             probeCallCount++;
    319             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    320                 if (isSpecialGPR(id))
    321                     continue;
    322                 CHECK(context->gpr(id) == originalState.gpr(id));
     330            auto& cpu = context->cpu;
     331            probeCallCount++;
     332            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     333                if (isSpecialGPR(id))
     334                    continue;
     335                CHECK_EQ(cpu.gpr(id), originalState.gpr(id));
    323336            }
    324337            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    325                 CHECK_DOUBLE_BITWISE_EQ(context->fpr(id), originalState.fpr(id));
     338                CHECK_EQ(cpu.fpr<uint64_t>(id), originalState.fpr<uint64_t>(id));
    326339        });
    327340
     
    329342        jit.ret();
    330343    });
    331     CHECK(probeCallCount == 5);
     344    CHECK_EQ(probeCallCount, 5);
    332345}
    333346
     
    336349    unsigned probeCallCount = 0;
    337350    MacroAssembler::CPUState originalState;
    338     uint8_t* originalSP { nullptr };
     351    void* originalSP { nullptr };
    339352    void* modifiedSP { nullptr };
    340353    uintptr_t modifiedFlags { 0 };
     
    357370        // write expected values into other registers (except for fp, and pc).
    358371        jit.probe([&] (ProbeContext* context) {
    359             probeCallCount++;
    360             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    361                 originalState.gpr(id) = context->gpr(id);
    362                 if (isSpecialGPR(id))
    363                     continue;
    364                 context->gpr(id) = testWord(static_cast<int>(id));
     372            auto& cpu = context->cpu;
     373            probeCallCount++;
     374            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     375                originalState.gpr(id) = cpu.gpr(id);
     376                if (isSpecialGPR(id))
     377                    continue;
     378                cpu.gpr(id) = testWord(static_cast<int>(id));
    365379            }
    366380            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) {
    367                 originalState.fpr(id) = context->fpr(id);
    368                 context->fpr(id) = testWord(id);
    369             }
    370 
    371             originalState.spr(flagsSPR) = context->spr(flagsSPR);
     381                originalState.fpr(id) = cpu.fpr(id);
     382                cpu.fpr(id) = bitwise_cast<double>(testWord64(id));
     383            }
     384
     385            originalState.spr(flagsSPR) = cpu.spr(flagsSPR);
    372386            modifiedFlags = originalState.spr(flagsSPR) ^ flagsMask;
    373             context->spr(flagsSPR) = modifiedFlags;
    374 
    375             originalSP = reinterpret_cast<uint8_t*>(context->sp());
     387            cpu.spr(flagsSPR) = modifiedFlags;
     388
     389            originalSP = cpu.sp();
    376390            modifiedSP = computeModifiedStack(context);
    377             context->sp() = modifiedSP;
     391            cpu.sp() = modifiedSP;
    378392        });
    379393
    380394        // Validate that the registers have the expected values.
    381395        jit.probe([&] (ProbeContext* context) {
     396            auto& cpu = context->cpu;
    382397            probeCallCount++;
    383398            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    384399                if (isFP(id)) {
    385                     CHECK(context->gpr(id) == originalState.gpr(id));
     400                    CHECK_EQ(cpu.gpr(id), originalState.gpr(id));
    386401                    continue;
    387402                }
    388403                if (isSpecialGPR(id))
    389404                    continue;
    390                 CHECK(context->gpr(id) == testWord(id));
     405                CHECK_EQ(cpu.gpr(id), testWord(id));
    391406            }
    392407            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    393                 CHECK_DOUBLE_BITWISE_EQ(context->fpr(id), testDoubleWord(id));
    394             CHECK(context->spr(flagsSPR) == modifiedFlags);
    395             CHECK(context->sp() == modifiedSP);
     408                CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id));
     409            CHECK_EQ(cpu.spr(flagsSPR), modifiedFlags);
     410            CHECK_EQ(cpu.sp(), modifiedSP);
    396411        });
    397412
    398413        // Restore the original state.
    399414        jit.probe([&] (ProbeContext* context) {
    400             probeCallCount++;
    401             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    402                 if (isSpecialGPR(id))
    403                     continue;
    404                 context->gpr(id) = originalState.gpr(id);
     415            auto& cpu = context->cpu;
     416            probeCallCount++;
     417            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     418                if (isSpecialGPR(id))
     419                    continue;
     420                cpu.gpr(id) = originalState.gpr(id);
    405421            }
    406422            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    407                 context->fpr(id) = originalState.fpr(id);
    408             context->spr(flagsSPR) = originalState.spr(flagsSPR);
    409             context->sp() = originalSP;
     423                cpu.fpr(id) = originalState.fpr(id);
     424            cpu.spr(flagsSPR) = originalState.spr(flagsSPR);
     425            cpu.sp() = originalSP;
    410426        });
    411427
    412428        // Validate that the original state was restored.
    413429        jit.probe([&] (ProbeContext* context) {
    414             probeCallCount++;
    415             for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
    416                 if (isSpecialGPR(id))
    417                     continue;
    418                 CHECK(context->gpr(id) == originalState.gpr(id));
     430            auto& cpu = context->cpu;
     431            probeCallCount++;
     432            for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) {
     433                if (isSpecialGPR(id))
     434                    continue;
     435                CHECK_EQ(cpu.gpr(id), originalState.gpr(id));
    419436            }
    420437            for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id))
    421                 CHECK_DOUBLE_BITWISE_EQ(context->fpr(id),  originalState.fpr(id));
    422             CHECK(context->spr(flagsSPR) == originalState.spr(flagsSPR));
    423             CHECK(context->sp() == originalSP);
     438                CHECK_EQ(cpu.fpr<uint64_t>(id), originalState.fpr<uint64_t>(id));
     439            CHECK_EQ(cpu.spr(flagsSPR), originalState.spr(flagsSPR));
     440            CHECK_EQ(cpu.sp(), originalSP);
    424441        });
    425442
     
    427444        jit.ret();
    428445    });
    429     CHECK(probeCallCount == 4);
     446    CHECK_EQ(probeCallCount, 4);
    430447}
    431448
     
    488505        jit.breakpoint(); // We should never get here.
    489506    });
    490     CHECK(probeCallCount == 2);
    491     CHECK(continuationWasReached);
     507    CHECK_EQ(probeCallCount, 2);
     508    CHECK_EQ(continuationWasReached, true);
    492509}
    493510
     
    495512        if (!shouldRun(#test))                  \
    496513            break;                              \
     514        numberOfTests++;                        \
    497515        tasks.append(                           \
    498516            createSharedTask<void()>(           \
     
    507525{
    508526    JSC::initializeThreading();
     527    unsigned numberOfTests = 0;
    509528
    510529    Deque<RefPtr<SharedTask<void()>>> tasks;
     
    551570        thread->waitForCompletion();
    552571    crashLock.lock();
     572    dataLog("Completed ", numberOfTests, " tests\n");
    553573}
    554574
Note: See TracChangeset for help on using the changeset viewer.