Changeset 95399 in webkit
- Timestamp:
- Sep 18, 2011, 3:29:41 PM (14 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r95398 r95399 1 2011-09-17 Filip Pizlo <fpizlo@apple.com> 2 3 DFG JIT should inline Math.min, Math.max, and Math.sqrt 4 https://bugs.webkit.org/show_bug.cgi?id=68318 5 6 Reviewed by Gavin Barraclough. 7 8 Adds Math.min, Math.max, and Math.sqrt intrinsics. Adds support for 9 a function to have an intrinsic but not a thunk generator. This is 10 a 7% speed-up on access-nbody, and neutral elsewhere, mainly because 11 we're still not DFG compiling the bulk of the hot code in Kraken audio 12 benchmarks. 13 14 * create_hash_table: 15 * dfg/DFGByteCodeParser.cpp: 16 (JSC::DFG::ByteCodeParser::handleMinMax): 17 (JSC::DFG::ByteCodeParser::handleIntrinsic): 18 * dfg/DFGIntrinsic.h: 19 * dfg/DFGNode.h: 20 * dfg/DFGPropagator.cpp: 21 (JSC::DFG::Propagator::propagateNode): 22 (JSC::DFG::Propagator::fixupNode): 23 * dfg/DFGSpeculativeJIT.cpp: 24 (JSC::DFG::SpeculativeJIT::compile): 25 * jit/JITStubs.cpp: 26 (JSC::JITThunks::hostFunctionStub): 27 * runtime/Lookup.cpp: 28 (JSC::setUpStaticFunctionSlot): 29 1 30 2011-09-18 Nico Weber <thakis@chromium.org> 2 31 -
trunk/Source/JavaScriptCore/create_hash_table
r95310 r95399 289 289 } 290 290 if ($name eq "mathTable") { 291 if ($key eq "min") { 292 $intrinsic = "DFG::MinIntrinsic"; 293 } 294 if ($key eq "max") { 295 $intrinsic = "DFG::MaxIntrinsic"; 296 } 291 297 if ($key eq "sqrt") { 292 298 $thunkGenerator = "sqrtThunkGenerator"; 299 $intrinsic = "DFG::SqrtIntrinsic"; 293 300 } 294 301 if ($key eq "pow") { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r95389 r95399 65 65 66 66 private: 67 // Helper for min and max. 68 bool handleMinMax(bool usesResult, int resultOperand, NodeType op, int firstArg, int lastArg); 69 67 70 // Handle intrinsic functions. 68 71 bool handleIntrinsic(bool usesResult, int resultOperand, Intrinsic, int firstArg, int lastArg); … … 601 604 return !m_parseFailed 602 605 606 bool ByteCodeParser::handleMinMax(bool usesResult, int resultOperand, NodeType op, int firstArg, int lastArg) 607 { 608 if (!usesResult) 609 return true; 610 611 if (lastArg == firstArg) { 612 set(resultOperand, constantNaN()); 613 return true; 614 } 615 616 if (lastArg == firstArg + 1) { 617 set(resultOperand, getToNumber(firstArg + 1)); 618 return true; 619 } 620 621 if (lastArg == firstArg + 2) { 622 set(resultOperand, addToGraph(op, getToNumber(firstArg + 1), getToNumber(firstArg + 2))); 623 return true; 624 } 625 626 // Don't handle >=3 arguments for now. 627 return false; 628 } 629 603 630 bool ByteCodeParser::handleIntrinsic(bool usesResult, int resultOperand, Intrinsic intrinsic, int firstArg, int lastArg) 604 631 { … … 618 645 else 619 646 set(resultOperand, addToGraph(ArithAbs, getToNumber(absArg))); 647 return true; 648 } 649 650 case MinIntrinsic: 651 return handleMinMax(usesResult, resultOperand, ArithMin, firstArg, lastArg); 652 653 case MaxIntrinsic: 654 return handleMinMax(usesResult, resultOperand, ArithMax, firstArg, lastArg); 655 656 case SqrtIntrinsic: { 657 if (!usesResult) 658 return true; 659 660 if (firstArg == lastArg) { 661 set(resultOperand, constantNaN()); 662 return true; 663 } 664 665 set(resultOperand, addToGraph(ArithSqrt, getToNumber(firstArg + 1))); 620 666 return true; 621 667 } -
trunk/Source/JavaScriptCore/dfg/DFGIntrinsic.h
r95310 r95399 31 31 enum Intrinsic { 32 32 NoIntrinsic, 33 AbsIntrinsic 33 AbsIntrinsic, 34 MinIntrinsic, 35 MaxIntrinsic, 36 SqrtIntrinsic 34 37 }; 35 38 -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r95389 r95399 156 156 macro(ArithMod, NodeResultNumber) \ 157 157 macro(ArithAbs, NodeResultNumber) \ 158 macro(ArithMin, NodeResultNumber) \ 159 macro(ArithMax, NodeResultNumber) \ 160 macro(ArithSqrt, NodeResultNumber) \ 158 161 /* Arithmetic operators call ToNumber on their operands. */\ 159 162 macro(ValueToNumber, NodeResultNumber | NodeMustGenerate) \ -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r95389 r95399 226 226 case ArithAdd: 227 227 case ArithSub: 228 case ArithMul: { 228 case ArithMul: 229 case ArithMin: 230 case ArithMax: { 229 231 PredictedType left = m_predictions[node.child1()]; 230 232 PredictedType right = m_predictions[node.child2()]; … … 239 241 } 240 242 241 case ArithDiv: { 243 case ArithDiv: 244 case ArithSqrt: { 242 245 changed |= setPrediction(makePrediction(PredictDouble, StrongPrediction)); 243 246 break; … … 406 409 case ArithAdd: 407 410 case ArithSub: 408 case ArithMul: { 411 case ArithMul: 412 case ArithMin: 413 case ArithMax: { 409 414 PredictedType left = m_predictions[node.child1()]; 410 415 PredictedType right = m_predictions[node.child2()]; … … 422 427 toDouble(node.child1()); 423 428 toDouble(node.child2()); 429 break; 430 } 431 432 case ArithAbs: { 433 PredictedType prediction = m_predictions[node.child1()]; 434 if (isStrongPrediction(prediction) && (prediction & PredictDouble)) 435 toDouble(node.child1()); 436 break; 437 } 438 439 case ArithSqrt: { 440 toDouble(node.child1()); 424 441 break; 425 442 } … … 731 748 case ArithDiv: 732 749 case ArithAbs: 750 case ArithMin: 751 case ArithMax: 752 case ArithSqrt: 733 753 setReplacement(pureCSE(node)); 734 754 break; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r95389 r95399 1084 1084 break; 1085 1085 } 1086 1087 case ArithMin: 1088 case ArithMax: { 1089 if (shouldSpeculateInteger(node.child1(), node.child2())) { 1090 SpeculateIntegerOperand op1(this, node.child1()); 1091 SpeculateIntegerOperand op2(this, node.child2()); 1092 GPRTemporary result(this, op1); 1093 1094 MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr()); 1095 m_jit.move(op2.gpr(), result.gpr()); 1096 if (op1.gpr() != result.gpr()) { 1097 MacroAssembler::Jump done = m_jit.jump(); 1098 op1Less.link(&m_jit); 1099 m_jit.move(op1.gpr(), result.gpr()); 1100 done.link(&m_jit); 1101 } else 1102 op1Less.link(&m_jit); 1103 1104 integerResult(result.gpr(), m_compileIndex); 1105 break; 1106 } 1107 1108 SpeculateDoubleOperand op1(this, node.child1()); 1109 SpeculateDoubleOperand op2(this, node.child2()); 1110 FPRTemporary result(this, op1); 1111 1112 MacroAssembler::JumpList done; 1113 1114 MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr()); 1115 1116 // op2 is eather the lesser one or one of then is NaN 1117 MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThan : MacroAssembler::DoubleLessThan, op1.fpr(), op2.fpr()); 1118 1119 // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 1120 // op1 + op2 and putting it into result. 1121 m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr()); 1122 done.append(m_jit.jump()); 1123 1124 op2Less.link(&m_jit); 1125 m_jit.moveDouble(op2.fpr(), result.fpr()); 1126 1127 if (op1.fpr() != result.fpr()) { 1128 done.append(m_jit.jump()); 1129 1130 op1Less.link(&m_jit); 1131 m_jit.moveDouble(op1.fpr(), result.fpr()); 1132 } else 1133 op1Less.link(&m_jit); 1134 1135 done.link(&m_jit); 1136 1137 doubleResult(result.fpr(), m_compileIndex); 1138 break; 1139 } 1140 1141 case ArithSqrt: { 1142 SpeculateDoubleOperand op1(this, node.child1()); 1143 FPRTemporary result(this, op1); 1144 1145 m_jit.sqrtDouble(op1.fpr(), result.fpr()); 1146 1147 doubleResult(result.fpr(), m_compileIndex); 1148 break; 1149 } 1086 1150 1087 1151 case LogicalNot: { -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r95388 r95399 3784 3784 std::pair<HostFunctionStubMap::iterator, bool> entry = m_hostFunctionStubMap->add(function, Weak<NativeExecutable>()); 3785 3785 if (!*entry.first->second) { 3786 MacroAssemblerCodeRef code = globalData->canUseJIT() ? generator(globalData) : MacroAssemblerCodeRef(); 3786 MacroAssemblerCodeRef code; 3787 if (generator) { 3788 if (globalData->canUseJIT()) 3789 code = generator(globalData); 3790 else 3791 code = MacroAssemblerCodeRef(); 3792 } else 3793 code = JIT::compileCTINativeCall(globalData, function); 3787 3794 entry.first->second.set(*globalData, NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic)); 3788 3795 } -
trunk/Source/JavaScriptCore/runtime/Lookup.cpp
r95318 r95399 82 82 JSGlobalObject* globalObject = thisObj->globalObject(); 83 83 #if ENABLE(JIT) 84 if (entry->generator() )84 if (entry->generator() || entry->intrinsic() != DFG::NoIntrinsic) 85 85 function = JSFunction::create(exec, globalObject, globalObject->functionStructure(), entry->functionLength(), propertyName, exec->globalData().getHostFunction(entry->function(), entry->generator(), entry->intrinsic())); 86 86 else
Note:
See TracChangeset
for help on using the changeset viewer.