Changeset 96750 in webkit
- Timestamp:
- Oct 5, 2011 2:36:23 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r96741 r96750 1 2011-10-04 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should be capable of a broader range of speculations on branch and not 4 https://bugs.webkit.org/show_bug.cgi?id=69322 5 6 Reviewed by Oliver Hunt. 7 8 * bytecode/PredictedType.h: 9 (JSC::isFinalObjectOrOtherPrediction): 10 (JSC::isArrayOrOtherPrediction): 11 * dfg/DFGJITCodeGenerator.cpp: 12 * dfg/DFGJITCodeGenerator.h: 13 (JSC::DFG::JITCodeGenerator::JITCodeGenerator): 14 * dfg/DFGJITCodeGenerator32_64.cpp: 15 (JSC::DFG::JITCodeGenerator::fillDouble): 16 (JSC::DFG::JITCodeGenerator::fillJSValue): 17 * dfg/DFGJITCodeGenerator64.cpp: 18 (JSC::DFG::JITCodeGenerator::fillDouble): 19 (JSC::DFG::JITCodeGenerator::fillJSValue): 20 * dfg/DFGOperations.cpp: 21 * dfg/DFGSpeculativeJIT.h: 22 (JSC::DFG::SpeculativeJIT::shouldSpeculateFinalObjectOrOther): 23 (JSC::DFG::SpeculativeJIT::shouldSpeculateArrayOrOther): 24 (JSC::DFG::SpeculativeJIT::SpeculativeJIT): 25 * dfg/DFGSpeculativeJIT32_64.cpp: 26 (JSC::DFG::SpeculativeJIT::emitBranch): 27 * dfg/DFGSpeculativeJIT64.cpp: 28 (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot): 29 (JSC::DFG::SpeculativeJIT::compileLogicalNot): 30 (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): 31 (JSC::DFG::SpeculativeJIT::emitBranch): 32 1 33 2011-10-05 Sheriff Bot <webkit.review.bot@gmail.com> 2 34 -
trunk/Source/JavaScriptCore/bytecode/PredictedType.h
r95930 r96750 68 68 } 69 69 70 inline bool isFinalObjectOrOtherPrediction(PredictedType value) 71 { 72 return !!(value & (PredictFinalObject | PredictOther)) && !(value & ~(PredictFinalObject | PredictOther)); 73 } 74 70 75 inline bool isStringPrediction(PredictedType value) 71 76 { … … 76 81 { 77 82 return value == PredictArray; 83 } 84 85 inline bool isArrayOrOtherPrediction(PredictedType value) 86 { 87 return !!(value & (PredictArray | PredictOther)) && !(value & ~(PredictArray | PredictOther)); 78 88 } 79 89 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r96673 r96750 875 875 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw); 876 876 CodeBlock* codeBlock = debugInfo->codeBlock; 877 printf("Speculation failure in %p at 0x%x with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, success/fail %u/%u\n", codeBlock, debugInfo->debugOffset, codeBlock->alternative()->executeCounter(), codeBlock->alternative()->reoptimizationRetryCounter(), codeBlock->alternative()->optimizationDelayCounter(), codeBlock->speculativeSuccessCounter(), codeBlock->speculativeFailCounter()); 877 CodeBlock* alternative = codeBlock->alternative(); 878 printf("Speculation failure in %p at 0x%x with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u, success/fail %u/%u\n", codeBlock, debugInfo->debugOffset, alternative ? alternative->executeCounter() : 0, alternative ? alternative->reoptimizationRetryCounter() : 0, alternative ? alternative->optimizationDelayCounter() : 0, codeBlock->speculativeSuccessCounter(), codeBlock->speculativeFailCounter()); 878 879 } 879 880 #endif -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r96661 r96750 501 501 } 502 502 503 bool shouldSpeculateFinalObjectOrOther(NodeIndex nodeIndex) 504 { 505 return isFinalObjectOrOtherPrediction(m_jit.getPrediction(nodeIndex)); 506 } 507 503 508 bool shouldSpeculateArray(NodeIndex nodeIndex) 504 509 { … … 509 514 prediction = m_jit.getPrediction(nodeIndex); 510 515 return isArrayPrediction(prediction); 516 } 517 518 bool shouldSpeculateArrayOrOther(NodeIndex nodeIndex) 519 { 520 return isArrayOrOtherPrediction(m_jit.getPrediction(nodeIndex)); 511 521 } 512 522 … … 600 610 void compileObjectEquality(Node&, void* vptr); 601 611 void compileValueAdd(Node&); 612 void compileObjectOrOtherLogicalNot(NodeIndex value, void* vptr); 602 613 void compileLogicalNot(Node&); 614 void emitObjectOrOtherBranch(NodeIndex value, BlockIndex taken, BlockIndex notTaken, void *vptr); 603 615 void emitBranch(Node&); 604 616 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r96661 r96750 436 436 } 437 437 438 void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void* vptr) 439 { 440 JSValueOperand value(this, nodeIndex); 441 GPRTemporary resultTag(this); 442 GPRTemporary resultPayload(this); 443 GPRReg valueTagGPR = value.tagGPR(); 444 GPRReg valuePayloadGPR = value.payloadGPR(); 445 GPRReg resultTagGPR = resultTag.gpr(); 446 GPRReg resultPayloadGPR = resultPayload.gpr(); 447 448 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr()); 449 450 MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag)); 451 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr))); 452 m_jit.move(TrustedImm32(1), resultPayloadGPR); 453 MacroAssembler::Jump done = m_jit.jump(); 454 455 notCell.link(&m_jit); 456 457 m_jit.move(valueTagGPR, resultPayloadGPR); 458 m_jit.and32(MacroAssembler::TrustedImm32(JSValue::UndefinedTag), resultPayloadGPR); 459 speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, resultPayloadGPR, TrustedImm32(JSValue::UndefinedTag))); 460 m_jit.move(TrustedImm32(0), resultPayloadGPR); 461 462 done.link(&m_jit); 463 464 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean); 465 } 466 438 467 void SpeculativeJIT::compileLogicalNot(Node& node) 439 468 { 440 469 // FIXME: Need to add fast paths for known booleans. 470 471 if (shouldSpeculateFinalObjectOrOther(node.child1())) { 472 compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsFinalObjectVPtr); 473 return; 474 } 475 if (shouldSpeculateArrayOrOther(node.child1())) { 476 compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsArrayVPtr); 477 return; 478 } 479 if (shouldSpeculateInteger(node.child1())) { 480 SpeculateIntegerOperand value(this, node.child1()); 481 GPRTemporary resultPayload(this, value); 482 GPRTemporary resultTag(this); 483 m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), resultPayload.gpr()); 484 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr()); 485 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean); 486 return; 487 } 488 if (shouldSpeculateNumber(node.child1())) { 489 SpeculateDoubleOperand value(this, node.child1()); 490 FPRTemporary scratch(this); 491 GPRTemporary resultTag(this); 492 GPRTemporary resultPayload(this); 493 m_jit.move(TrustedImm32(0), resultPayload.gpr()); 494 MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr()); 495 m_jit.move(TrustedImm32(1), resultPayload.gpr()); 496 nonZero.link(&m_jit); 497 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr()); 498 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean); 499 return; 500 } 501 441 502 JSValueOperand value(this, node.child1()); 442 503 GPRTemporary resultTag(this, value); … … 483 544 } 484 545 485 void SpeculativeJIT::emit Branch(Node& node)546 void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, void *vptr) 486 547 { 487 // FIXME: Add fast cases for known Boolean! 488 JSValueOperand value(this, node.child1()); 489 value.fill(); 548 JSValueOperand value(this, nodeIndex); 490 549 GPRReg valueTagGPR = value.tagGPR(); 491 550 GPRReg valuePayloadGPR = value.payloadGPR(); 492 493 GPRTemporary result(this);494 GPRReg resultGPR = result.gpr();495 551 496 use(node.child1()); 552 MacroAssembler::Jump notCell = m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::CellTag)); 553 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valuePayloadGPR), MacroAssembler::TrustedImmPtr(vptr))); 554 addBranch(m_jit.jump(), taken); 497 555 498 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset()); 499 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset()); 500 501 JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)); 502 JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag)); 503 504 fastPath.link(&m_jit); 505 addBranch(m_jit.branchTest32(JITCompiler::Zero, valuePayloadGPR), notTaken); 506 addBranch(m_jit.jump(), taken); 507 508 slowPath.link(&m_jit); 509 silentSpillAllRegisters(resultGPR); 510 m_jit.push(valueTagGPR); 511 m_jit.push(valuePayloadGPR); 512 m_jit.push(GPRInfo::callFrameRegister); 513 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean); 514 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 515 silentFillAllRegisters(resultGPR); 556 notCell.link(&m_jit); 516 557 517 addBranch(m_jit.branchTest8(JITCompiler::NonZero, resultGPR), taken); 558 m_jit.and32(MacroAssembler::TrustedImm32(JSValue::UndefinedTag), valueTagGPR); 559 speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, valueTagGPR, TrustedImm32(JSValue::UndefinedTag))); 518 560 if (notTaken != (m_block + 1)) 519 561 addBranch(m_jit.jump(), notTaken); 520 562 521 noResult(m_compileIndex, UseChildrenCalledExplicitly); 563 noResult(m_compileIndex); 564 } 565 566 void SpeculativeJIT::emitBranch(Node& node) 567 { 568 BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset()); 569 BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset()); 570 571 // FIXME: Add fast cases for known Boolean! 572 573 if (shouldSpeculateFinalObjectOrOther(node.child1())) { 574 emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsFinalObjectVPtr); 575 } else if (shouldSpeculateArrayOrOther(node.child1())) { 576 emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsArrayVPtr); 577 } else if (shouldSpeculateNumber(node.child1())) { 578 if (shouldSpeculateInteger(node.child1())) { 579 bool invert = false; 580 581 if (taken == (m_block + 1)) { 582 invert = true; 583 BlockIndex tmp = taken; 584 taken = notTaken; 585 notTaken = tmp; 586 } 587 588 SpeculateIntegerOperand value(this, node.child1()); 589 addBranch(m_jit.branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr()), taken); 590 } else { 591 SpeculateDoubleOperand value(this, node.child1()); 592 FPRTemporary scratch(this); 593 addBranch(m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr()), taken); 594 } 595 596 if (notTaken != (m_block + 1)) 597 addBranch(m_jit.jump(), notTaken); 598 599 noResult(m_compileIndex); 600 } else { 601 JSValueOperand value(this, node.child1()); 602 value.fill(); 603 GPRReg valueTagGPR = value.tagGPR(); 604 GPRReg valuePayloadGPR = value.payloadGPR(); 605 606 GPRTemporary result(this); 607 GPRReg resultGPR = result.gpr(); 608 609 use(node.child1()); 610 611 JITCompiler::Jump fastPath = m_jit.branch32(JITCompiler::Equal, valueTagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)); 612 JITCompiler::Jump slowPath = m_jit.branch32(JITCompiler::NotEqual, valueTagGPR, JITCompiler::TrustedImm32(JSValue::BooleanTag)); 613 614 fastPath.link(&m_jit); 615 addBranch(m_jit.branchTest32(JITCompiler::Zero, valuePayloadGPR), notTaken); 616 addBranch(m_jit.jump(), taken); 617 618 slowPath.link(&m_jit); 619 silentSpillAllRegisters(resultGPR); 620 m_jit.push(valueTagGPR); 621 m_jit.push(valuePayloadGPR); 622 m_jit.push(GPRInfo::callFrameRegister); 623 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean); 624 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 625 silentFillAllRegisters(resultGPR); 626 627 addBranch(m_jit.branchTest8(JITCompiler::NonZero, resultGPR), taken); 628 if (notTaken != (m_block + 1)) 629 addBranch(m_jit.jump(), notTaken); 630 631 noResult(m_compileIndex, UseChildrenCalledExplicitly); 632 } 522 633 } 523 634 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r96661 r96750 530 530 } 531 531 532 void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void *vptr) 533 { 534 JSValueOperand value(this, nodeIndex); 535 GPRTemporary result(this); 536 GPRReg valueGPR = value.gpr(); 537 GPRReg resultGPR = result.gpr(); 538 539 MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); 540 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr))); 541 m_jit.move(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR); 542 MacroAssembler::Jump done = m_jit.jump(); 543 544 notCell.link(&m_jit); 545 546 m_jit.move(valueGPR, resultGPR); 547 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR); 548 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull)))); 549 m_jit.move(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR); 550 551 done.link(&m_jit); 552 553 jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean); 554 } 555 532 556 void SpeculativeJIT::compileLogicalNot(Node& node) 533 557 { … … 539 563 m_jit.xorPtr(TrustedImm32(true), result.gpr()); 540 564 565 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 566 return; 567 } 568 if (shouldSpeculateFinalObjectOrOther(node.child1())) { 569 compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsFinalObjectVPtr); 570 return; 571 } 572 if (shouldSpeculateArrayOrOther(node.child1())) { 573 compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsArrayVPtr); 574 return; 575 } 576 if (shouldSpeculateInteger(node.child1())) { 577 SpeculateIntegerOperand value(this, node.child1()); 578 GPRTemporary result(this, value); 579 m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr()); 580 m_jit.or32(TrustedImm32(ValueFalse), result.gpr()); 581 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 582 return; 583 } 584 if (shouldSpeculateNumber(node.child1())) { 585 SpeculateDoubleOperand value(this, node.child1()); 586 FPRTemporary scratch(this); 587 GPRTemporary result(this); 588 m_jit.move(TrustedImm32(ValueFalse), result.gpr()); 589 MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr()); 590 m_jit.xor32(Imm32(true), result.gpr()); 591 nonZero.link(&m_jit); 541 592 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 542 593 return; … … 583 634 } 584 635 636 void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, void *vptr) 637 { 638 JSValueOperand value(this, nodeIndex); 639 GPRReg valueGPR = value.gpr(); 640 641 MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); 642 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr))); 643 addBranch(m_jit.jump(), taken); 644 645 notCell.link(&m_jit); 646 647 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), valueGPR); 648 speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, valueGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull)))); 649 if (notTaken != (m_block + 1)) 650 addBranch(m_jit.jump(), notTaken); 651 652 noResult(m_compileIndex); 653 } 654 585 655 void SpeculativeJIT::emitBranch(Node& node) 586 656 { … … 606 676 607 677 noResult(m_compileIndex); 678 } else if (shouldSpeculateFinalObjectOrOther(node.child1())) { 679 emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsFinalObjectVPtr); 680 } else if (shouldSpeculateArrayOrOther(node.child1())) { 681 emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsArrayVPtr); 682 } else if (shouldSpeculateNumber(node.child1())) { 683 if (shouldSpeculateInteger(node.child1())) { 684 bool invert = false; 685 686 if (taken == (m_block + 1)) { 687 invert = true; 688 BlockIndex tmp = taken; 689 taken = notTaken; 690 notTaken = tmp; 691 } 692 693 SpeculateIntegerOperand value(this, node.child1()); 694 addBranch(m_jit.branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr()), taken); 695 } else { 696 SpeculateDoubleOperand value(this, node.child1()); 697 FPRTemporary scratch(this); 698 addBranch(m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr()), taken); 699 } 700 701 if (notTaken != (m_block + 1)) 702 addBranch(m_jit.jump(), notTaken); 703 704 noResult(m_compileIndex); 608 705 } else { 609 706 GPRTemporary result(this); … … 615 712 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken); 616 713 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken); 617 714 } 715 716 if (predictBoolean) { 618 717 speculationCheck(m_jit.jump()); 619 718 value.use(); … … 622 721 addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken); 623 722 624 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken); 625 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken); 723 if (!predictBoolean) { 724 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken); 725 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken); 726 } 626 727 627 728 value.use();
Note: See TracChangeset
for help on using the changeset viewer.