Changeset 220958 in webkit for trunk/Source/JavaScriptCore/assembler/testmasm.cpp
- Timestamp:
- Aug 20, 2017, 9:26:40 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/assembler/testmasm.cpp
r220926 r220958 32 32 #include "InitializeThreading.h" 33 33 #include "LinkBuffer.h" 34 #include "ProbeContext.h" 34 35 #include <wtf/Compiler.h> 35 36 #include <wtf/DataLog.h> … … 62 63 #endif // ENABLE(MASM_PROBE) 63 64 65 namespace JSC { 66 namespace Probe { 67 68 JS_EXPORT_PRIVATE void* probeStateForContext(Probe::Context&); 69 70 } // namespace Probe 71 } // namespace JSC 72 64 73 using namespace JSC; 65 74 … … 67 76 68 77 #if ENABLE(MASM_PROBE) 69 using CPUState = MacroAssembler::CPUState;78 using CPUState = Probe::CPUState; 70 79 #endif 71 80 … … 185 194 #endif 186 195 187 jit.probe([&] (Probe:: State*context) {188 auto& cpu = context ->cpu;196 jit.probe([&] (Probe::Context& context) { 197 auto& cpu = context.cpu; 189 198 probeWasCalled = true; 190 199 CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR0), testWord(0)); … … 227 236 228 237 // Write expected values. 229 jit.probe([&] (Probe:: State*context) {230 auto& cpu = context ->cpu;238 jit.probe([&] (Probe::Context& context) { 239 auto& cpu = context.cpu; 231 240 probeCallCount++; 232 241 cpu.gpr(GPRInfo::argumentGPR0) = testWord(0); … … 240 249 241 250 // Validate that expected values were written. 242 jit.probe([&] (Probe:: State*context) {243 auto& cpu = context ->cpu;251 jit.probe([&] (Probe::Context& context) { 252 auto& cpu = context.cpu; 244 253 probeCallCount++; 245 254 CHECK_EQ(cpu.gpr(GPRInfo::argumentGPR0), testWord(0)); … … 283 292 284 293 // Write expected values into the registers (except for sp, fp, and pc). 285 jit.probe([&] (Probe:: State*context) {286 auto& cpu = context ->cpu;294 jit.probe([&] (Probe::Context& context) { 295 auto& cpu = context.cpu; 287 296 probeCallCount++; 288 297 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 299 308 300 309 // Invoke the probe to call a lot of functions and trash register values. 301 jit.probe([&] (Probe:: State*) {310 jit.probe([&] (Probe::Context&) { 302 311 probeCallCount++; 303 312 CHECK_EQ(testFunctionToTrashGPRs(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), 10); … … 306 315 307 316 // Validate that the registers have the expected values. 308 jit.probe([&] (Probe:: State*context) {309 auto& cpu = context ->cpu;317 jit.probe([&] (Probe::Context& context) { 318 auto& cpu = context.cpu; 310 319 probeCallCount++; 311 320 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 323 332 324 333 // Restore the original state. 325 jit.probe([&] (Probe:: State*context) {326 auto& cpu = context ->cpu;334 jit.probe([&] (Probe::Context& context) { 335 auto& cpu = context.cpu; 327 336 probeCallCount++; 328 337 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 336 345 337 346 // Validate that the original state was restored. 338 jit.probe([&] (Probe:: State*context) {339 auto& cpu = context ->cpu;347 jit.probe([&] (Probe::Context& context) { 348 auto& cpu = context.cpu; 340 349 probeCallCount++; 341 350 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 354 363 } 355 364 356 void testProbeModifiesStackPointer(WTF::Function<void*(Probe:: State*)> computeModifiedStack)365 void testProbeModifiesStackPointer(WTF::Function<void*(Probe::Context&)> computeModifiedStackPointer) 357 366 { 358 367 unsigned probeCallCount = 0; … … 367 376 #elif CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) 368 377 auto flagsSPR = ARMRegisters::apsr; 369 uintptr_t flagsMask = 0xf 0000000;378 uintptr_t flagsMask = 0xf8000000; 370 379 #elif CPU(ARM64) 371 380 auto flagsSPR = ARM64Registers::nzcv; … … 378 387 // Preserve original stack pointer and modify the sp, and 379 388 // write expected values into other registers (except for fp, and pc). 380 jit.probe([&] (Probe:: State*context) {381 auto& cpu = context ->cpu;389 jit.probe([&] (Probe::Context& context) { 390 auto& cpu = context.cpu; 382 391 probeCallCount++; 383 392 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 397 406 398 407 originalSP = cpu.sp(); 399 modifiedSP = computeModifiedStack (context);408 modifiedSP = computeModifiedStackPointer(context); 400 409 cpu.sp() = modifiedSP; 401 410 }); 402 411 403 412 // Validate that the registers have the expected values. 404 jit.probe([&] (Probe:: State*context) {405 auto& cpu = context ->cpu;413 jit.probe([&] (Probe::Context& context) { 414 auto& cpu = context.cpu; 406 415 probeCallCount++; 407 416 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 416 425 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 417 426 CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id)); 418 CHECK_EQ(cpu.spr(flagsSPR) , modifiedFlags);427 CHECK_EQ(cpu.spr(flagsSPR) & flagsMask, modifiedFlags & flagsMask); 419 428 CHECK_EQ(cpu.sp(), modifiedSP); 420 429 }); 421 430 422 431 // Restore the original state. 423 jit.probe([&] (Probe:: State*context) {424 auto& cpu = context ->cpu;432 jit.probe([&] (Probe::Context& context) { 433 auto& cpu = context.cpu; 425 434 probeCallCount++; 426 435 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 436 445 437 446 // Validate that the original state was restored. 438 jit.probe([&] (Probe:: State*context) {439 auto& cpu = context ->cpu;447 jit.probe([&] (Probe::Context& context) { 448 auto& cpu = context.cpu; 440 449 probeCallCount++; 441 450 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 446 455 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 447 456 CHECK_EQ(cpu.fpr<uint64_t>(id), originalState.fpr<uint64_t>(id)); 448 CHECK_EQ(cpu.spr(flagsSPR) , originalState.spr(flagsSPR));457 CHECK_EQ(cpu.spr(flagsSPR) & flagsMask, originalState.spr(flagsSPR) & flagsMask); 449 458 CHECK_EQ(cpu.sp(), originalSP); 450 459 }); … … 464 473 #endif 465 474 for (size_t offset = 0; offset < sizeof(Probe::State); offset += increment) { 466 testProbeModifiesStackPointer([=] (Probe::State* context) -> void* { 467 return reinterpret_cast<uint8_t*>(context) + offset; 475 testProbeModifiesStackPointer([=] (Probe::Context& context) -> void* { 476 return reinterpret_cast<uint8_t*>(probeStateForContext(context)) + offset; 477 468 478 }); 469 479 } … … 478 488 #endif 479 489 for (size_t offset = 0; offset < 1 * KB; offset += increment) { 480 testProbeModifiesStackPointer([=] (Probe:: State*context) -> void* {481 return reinterpret_cast<uint8_t*>(context->cpu.sp()) - offset;490 testProbeModifiesStackPointer([=] (Probe::Context& context) -> void* { 491 return context.cpu.sp<uint8_t*>() - offset; 482 492 }); 483 493 } … … 494 504 MacroAssemblerCodeRef continuation = compile([&] (CCallHelpers& jit) { 495 505 // Validate that we reached the continuation. 496 jit.probe([&] (Probe:: State*) {506 jit.probe([&] (Probe::Context&) { 497 507 probeCallCount++; 498 508 continuationWasReached = true; … … 507 517 508 518 // Write expected values into the registers. 509 jit.probe([&] (Probe:: State*context) {510 probeCallCount++; 511 context ->pc() = continuation.code().executableAddress();519 jit.probe([&] (Probe::Context& context) { 520 probeCallCount++; 521 context.cpu.pc() = continuation.code().executableAddress(); 512 522 }); 513 523 … … 518 528 } 519 529 520 struct FillStackData { 530 void testProbeModifiesStackValues() 531 { 532 unsigned probeCallCount = 0; 521 533 CPUState originalState; 522 534 void* originalSP { nullptr }; 523 535 void* newSP { nullptr }; 524 536 uintptr_t modifiedFlags { 0 }; 525 MacroAssembler::SPRegisterID flagsSPR; 526 }; 527 528 static void fillStack(Probe::State* context) 529 { 530 auto& cpu = context->cpu; 531 532 FillStackData& data = *reinterpret_cast<FillStackData*>(context->initializeStackArg); 533 CPUState& originalState = data.originalState; 534 void*& originalSP = data.originalSP; 535 void*& newSP = data.newSP; 536 uintptr_t& modifiedFlags = data.modifiedFlags; 537 MacroAssembler::SPRegisterID& flagsSPR = data.flagsSPR; 538 539 CHECK_EQ(reinterpret_cast<void*>(context->initializeStackFunction), reinterpret_cast<void*>(fillStack)); 540 CHECK_EQ(cpu.sp(), newSP); 541 542 // Verify that the probe has put the Probe::State out of harm's way. 543 CHECK_EQ((reinterpret_cast<void*>(context + 1) <= cpu.sp()), true); 544 545 // Verify the CPU state. 546 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { 547 if (isFP(id)) { 548 CHECK_EQ(cpu.gpr(id), originalState.gpr(id)); 549 continue; 550 } 551 if (isSpecialGPR(id)) 552 continue; 553 CHECK_EQ(cpu.gpr(id), testWord(id)); 554 } 555 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 556 CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id)); 557 CHECK_EQ(cpu.spr(flagsSPR), modifiedFlags); 558 559 // Fill the stack with values. 560 uintptr_t* p = reinterpret_cast<uintptr_t*>(newSP); 561 int count = 0; 562 while (p < reinterpret_cast<uintptr_t*>(originalSP)) 563 *p++ = testWord(count++); 564 }; 565 566 void testProbeModifiesStackWithCallback() 567 { 568 unsigned probeCallCount = 0; 569 FillStackData data; 570 CPUState& originalState = data.originalState; 571 void*& originalSP = data.originalSP; 572 void*& newSP = data.newSP; 573 uintptr_t& modifiedFlags = data.modifiedFlags; 574 size_t numberOfExtraEntriesToWrite = 10; // ARM64 requires that this be 2 word aligned. 575 MacroAssembler::SPRegisterID& flagsSPR = data.flagsSPR; 537 size_t numberOfExtraEntriesToWrite { 10 }; // ARM64 requires that this be 2 word aligned. 576 538 577 539 #if CPU(X86) || CPU(X86_64) 578 flagsSPR = X86Registers::eflags;540 MacroAssembler::SPRegisterID flagsSPR = X86Registers::eflags; 579 541 uintptr_t flagsMask = 0xc5; 580 542 #elif CPU(ARM_THUMB2) || CPU(ARM_TRADITIONAL) 581 flagsSPR = ARMRegisters::apsr;582 uintptr_t flagsMask = 0xf 0000000;543 MacroAssembler::SPRegisterID flagsSPR = ARMRegisters::apsr; 544 uintptr_t flagsMask = 0xf8000000; 583 545 #elif CPU(ARM64) 584 flagsSPR = ARM64Registers::nzcv;546 MacroAssembler::SPRegisterID flagsSPR = ARM64Registers::nzcv; 585 547 uintptr_t flagsMask = 0xf0000000; 586 548 #endif … … 590 552 591 553 // Write expected values into the registers. 592 jit.probe([&] (Probe::State* context) { 593 auto& cpu = context->cpu; 554 jit.probe([&] (Probe::Context& context) { 555 auto& cpu = context.cpu; 556 auto& stack = context.stack(); 594 557 probeCallCount++; 595 558 … … 609 572 cpu.spr(flagsSPR) = modifiedFlags; 610 573 611 CHECK_EQ(reinterpret_cast<void*>(context->initializeStackFunction), 0);612 613 // Prepare for initializeStack callback.614 context->initializeStackFunction = fillStack;615 context->initializeStackArg = &data;616 617 574 // Ensure that we'll be writing over the regions of the stack where the Probe::State is. 618 575 originalSP = cpu.sp(); 619 newSP = reinterpret_cast<uintptr_t*>( context) - numberOfExtraEntriesToWrite;576 newSP = reinterpret_cast<uintptr_t*>(probeStateForContext(context)) - numberOfExtraEntriesToWrite; 620 577 cpu.sp() = newSP; 578 579 // Fill the stack with values. 580 uintptr_t* p = reinterpret_cast<uintptr_t*>(newSP); 581 int count = 0; 582 stack.set<double>(p++, 1.23456789); 583 if (is32Bit()) 584 p++; // On 32-bit targets, a double takes up 2 uintptr_t. 585 while (p < reinterpret_cast<uintptr_t*>(originalSP)) 586 stack.set<uintptr_t>(p++, testWord(count++)); 621 587 }); 622 588 623 589 // Validate that the registers and stack have the expected values. 624 jit.probe([&] (Probe::State* context) { 625 auto& cpu = context->cpu; 590 jit.probe([&] (Probe::Context& context) { 591 auto& cpu = context.cpu; 592 auto& stack = context.stack(); 626 593 probeCallCount++; 627 594 … … 638 605 for (auto id = CCallHelpers::firstFPRegister(); id <= CCallHelpers::lastFPRegister(); id = nextID(id)) 639 606 CHECK_EQ(cpu.fpr<uint64_t>(id), testWord64(id)); 640 CHECK_EQ(cpu.spr(flagsSPR) , modifiedFlags);607 CHECK_EQ(cpu.spr(flagsSPR) & flagsMask, modifiedFlags & flagsMask); 641 608 CHECK_EQ(cpu.sp(), newSP); 642 609 643 // Validate the stack withvalues.610 // Validate the stack values. 644 611 uintptr_t* p = reinterpret_cast<uintptr_t*>(newSP); 645 612 int count = 0; 613 CHECK_EQ(stack.get<double>(p++), 1.23456789); 614 if (is32Bit()) 615 p++; // On 32-bit targets, a double takes up 2 uintptr_t. 646 616 while (p < reinterpret_cast<uintptr_t*>(originalSP)) 647 CHECK_EQ( *p++, testWord(count++));617 CHECK_EQ(stack.get<uintptr_t>(p++), testWord(count++)); 648 618 }); 649 619 650 620 // Restore the original state. 651 jit.probe([&] (Probe:: State*context) {652 auto& cpu = context ->cpu;621 jit.probe([&] (Probe::Context& context) { 622 auto& cpu = context.cpu; 653 623 probeCallCount++; 654 624 for (auto id = CCallHelpers::firstRegister(); id <= CCallHelpers::lastRegister(); id = nextID(id)) { … … 708 678 RUN(testProbeModifiesStackPointerToNBytesBelowSP()); 709 679 RUN(testProbeModifiesProgramCounter()); 710 RUN(testProbeModifiesStack WithCallback());680 RUN(testProbeModifiesStackValues()); 711 681 #endif // ENABLE(MASM_PROBE) 712 682
Note:
See TracChangeset
for help on using the changeset viewer.