Changeset 89961 in webkit
- Timestamp:
- Jun 28, 2011 2:33:38 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r89959 r89961 1 2011-06-28 Gavin Barraclough <barraclough@apple.com> 2 3 Reviewed by Oliver Hunt. 4 5 https://bugs.webkit.org/show_bug.cgi?id=63563 6 DFG JIT - add support for double arith to speculative path 7 8 Add integer support for div & mod, add double support for div, mod, 9 add, sub & mul, dynamically selecting based on operand types. 10 11 * dfg/DFGJITCodeGenerator.cpp: 12 (JSC::DFG::FPRTemporary::FPRTemporary): 13 * dfg/DFGJITCodeGenerator.h: 14 * dfg/DFGJITCompiler.h: 15 (JSC::DFG::JITCompiler::assembler): 16 * dfg/DFGSpeculativeJIT.cpp: 17 (JSC::DFG::SpeculativeJIT::fillSpeculateDouble): 18 (JSC::DFG::SpeculativeJIT::compile): 19 * dfg/DFGSpeculativeJIT.h: 20 (JSC::DFG::SpeculateDoubleOperand::SpeculateDoubleOperand): 21 (JSC::DFG::SpeculateDoubleOperand::~SpeculateDoubleOperand): 22 (JSC::DFG::SpeculateDoubleOperand::index): 23 (JSC::DFG::SpeculateDoubleOperand::fpr): 24 1 25 2011-06-28 Oliver Hunt <oliver@apple.com> 2 26 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.cpp
r89956 r89961 637 637 } 638 638 639 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1) 640 : m_jit(jit) 641 , m_fpr(InvalidFPRReg) 642 { 643 if (m_jit->canReuse(op1.index())) 644 m_fpr = m_jit->reuse(op1.fpr()); 645 else 646 m_fpr = m_jit->fprAllocate(); 647 } 648 649 FPRTemporary::FPRTemporary(JITCodeGenerator* jit, SpeculateDoubleOperand& op1, SpeculateDoubleOperand& op2) 650 : m_jit(jit) 651 , m_fpr(InvalidFPRReg) 652 { 653 if (m_jit->canReuse(op1.index())) 654 m_fpr = m_jit->reuse(op1.fpr()); 655 else if (m_jit->canReuse(op2.index())) 656 m_fpr = m_jit->reuse(op2.fpr()); 657 else 658 m_fpr = m_jit->fprAllocate(); 659 } 660 639 661 } } // namespace JSC::DFG 640 662 -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator.h
r89956 r89961 40 40 class SpeculateIntegerOperand; 41 41 class SpeculateStrictInt32Operand; 42 class SpeculateDoubleOperand; 42 43 class SpeculateCellOperand; 43 44 … … 1036 1037 FPRTemporary(JITCodeGenerator*, DoubleOperand&); 1037 1038 FPRTemporary(JITCodeGenerator*, DoubleOperand&, DoubleOperand&); 1039 FPRTemporary(JITCodeGenerator*, SpeculateDoubleOperand&); 1040 FPRTemporary(JITCodeGenerator*, SpeculateDoubleOperand&, SpeculateDoubleOperand&); 1038 1041 1039 1042 ~FPRTemporary() -
trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.h
r89861 r89961 107 107 CodeBlock* codeBlock() { return m_codeBlock; } 108 108 JSGlobalData* globalData() { return m_globalData; } 109 AssemblerType_T& assembler() { return m_assembler; } 109 110 110 111 #if CPU(X86_64) -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r89957 r89961 175 175 } 176 176 177 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex) 178 { 179 Node& node = m_jit.graph()[nodeIndex]; 180 VirtualRegister virtualRegister = node.virtualRegister(); 181 GenerationInfo& info = m_generationInfo[virtualRegister]; 182 183 if (info.registerFormat() == DataFormatNone) { 184 GPRReg gpr = allocate(); 185 186 if (node.isConstant()) { 187 if (isInt32Constant(nodeIndex)) { 188 FPRReg fpr = fprAllocate(); 189 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(static_cast<double>(valueOfInt32Constant(nodeIndex))))), gpr); 190 m_jit.movePtrToDouble(gpr, fpr); 191 unlock(gpr); 192 193 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble); 194 info.fillDouble(fpr); 195 return fpr; 196 } 197 if (isDoubleConstant(nodeIndex)) { 198 FPRReg fpr = fprAllocate(); 199 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(nodeIndex)))), gpr); 200 m_jit.movePtrToDouble(gpr, fpr); 201 unlock(gpr); 202 203 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble); 204 info.fillDouble(fpr); 205 return fpr; 206 } 207 ASSERT(isJSConstant(nodeIndex)); 208 JSValue jsValue = valueOfJSConstant(nodeIndex); 209 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr); 210 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant); 211 info.fillJSValue(gpr, DataFormatJS); 212 unlock(gpr); 213 } else { 214 DataFormat spillFormat = info.spillFormat(); 215 ASSERT(spillFormat & DataFormatJS); 216 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled); 217 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr); 218 info.fillJSValue(gpr, spillFormat); 219 unlock(gpr); 220 } 221 } 222 223 switch (info.registerFormat()) { 224 case DataFormatNone: 225 // Should have filled, above. 226 ASSERT_NOT_REACHED(); 227 228 case DataFormatCell: 229 case DataFormatJSCell: 230 case DataFormatJS: { 231 GPRReg jsValueGpr = info.gpr(); 232 m_gprs.lock(jsValueGpr); 233 FPRReg fpr = fprAllocate(); 234 GPRReg tempGpr = allocate(); 235 236 JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister); 237 238 speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister)); 239 240 // First, if we get here we have a double encoded as a JSValue 241 m_jit.move(jsValueGpr, tempGpr); 242 m_jit.addPtr(GPRInfo::tagTypeNumberRegister, tempGpr); 243 m_jit.movePtrToDouble(tempGpr, fpr); 244 JITCompiler::Jump hasUnboxedDouble = m_jit.jump(); 245 246 // Finally, handle integers. 247 isInteger.link(&m_jit); 248 m_jit.convertInt32ToDouble(jsValueGpr, fpr); 249 hasUnboxedDouble.link(&m_jit); 250 251 m_gprs.release(jsValueGpr); 252 m_gprs.unlock(jsValueGpr); 253 m_gprs.unlock(tempGpr); 254 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble); 255 info.fillDouble(fpr); 256 return fpr; 257 } 258 259 case DataFormatJSInteger: 260 case DataFormatInteger: { 261 FPRReg fpr = fprAllocate(); 262 GPRReg gpr = info.gpr(); 263 m_gprs.lock(gpr); 264 m_jit.convertInt32ToDouble(gpr, fpr); 265 m_gprs.unlock(gpr); 266 return fpr; 267 } 268 269 // Unbox the double 270 case DataFormatJSDouble: { 271 GPRReg gpr = info.gpr(); 272 FPRReg fpr = unboxDouble(gpr); 273 274 m_gprs.release(gpr); 275 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble); 276 277 info.fillDouble(fpr); 278 return fpr; 279 } 280 281 case DataFormatDouble: { 282 FPRReg fpr = info.fpr(); 283 m_fprs.lock(fpr); 284 return fpr; 285 } 286 } 287 288 ASSERT_NOT_REACHED(); 289 return InvalidFPRReg; 290 } 291 177 292 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex) 178 293 { … … 431 546 432 547 case ValueToNumber: { 433 SpeculateIntegerOperand op1(this, node.child1); 434 GPRTemporary result(this, op1); 435 m_jit.move(op1.gpr(), result.gpr()); 436 integerResult(result.gpr(), m_compileIndex, op1.format()); 548 if (isInteger(node.child1)) { 549 SpeculateIntegerOperand op1(this, node.child1); 550 GPRTemporary result(this, op1); 551 m_jit.move(op1.gpr(), result.gpr()); 552 integerResult(result.gpr(), m_compileIndex, op1.format()); 553 break; 554 } 555 SpeculateDoubleOperand op1(this, node.child1); 556 FPRTemporary result(this, op1); 557 m_jit.moveDouble(op1.fpr(), result.fpr()); 558 doubleResult(result.fpr(), m_compileIndex); 437 559 break; 438 560 } … … 440 562 case ValueAdd: 441 563 case ArithAdd: { 442 if (isInt32Constant(node.child1)) { 443 int32_t imm1 = valueOfInt32Constant(node.child1); 564 if (isInteger(node.child1) || isInteger(node.child2)) { 565 if (isInt32Constant(node.child1)) { 566 int32_t imm1 = valueOfInt32Constant(node.child1); 567 SpeculateIntegerOperand op2(this, node.child2); 568 GPRTemporary result(this); 569 570 speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr())); 571 572 integerResult(result.gpr(), m_compileIndex); 573 break; 574 } 575 576 if (isInt32Constant(node.child2)) { 577 SpeculateIntegerOperand op1(this, node.child1); 578 int32_t imm2 = valueOfInt32Constant(node.child2); 579 GPRTemporary result(this); 580 581 speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 582 583 integerResult(result.gpr(), m_compileIndex); 584 break; 585 } 586 587 SpeculateIntegerOperand op1(this, node.child1); 588 SpeculateIntegerOperand op2(this, node.child2); 589 GPRTemporary result(this, op1, op2); 590 591 GPRReg gpr1 = op1.gpr(); 592 GPRReg gpr2 = op2.gpr(); 593 GPRReg gprResult = result.gpr(); 594 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult); 595 596 if (gpr1 == gprResult) 597 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2)); 598 else if (gpr2 == gprResult) 599 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1)); 600 else 601 speculationCheck(check); 602 603 integerResult(gprResult, m_compileIndex); 604 break; 605 } 606 607 SpeculateDoubleOperand op1(this, node.child1); 608 SpeculateDoubleOperand op2(this, node.child2); 609 FPRTemporary result(this, op1, op2); 610 611 FPRReg reg1 = op1.fpr(); 612 FPRReg reg2 = op2.fpr(); 613 m_jit.addDouble(reg1, reg2, result.fpr()); 614 615 doubleResult(result.fpr(), m_compileIndex); 616 break; 617 } 618 619 case ArithSub: { 620 if (isInteger(node.child1) || isInteger(node.child2)) { 621 if (isInt32Constant(node.child2)) { 622 SpeculateIntegerOperand op1(this, node.child1); 623 int32_t imm2 = valueOfInt32Constant(node.child2); 624 GPRTemporary result(this); 625 626 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 627 628 integerResult(result.gpr(), m_compileIndex); 629 break; 630 } 631 632 SpeculateIntegerOperand op1(this, node.child1); 444 633 SpeculateIntegerOperand op2(this, node.child2); 445 634 GPRTemporary result(this); 446 635 447 speculationCheck(m_jit.branch Add32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));636 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr())); 448 637 449 638 integerResult(result.gpr(), m_compileIndex); 450 639 break; 451 640 } 452 453 if (isInt32Constant(node.child2)) { 641 SpeculateDoubleOperand op1(this, node.child1); 642 SpeculateDoubleOperand op2(this, node.child2); 643 FPRTemporary result(this, op1); 644 645 FPRReg reg1 = op1.fpr(); 646 FPRReg reg2 = op2.fpr(); 647 m_jit.subDouble(reg1, reg2, result.fpr()); 648 649 doubleResult(result.fpr(), m_compileIndex); 650 break; 651 } 652 653 case ArithMul: { 654 if (isInteger(node.child1) && isInteger(node.child2)) { 454 655 SpeculateIntegerOperand op1(this, node.child1); 455 int32_t imm2 = valueOfInt32Constant(node.child2);656 SpeculateIntegerOperand op2(this, node.child2); 456 657 GPRTemporary result(this); 457 658 458 speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 659 GPRReg reg1 = op1.gpr(); 660 GPRReg reg2 = op2.gpr(); 661 speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr())); 662 663 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr()); 664 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0))); 665 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0))); 666 resultNonZero.link(&m_jit); 459 667 460 668 integerResult(result.gpr(), m_compileIndex); 461 669 break; 462 670 } 463 464 SpeculateIntegerOperand op1(this, node.child1); 465 SpeculateIntegerOperand op2(this, node.child2); 466 GPRTemporary result(this, op1, op2); 467 468 GPRReg gpr1 = op1.gpr(); 469 GPRReg gpr2 = op2.gpr(); 470 GPRReg gprResult = result.gpr(); 471 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult); 472 473 if (gpr1 == gprResult) 474 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2)); 475 else if (gpr2 == gprResult) 476 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1)); 477 else 478 speculationCheck(check); 479 480 integerResult(gprResult, m_compileIndex); 481 break; 482 } 483 484 case ArithSub: { 485 if (isInt32Constant(node.child2)) { 486 SpeculateIntegerOperand op1(this, node.child1); 487 int32_t imm2 = valueOfInt32Constant(node.child2); 488 GPRTemporary result(this); 489 490 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr())); 491 492 integerResult(result.gpr(), m_compileIndex); 493 break; 494 } 495 496 SpeculateIntegerOperand op1(this, node.child1); 497 SpeculateIntegerOperand op2(this, node.child2); 498 GPRTemporary result(this); 499 500 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr())); 501 502 integerResult(result.gpr(), m_compileIndex); 503 break; 504 } 505 506 case ArithMul: { 507 SpeculateIntegerOperand op1(this, node.child1); 508 SpeculateIntegerOperand op2(this, node.child2); 509 GPRTemporary result(this); 510 511 GPRReg reg1 = op1.gpr(); 512 GPRReg reg2 = op2.gpr(); 513 speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr())); 514 515 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr()); 516 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0))); 517 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0))); 518 resultNonZero.link(&m_jit); 519 520 integerResult(result.gpr(), m_compileIndex); 671 SpeculateDoubleOperand op1(this, node.child1); 672 SpeculateDoubleOperand op2(this, node.child2); 673 FPRTemporary result(this, op1, op2); 674 675 FPRReg reg1 = op1.fpr(); 676 FPRReg reg2 = op2.fpr(); 677 678 m_jit.mulDouble(reg1, reg2, result.fpr()); 679 680 doubleResult(result.fpr(), m_compileIndex); 521 681 break; 522 682 } 523 683 524 684 case ArithDiv: { 525 Speculate IntegerOperand op1(this, node.child1);526 Speculate IntegerOperand op2(this, node.child2);527 GPRTemporary result(this, op1, op2);528 529 op1.gpr();530 op2.gpr();531 terminateSpeculativeExecution();532 533 integerResult(result.gpr(), m_compileIndex);685 SpeculateDoubleOperand op1(this, node.child1); 686 SpeculateDoubleOperand op2(this, node.child2); 687 FPRTemporary result(this, op1); 688 689 FPRReg reg1 = op1.fpr(); 690 FPRReg reg2 = op2.fpr(); 691 m_jit.divDouble(reg1, reg2, result.fpr()); 692 693 doubleResult(result.fpr(), m_compileIndex); 534 694 break; 535 695 } … … 538 698 SpeculateIntegerOperand op1(this, node.child1); 539 699 SpeculateIntegerOperand op2(this, node.child2); 540 GPRTemporary result(this, op1, op2); 541 542 op1.gpr(); 543 op2.gpr(); 544 terminateSpeculativeExecution(); 545 546 integerResult(result.gpr(), m_compileIndex); 700 GPRTemporary eax(this, X86Registers::eax); 701 GPRTemporary edx(this, X86Registers::edx); 702 GPRReg op1Gpr = op1.gpr(); 703 GPRReg op2Gpr = op2.gpr(); 704 705 speculationCheck(m_jit.branchTestPtr(JITCompiler::Zero, op2Gpr)); 706 707 GPRReg temp2 = InvalidGPRReg; 708 if (op2Gpr == X86Registers::eax || op2Gpr == X86Registers::edx) { 709 temp2 = allocate(); 710 m_jit.move(op2Gpr, temp2); 711 op2Gpr = temp2; 712 } 713 714 m_jit.move(op1Gpr, eax.gpr()); 715 m_jit.assembler().cdq(); 716 m_jit.assembler().idivl_r(op2Gpr); 717 718 if (temp2 != InvalidGPRReg) 719 unlock(temp2); 720 721 integerResult(edx.gpr(), m_compileIndex); 547 722 break; 548 723 } -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r89957 r89961 130 130 GPRReg fillSpeculateInt(NodeIndex, DataFormat& returnFormat); 131 131 GPRReg fillSpeculateIntStrict(NodeIndex); 132 FPRReg fillSpeculateDouble(NodeIndex); 132 133 GPRReg fillSpeculateCell(NodeIndex); 133 134 … … 318 319 }; 319 320 321 class SpeculateDoubleOperand { 322 public: 323 explicit SpeculateDoubleOperand(SpeculativeJIT* jit, NodeIndex index) 324 : m_jit(jit) 325 , m_index(index) 326 , m_fprOrInvalid(InvalidFPRReg) 327 { 328 ASSERT(m_jit); 329 if (jit->isFilled(index)) 330 fpr(); 331 } 332 333 ~SpeculateDoubleOperand() 334 { 335 ASSERT(m_fprOrInvalid != InvalidFPRReg); 336 m_jit->unlock(m_fprOrInvalid); 337 } 338 339 NodeIndex index() const 340 { 341 return m_index; 342 } 343 344 FPRReg fpr() 345 { 346 if (m_fprOrInvalid == InvalidFPRReg) 347 m_fprOrInvalid = m_jit->fillSpeculateDouble(index()); 348 return m_fprOrInvalid; 349 } 350 351 private: 352 SpeculativeJIT* m_jit; 353 NodeIndex m_index; 354 FPRReg m_fprOrInvalid; 355 }; 356 320 357 class SpeculateCellOperand { 321 358 public:
Note: See TracChangeset
for help on using the changeset viewer.