Changeset 96415 in webkit
- Timestamp:
- Sep 30, 2011 1:01:38 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r96406 r96415 1 2011-09-30 Gavin Barraclough <barraclough@apple.com> 2 3 Merge some more of DFGSpeculativeJIT 32_64/64 4 https://bugs.webkit.org/show_bug.cgi?id=69164 5 6 Reviewed by Oliver Hunt. 7 8 * dfg/DFGJITCodeGenerator.h: 9 * dfg/DFGJITCodeGenerator32_64.cpp: 10 * dfg/DFGJITCodeGenerator64.cpp: 11 * dfg/DFGSpeculativeJIT.cpp: 12 (JSC::DFG::SpeculativeJIT::compilePeepHoleBranch): 13 * dfg/DFGSpeculativeJIT.h: 14 * dfg/DFGSpeculativeJIT32_64.cpp: 15 (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal): 16 (JSC::DFG::SpeculativeJIT::compare): 17 (JSC::DFG::SpeculativeJIT::compileValueAdd): 18 (JSC::DFG::SpeculativeJIT::compileLogicalNot): 19 (JSC::DFG::SpeculativeJIT::compile): 20 * dfg/DFGSpeculativeJIT64.cpp: 21 (JSC::DFG::SpeculativeJIT::compare): 22 (JSC::DFG::SpeculativeJIT::compileValueAdd): 23 (JSC::DFG::SpeculativeJIT::compileLogicalNot): 24 (JSC::DFG::SpeculativeJIT::compile): 25 1 26 2011-09-30 Mark Hahnenberg <mhahnenberg@apple.com> 2 27 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r96391 r96415 780 780 void emitBranch(Node&); 781 781 782 void nonSpeculativeLogicalNot(Node&);783 784 782 MacroAssembler::Address addressOfCallData(int idx) 785 783 { -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp
r96391 r96415 1555 1555 } 1556 1556 1557 void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)1558 {1559 JSValueOperand arg1(this, node.child1());1560 GPRTemporary resultTag(this, arg1);1561 GPRTemporary resultPayload(this, arg1, false);1562 GPRReg arg1TagGPR = arg1.tagGPR();1563 GPRReg arg1PayloadGPR = arg1.payloadGPR();1564 GPRReg resultTagGPR = resultTag.gpr();1565 GPRReg resultPayloadGPR = resultPayload.gpr();1566 1567 arg1.use();1568 1569 JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));1570 1571 silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);1572 m_jit.push(arg1TagGPR);1573 m_jit.push(arg1PayloadGPR);1574 m_jit.push(GPRInfo::callFrameRegister);1575 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);1576 m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);1577 silentFillAllRegisters(resultTagGPR, resultPayloadGPR);1578 JITCompiler::Jump doNot = m_jit.jump();1579 1580 fastCase.link(&m_jit);1581 m_jit.move(arg1PayloadGPR, resultPayloadGPR);1582 1583 doNot.link(&m_jit);1584 m_jit.xor32(TrustedImm32(1), resultPayloadGPR);1585 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);1586 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);1587 }1588 1589 1557 void JITCodeGenerator::emitCall(Node& node) 1590 1558 { -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp
r96377 r96415 1526 1526 } 1527 1527 1528 void JITCodeGenerator::nonSpeculativeLogicalNot(Node& node)1529 {1530 JSValueOperand arg1(this, node.child1());1531 GPRTemporary result(this);1532 1533 GPRReg arg1GPR = arg1.gpr();1534 GPRReg resultGPR = result.gpr();1535 1536 arg1.use();1537 1538 m_jit.move(arg1GPR, resultGPR);1539 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);1540 JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));1541 1542 silentSpillAllRegisters(resultGPR);1543 m_jit.move(arg1GPR, GPRInfo::argumentGPR1);1544 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);1545 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);1546 m_jit.move(GPRInfo::returnValueGPR, resultGPR);1547 silentFillAllRegisters(resultGPR);1548 1549 fastCase.link(&m_jit);1550 1551 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);1552 jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);1553 }1554 1555 1528 void JITCodeGenerator::emitCall(Node& node) 1556 1529 { -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r96379 r96415 193 193 if (notTaken != (m_block + 1)) 194 194 addBranch(m_jit.jump(), notTaken); 195 } 196 197 // Returns true if the compare is fused with a subsequent branch. 198 bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation) 199 { 200 // Fused compare & branch. 201 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 202 if (branchNodeIndex != NoNode) { 203 // detectPeepHoleBranch currently only permits the branch to be the very next node, 204 // so can be no intervening nodes to also reference the compare. 205 ASSERT(node.adjustedRefCount() == 1); 206 207 if (shouldSpeculateInteger(node.child1(), node.child2())) { 208 compilePeepHoleIntegerBranch(node, branchNodeIndex, condition); 209 use(node.child1()); 210 use(node.child2()); 211 } else if (shouldSpeculateNumber(node.child1(), node.child2())) { 212 compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition); 213 use(node.child1()); 214 use(node.child2()); 215 } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) { 216 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr); 217 use(node.child1()); 218 use(node.child2()); 219 } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) { 220 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr); 221 use(node.child1()); 222 use(node.child2()); 223 } else 224 nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation); 225 226 m_compileIndex = branchNodeIndex; 227 return true; 228 } 229 return false; 195 230 } 196 231 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r96379 r96415 571 571 572 572 bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ); 573 bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, Z_DFGOperation_EJJ); 573 574 void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition); 574 575 void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition); 575 576 void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex, void* vptr); 576 577 void compileObjectEquality(Node&, void* vptr); 578 void compileValueAdd(Node&); 579 void compileLogicalNot(Node&); 577 580 578 581 // It is acceptable to have structure be equal to scratch, so long as you're fine -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r96389 r96415 102 102 case DataFormatBoolean: 103 103 case DataFormatJSDouble: 104 case DataFormatJSCell: 104 case DataFormatJSCell: 105 105 case DataFormatJSBoolean: { 106 106 terminateSpeculativeExecution(); … … 374 374 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation) 375 375 { 376 // Fused compare & branch. 377 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 378 if (branchNodeIndex != NoNode) { 379 // detectPeepHoleBranch currently only permits the branch to be the very next node, 380 // so can be no intervening nodes to also reference the compare. 381 ASSERT(node.adjustedRefCount() == 1); 382 383 if (shouldSpeculateInteger(node.child1(), node.child2())) { 384 compilePeepHoleIntegerBranch(node, branchNodeIndex, condition); 385 use(node.child1()); 386 use(node.child2()); 387 } else if (shouldSpeculateNumber(node.child1(), node.child2())) { 388 compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition); 389 use(node.child1()); 390 use(node.child2()); 391 } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) { 392 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr); 393 use(node.child1()); 394 use(node.child2()); 395 } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) { 396 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr); 397 use(node.child1()); 398 use(node.child2()); 399 } else 400 nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation); 401 402 m_compileIndex = branchNodeIndex; 376 if (compilePeepHoleBranch(node, condition, doubleCondition, operation)) 403 377 return true; 404 }405 378 406 379 if (shouldSpeculateFinalObject(node.child1(), node.child2())) … … 441 414 } 442 415 416 void SpeculativeJIT::compileValueAdd(Node& node) 417 { 418 JSValueOperand op1(this, node.child1()); 419 JSValueOperand op2(this, node.child2()); 420 421 GPRReg op1TagGPR = op1.tagGPR(); 422 GPRReg op1PayloadGPR = op1.payloadGPR(); 423 GPRReg op2TagGPR = op2.tagGPR(); 424 GPRReg op2PayloadGPR = op2.payloadGPR(); 425 426 flushRegisters(); 427 428 GPRResult2 resultTag(this); 429 GPRResult resultPayload(this); 430 if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2())) 431 callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR); 432 else 433 callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR); 434 435 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); 436 } 437 438 void SpeculativeJIT::compileLogicalNot(Node& node) 439 { 440 // FIXME: Need to add fast paths for known booleans. 441 JSValueOperand value(this, node.child1()); 442 GPRTemporary resultTag(this, value); 443 GPRTemporary resultPayload(this, value, false); 444 speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag))); 445 m_jit.move(value.payloadGPR(), resultPayload.gpr()); 446 m_jit.xor32(TrustedImm32(1), resultPayload.gpr()); 447 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr()); 448 449 // If we add a DataFormatBool, we should use it here. 450 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean); 451 452 // This code is moved from nonSpeculativeLogicalNot, currently unused! 453 #if 0 454 JSValueOperand arg1(this, node.child1()); 455 GPRTemporary resultTag(this, arg1); 456 GPRTemporary resultPayload(this, arg1, false); 457 GPRReg arg1TagGPR = arg1.tagGPR(); 458 GPRReg arg1PayloadGPR = arg1.payloadGPR(); 459 GPRReg resultTagGPR = resultTag.gpr(); 460 GPRReg resultPayloadGPR = resultPayload.gpr(); 461 462 arg1.use(); 463 464 JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag)); 465 466 silentSpillAllRegisters(resultTagGPR, resultPayloadGPR); 467 m_jit.push(arg1TagGPR); 468 m_jit.push(arg1PayloadGPR); 469 m_jit.push(GPRInfo::callFrameRegister); 470 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean); 471 m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR); 472 silentFillAllRegisters(resultTagGPR, resultPayloadGPR); 473 JITCompiler::Jump doNot = m_jit.jump(); 474 475 fastCase.link(&m_jit); 476 m_jit.move(arg1PayloadGPR, resultPayloadGPR); 477 478 doNot.link(&m_jit); 479 m_jit.xor32(TrustedImm32(1), resultPayloadGPR); 480 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR); 481 jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly); 482 #endif 483 } 484 443 485 void SpeculativeJIT::compile(Node& node) 444 486 { … … 460 502 461 503 GPRTemporary result(this); 462 VirtualRegister virtualRegister = node.virtualRegister();463 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());464 504 if (isInt32Prediction(prediction)) { 505 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr()); 506 465 507 // Like integerResult, but don't useChildren - our children are phi nodes, 466 508 // and don't represent values within this dataflow with virtual registers. 509 VirtualRegister virtualRegister = node.virtualRegister(); 467 510 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger); 468 511 m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr()); 469 } else { 470 // Like jsValueResult, but don't useChildren - our children are phi nodes, 471 // and don't represent values within this dataflow with virtual registers. 472 GPRTemporary tag(this); 473 m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr()); 474 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS); 475 m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS); 476 477 DataFormat format; 478 if (isArrayPrediction(prediction)) 479 format = DataFormatJSCell; 480 else if (isBooleanPrediction(prediction)) 481 format = DataFormatJSBoolean; 482 else 483 format = DataFormatJS; 484 485 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format); 486 } 512 break; 513 } 514 515 GPRTemporary tag(this); 516 m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr()); 517 m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr()); 518 519 // Like jsValueResult, but don't useChildren - our children are phi nodes, 520 // and don't represent values within this dataflow with virtual registers. 521 VirtualRegister virtualRegister = node.virtualRegister(); 522 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS); 523 m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS); 524 525 DataFormat format; 526 if (isArrayPrediction(prediction)) 527 format = DataFormatJSCell; 528 else if (isBooleanPrediction(prediction)) 529 format = DataFormatJSBoolean; 530 else 531 format = DataFormatJS; 532 533 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format); 487 534 break; 488 535 } … … 617 664 IntegerOperand op1(this, node.child1()); 618 665 FPRTemporary result(this); 619 GPRTemporary address(this, op1);620 666 621 667 GPRReg inputGPR = op1.gpr(); 622 668 FPRReg outputFPR = result.fpr(); 623 GPRReg addressGPR = address.gpr();624 669 625 670 m_jit.convertInt32ToDouble(inputGPR, outputFPR); 626 671 627 672 JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0)); 628 m_jit.move(JITCompiler::TrustedImmPtr(&twoToThe32), addressGPR); 629 m_jit.addDouble(JITCompiler::Address(addressGPR, 0), outputFPR); 673 m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR); 630 674 positive.link(&m_jit); 631 675 … … 765 809 766 810 ASSERT(op == ValueAdd); 767 768 JSValueOperand op1(this, node.child1()); 769 JSValueOperand op2(this, node.child2()); 770 771 GPRReg op1TagGPR = op1.tagGPR(); 772 GPRReg op1PayloadGPR = op1.payloadGPR(); 773 GPRReg op2TagGPR = op2.tagGPR(); 774 GPRReg op2PayloadGPR = op2.payloadGPR(); 775 776 flushRegisters(); 777 778 GPRResult2 resultTag(this); 779 GPRResult resultPayload(this); 780 if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2())) 781 callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR); 782 else 783 callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR); 784 785 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex); 811 compileValueAdd(node); 786 812 break; 787 813 } … … 1063 1089 } 1064 1090 1065 case LogicalNot: { 1066 // FIXME: Need to add fast paths for known booleans. 1067 JSValueOperand value(this, node.child1()); 1068 GPRTemporary resultTag(this, value); 1069 GPRTemporary resultPayload(this, value, false); 1070 speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag))); 1071 m_jit.move(value.payloadGPR(), resultPayload.gpr()); 1072 m_jit.xor32(TrustedImm32(1), resultPayload.gpr()); 1073 m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr()); 1074 1075 // If we add a DataFormatBool, we should use it here. 1076 jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean); 1077 break; 1078 } 1091 case LogicalNot: 1092 compileLogicalNot(node); 1093 break; 1079 1094 1080 1095 case CompareLess: … … 1157 1172 SpeculateStrictInt32Operand property(this, node.child2()); 1158 1173 JSValueOperand value(this, node.child3()); 1159 GPRTemporary scratch(this , base);1174 GPRTemporary scratch(this); 1160 1175 1161 1176 // Map base, property & value into registers, allocate a scratch register. -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r96389 r96415 477 477 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation) 478 478 { 479 // Fused compare & branch. 480 NodeIndex branchNodeIndex = detectPeepHoleBranch(); 481 if (branchNodeIndex != NoNode) { 482 // detectPeepHoleBranch currently only permits the branch to be the very next node, 483 // so can be no intervening nodes to also reference the compare. 484 ASSERT(node.adjustedRefCount() == 1); 485 486 if (shouldSpeculateInteger(node.child1(), node.child2())) { 487 compilePeepHoleIntegerBranch(node, branchNodeIndex, condition); 488 use(node.child1()); 489 use(node.child2()); 490 } else if (shouldSpeculateNumber(node.child1(), node.child2())) { 491 compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition); 492 use(node.child1()); 493 use(node.child2()); 494 } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) { 495 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr); 496 use(node.child1()); 497 use(node.child2()); 498 } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) { 499 compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr); 500 use(node.child1()); 501 use(node.child2()); 502 } else 503 nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation); 504 505 m_compileIndex = branchNodeIndex; 479 if (compilePeepHoleBranch(node, condition, doubleCondition, operation)) 506 480 return true; 507 }508 481 509 482 if (shouldSpeculateInteger(node.child1(), node.child2())) { … … 538 511 } 539 512 513 void SpeculativeJIT::compileValueAdd(Node& node) 514 { 515 JSValueOperand op1(this, node.child1()); 516 JSValueOperand op2(this, node.child2()); 517 518 GPRReg op1GPR = op1.gpr(); 519 GPRReg op2GPR = op2.gpr(); 520 521 flushRegisters(); 522 523 GPRResult result(this); 524 if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2())) 525 callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR); 526 else 527 callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR); 528 529 jsValueResult(result.gpr(), m_compileIndex); 530 } 531 532 void SpeculativeJIT::compileLogicalNot(Node& node) 533 { 534 if (isKnownBoolean(node.child1())) { 535 SpeculateBooleanOperand value(this, node.child1()); 536 GPRTemporary result(this, value); 537 538 m_jit.move(value.gpr(), result.gpr()); 539 m_jit.xorPtr(TrustedImm32(true), result.gpr()); 540 541 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 542 return; 543 } 544 545 PredictedType prediction = m_jit.getPrediction(node.child1()); 546 if (isBooleanPrediction(prediction) || !prediction) { 547 JSValueOperand value(this, node.child1()); 548 GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add). 549 550 m_jit.move(value.gpr(), result.gpr()); 551 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr()); 552 speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1)))); 553 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr()); 554 555 // If we add a DataFormatBool, we should use it here. 556 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 557 return; 558 } 559 560 JSValueOperand arg1(this, node.child1()); 561 GPRTemporary result(this); 562 563 GPRReg arg1GPR = arg1.gpr(); 564 GPRReg resultGPR = result.gpr(); 565 566 arg1.use(); 567 568 m_jit.move(arg1GPR, resultGPR); 569 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR); 570 JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1))); 571 572 silentSpillAllRegisters(resultGPR); 573 m_jit.move(arg1GPR, GPRInfo::argumentGPR1); 574 m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0); 575 appendCallWithExceptionCheck(dfgConvertJSValueToBoolean); 576 m_jit.move(GPRInfo::returnValueGPR, resultGPR); 577 silentFillAllRegisters(resultGPR); 578 579 fastCase.link(&m_jit); 580 581 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR); 582 jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly); 583 } 584 540 585 void SpeculativeJIT::compile(Node& node) 541 586 { … … 565 610 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger); 566 611 m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr()); 567 } else { 568 m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr()); 569 570 // Like jsValueResult, but don't useChildren - our children are phi nodes, 571 // and don't represent values within this dataflow with virtual registers. 572 VirtualRegister virtualRegister = node.virtualRegister(); 573 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS); 574 575 DataFormat format; 576 if (isArrayPrediction(prediction)) 577 format = DataFormatJSCell; 578 else if (isBooleanPrediction(prediction)) 579 format = DataFormatJSBoolean; 580 else 581 format = DataFormatJS; 582 583 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format); 584 } 612 break; 613 } 614 615 m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr()); 616 617 // Like jsValueResult, but don't useChildren - our children are phi nodes, 618 // and don't represent values within this dataflow with virtual registers. 619 VirtualRegister virtualRegister = node.virtualRegister(); 620 m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS); 621 622 DataFormat format; 623 if (isArrayPrediction(prediction)) 624 format = DataFormatJSCell; 625 else if (isBooleanPrediction(prediction)) 626 format = DataFormatJSBoolean; 627 else 628 format = DataFormatJS; 629 630 m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format); 585 631 break; 586 632 } … … 863 909 864 910 ASSERT(op == ValueAdd); 865 866 JSValueOperand op1(this, node.child1()); 867 JSValueOperand op2(this, node.child2()); 868 869 GPRReg op1GPR = op1.gpr(); 870 GPRReg op2GPR = op2.gpr(); 871 872 flushRegisters(); 873 874 GPRResult result(this); 875 if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2())) 876 callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR); 877 else 878 callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR); 879 880 jsValueResult(result.gpr(), m_compileIndex); 911 compileValueAdd(node); 881 912 break; 882 913 } … … 1158 1189 } 1159 1190 1160 case LogicalNot: { 1161 if (isKnownBoolean(node.child1())) { 1162 SpeculateBooleanOperand value(this, node.child1()); 1163 GPRTemporary result(this, value); 1164 1165 m_jit.move(value.gpr(), result.gpr()); 1166 m_jit.xorPtr(TrustedImm32(true), result.gpr()); 1167 1168 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 1169 break; 1170 } 1171 1172 PredictedType prediction = m_jit.getPrediction(node.child1()); 1173 if (isBooleanPrediction(prediction) || !prediction) { 1174 JSValueOperand value(this, node.child1()); 1175 GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add). 1176 1177 m_jit.move(value.gpr(), result.gpr()); 1178 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr()); 1179 speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1)))); 1180 m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr()); 1181 1182 // If we add a DataFormatBool, we should use it here. 1183 jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean); 1184 break; 1185 } 1186 1187 nonSpeculativeLogicalNot(node); 1188 1189 break; 1190 } 1191 case LogicalNot: 1192 compileLogicalNot(node); 1193 break; 1191 1194 1192 1195 case CompareLess:
Note: See TracChangeset
for help on using the changeset viewer.