Diff
Modified: trunk/LayoutTests/ChangeLog (158383 => 158384)
--- trunk/LayoutTests/ChangeLog 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/LayoutTests/ChangeLog 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1,3 +1,19 @@
+2013-10-31 Filip Pizlo <[email protected]>
+
+ Remove CachedTranscendentalFunction because caching math functions is an ugly idea
+ https://bugs.webkit.org/show_bug.cgi?id=123574
+
+ Reviewed by Mark Hahnenberg.
+
+ * js/dfg-cos-constant-expected.txt: Added.
+ * js/dfg-cos-constant.html: Added.
+ * js/dfg-sin-constant-expected.txt: Added.
+ * js/dfg-sin-constant.html: Added.
+ * js/script-tests/dfg-cos-constant.js: Added.
+ (foo):
+ * js/script-tests/dfg-sin-constant.js: Added.
+ (foo):
+
2013-10-30 Gavin Barraclough <[email protected]>
WebPageCreationParameters should be consistent in Window.open
Added: trunk/LayoutTests/js/dfg-cos-constant-expected.txt (0 => 158384)
--- trunk/LayoutTests/js/dfg-cos-constant-expected.txt (rev 0)
+++ trunk/LayoutTests/js/dfg-cos-constant-expected.txt 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,10 @@
+Tests that Math.cos() on a constant works in the DFG.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo() is 1 on all iterations including after DFG tier-up.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/dfg-cos-constant.html (0 => 158384)
--- trunk/LayoutTests/js/dfg-cos-constant.html (rev 0)
+++ trunk/LayoutTests/js/dfg-cos-constant.html 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/dfg-sin-constant-expected.txt (0 => 158384)
--- trunk/LayoutTests/js/dfg-sin-constant-expected.txt (rev 0)
+++ trunk/LayoutTests/js/dfg-sin-constant-expected.txt 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,10 @@
+Tests that Math.sin() on a constant works in the DFG.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo() is 0 on all iterations including after DFG tier-up.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/dfg-sin-constant.html (0 => 158384)
--- trunk/LayoutTests/js/dfg-sin-constant.html (rev 0)
+++ trunk/LayoutTests/js/dfg-sin-constant.html 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/script-tests/dfg-cos-constant.js (0 => 158384)
--- trunk/LayoutTests/js/script-tests/dfg-cos-constant.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/dfg-cos-constant.js 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,7 @@
+description(
+"Tests that Math.cos() on a constant works in the DFG."
+);
+
+function foo() { return Math.cos(0); }
+
+dfgShouldBe(foo, "foo()", "1");
Added: trunk/LayoutTests/js/script-tests/dfg-sin-constant.js (0 => 158384)
--- trunk/LayoutTests/js/script-tests/dfg-sin-constant.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/dfg-sin-constant.js 2013-10-31 19:19:15 UTC (rev 158384)
@@ -0,0 +1,7 @@
+description(
+"Tests that Math.sin() on a constant works in the DFG."
+);
+
+function foo() { return Math.sin(0); }
+
+dfgShouldBe(foo, "foo()", "0");
Modified: trunk/Source/_javascript_Core/ChangeLog (158383 => 158384)
--- trunk/Source/_javascript_Core/ChangeLog 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1,3 +1,54 @@
+2013-10-31 Filip Pizlo <[email protected]>
+
+ Remove CachedTranscendentalFunction because caching math functions is an ugly idea
+ https://bugs.webkit.org/show_bug.cgi?id=123574
+
+ Reviewed by Mark Hahnenberg.
+
+ This is performance-neutral because I also make Math.cos/sin intrinsic. This means that
+ we gain the "overhead" of actually computing sin and cos but we lose the overhead of
+ going through the native call thunks.
+
+ Caching transcendental functions is a really ugly idea. It works for SunSpider because
+ that benchmark makes very predictable calls into Math.sin. But I don't believe that this
+ is representative of any kind of reality, and so for sensible uses of Math.sin/cos all
+ that this was doing was adding more call overhead and some hashing overhead.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGBackwardsPropagationPhase.cpp:
+ (JSC::DFG::BackwardsPropagationPhase::propagate):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsic):
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::performNodeCSE):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ (JSC::DFG::PredictionPropagationPhase::propagate):
+ (JSC::DFG::PredictionPropagationPhase::doDoubleVoting):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * jit/JITOperations.h:
+ * runtime/CachedTranscendentalFunction.h: Removed.
+ * runtime/DateInstanceCache.h:
+ * runtime/Intrinsic.h:
+ * runtime/MathObject.cpp:
+ (JSC::MathObject::finishCreation):
+ (JSC::mathProtoFuncCos):
+ (JSC::mathProtoFuncSin):
+ * runtime/VM.h:
+
2013-10-30 Filip Pizlo <[email protected]>
Assertion failure in js/dom/global-constructors-attributes-dedicated-worker.html
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (158383 => 158384)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-10-31 19:19:15 UTC (rev 158384)
@@ -779,7 +779,6 @@
86880F1F14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */; };
86880F4D14353B2100B08D42 /* DFGSpeculativeJIT64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */; };
868916B0155F286300CB2B9A /* PrivateName.h in Headers */ = {isa = PBXBuildFile; fileRef = 868916A9155F285400CB2B9A /* PrivateName.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -2039,7 +2038,6 @@
86880F1B14328BB900B08D42 /* DFGSpeculativeJIT32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT32_64.cpp; path = dfg/DFGSpeculativeJIT32_64.cpp; sourceTree = "<group>"; };
86880F4C14353B2100B08D42 /* DFGSpeculativeJIT64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGSpeculativeJIT64.cpp; path = dfg/DFGSpeculativeJIT64.cpp; sourceTree = "<group>"; };
868916A9155F285400CB2B9A /* PrivateName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrivateName.h; sourceTree = "<group>"; };
- 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedTranscendentalFunction.h; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
86A054461556451B00445157 /* LowLevelInterpreter.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter.asm; path = llint/LowLevelInterpreter.asm; sourceTree = "<group>"; };
86A054471556451B00445157 /* LowLevelInterpreter32_64.asm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm.asm; name = LowLevelInterpreter32_64.asm; path = llint/LowLevelInterpreter32_64.asm; sourceTree = "<group>"; };
@@ -3302,7 +3300,6 @@
BC7952350E15EB5600A898AB /* BooleanPrototype.h */,
0FB7F38B15ED8E3800F167B2 /* Butterfly.h */,
0FB7F38C15ED8E3800F167B2 /* ButterflyInlines.h */,
- 869D04AE1193B54D00803475 /* CachedTranscendentalFunction.h */,
BCA62DFE0E2826230004F30D /* CallData.cpp */,
145C507F0D9DF63B0088F6B9 /* CallData.h */,
BC6AAAE40E1F426500AD87D8 /* ClassInfo.h */,
@@ -4133,7 +4130,6 @@
0F21C27F14BEAA8200ADC64B /* BytecodeConventions.h in Headers */,
969A07230ED1CE3300F1F681 /* BytecodeGenerator.h in Headers */,
0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
- 869D04AF1193B54D00803475 /* CachedTranscendentalFunction.h in Headers */,
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
A7C1EAEF17987AB600299DB2 /* CallFrameInlines.h in Headers */,
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -547,12 +547,32 @@
case ArithSqrt: {
JSValue child = forNode(node->child1()).value();
if (child && child.isNumber()) {
- setConstant(node, JSValue(sqrt(child.asNumber())));
+ setConstant(node, jsNumber(sqrt(child.asNumber())));
break;
}
forNode(node).setType(SpecDouble);
break;
}
+
+ case ArithSin: {
+ JSValue child = forNode(node->child1()).value();
+ if (child && child.isNumber()) {
+ setConstant(node, jsNumber(sin(child.asNumber())));
+ break;
+ }
+ forNode(node).setType(SpecDouble);
+ break;
+ }
+
+ case ArithCos: {
+ JSValue child = forNode(node->child1()).value();
+ if (child && child.isNumber()) {
+ setConstant(node, jsNumber(cos(child.asNumber())));
+ break;
+ }
+ forNode(node).setType(SpecDouble);
+ break;
+ }
case LogicalNot: {
switch (booleanResult(node, forNode(node->child1()))) {
Modified: trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGBackwardsPropagationPhase.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -383,6 +383,12 @@
break;
}
+ // Note: ArithSqrt, ArithSin, and ArithCos and other math intrinsics don't have special
+ // rules in here because they are always followed by Phantoms to signify that if the
+ // method call speculation fails, the bytecode may use the arguments in arbitrary ways.
+ // This corresponds to that possibility of someone doing something like:
+ // Math.sin = function(x) { doArbitraryThingsTo(x); }
+
default:
mergeDefaultFlags(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1454,8 +1454,6 @@
return false;
}
-// FIXME: We dead-code-eliminate unused Math intrinsics, but that's invalid because
-// they need to perform the ToNumber conversion, which can have side-effects.
bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction)
{
switch (intrinsic) {
@@ -1481,17 +1479,34 @@
case MaxIntrinsic:
return handleMinMax(resultOperand, ArithMax, registerOffset, argumentCountIncludingThis);
- case SqrtIntrinsic: {
- if (argumentCountIncludingThis == 1) { // Math.sqrt()
+ case SqrtIntrinsic:
+ case CosIntrinsic:
+ case SinIntrinsic: {
+ if (argumentCountIncludingThis == 1) {
set(VirtualRegister(resultOperand), constantNaN());
return true;
}
- if (!MacroAssembler::supportsFloatingPointSqrt())
+ switch (intrinsic) {
+ case SqrtIntrinsic:
+ if (!MacroAssembler::supportsFloatingPointSqrt())
+ return false;
+
+ set(VirtualRegister(resultOperand), addToGraph(ArithSqrt, get(virtualRegisterForArgument(1, registerOffset))));
+ return true;
+
+ case CosIntrinsic:
+ set(VirtualRegister(resultOperand), addToGraph(ArithCos, get(virtualRegisterForArgument(1, registerOffset))));
+ return true;
+
+ case SinIntrinsic:
+ set(VirtualRegister(resultOperand), addToGraph(ArithSin, get(virtualRegisterForArgument(1, registerOffset))));
+ return true;
+
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
return false;
-
- set(VirtualRegister(resultOperand), addToGraph(ArithSqrt, get(virtualRegisterForArgument(1, registerOffset))));
- return true;
+ }
}
case ArrayPushIntrinsic: {
Modified: trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1059,6 +1059,8 @@
case ArithMin:
case ArithMax:
case ArithSqrt:
+ case ArithSin:
+ case ArithCos:
case StringCharAt:
case StringCharCodeAt:
case IsUndefined:
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -97,6 +97,8 @@
case ArithMin:
case ArithMax:
case ArithSqrt:
+ case ArithSin:
+ case ArithCos:
case GetScope:
case SkipScope:
case CheckFunction:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -278,7 +278,9 @@
break;
}
- case ArithSqrt: {
+ case ArithSqrt:
+ case ArithSin:
+ case ArithCos: {
fixEdge<NumberUse>(node->child1());
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -129,6 +129,8 @@
macro(ArithMin, NodeResultNumber | NodeMustGenerate) \
macro(ArithMax, NodeResultNumber | NodeMustGenerate) \
macro(ArithSqrt, NodeResultNumber | NodeMustGenerate) \
+ macro(ArithSin, NodeResultNumber | NodeMustGenerate) \
+ macro(ArithCos, NodeResultNumber | NodeMustGenerate) \
\
/* Add of values may either be arithmetic, or result in string concatenation. */\
macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -329,7 +329,9 @@
break;
}
- case ArithSqrt: {
+ case ArithSqrt:
+ case ArithSin:
+ case ArithCos: {
changed |= setPrediction(SpecDouble);
break;
}
@@ -714,6 +716,8 @@
break;
case ArithSqrt:
+ case ArithCos:
+ case ArithSin:
m_graph.voteNode(node->child1(), VoteDouble);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -150,6 +150,8 @@
case ArithMin:
case ArithMax:
case ArithSqrt:
+ case ArithSin:
+ case ArithCos:
case ValueAdd:
case GetById:
case GetByIdFlush:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1133,6 +1133,11 @@
m_jit.setupArguments(arg1, arg2);
return appendCallSetResult(operation, result);
}
+ JITCompiler::Call callOperation(D_JITOperation_D operation, FPRReg result, FPRReg arg1)
+ {
+ m_jit.setupArguments(arg1);
+ return appendCallSetResult(operation, result);
+ }
JITCompiler::Call callOperation(D_JITOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
{
m_jit.setupArguments(arg1, arg2);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -2260,6 +2260,30 @@
break;
}
+ case ArithSin: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRReg op1FPR = op1.fpr();
+
+ flushRegisters();
+
+ FPRResult result(this);
+ callOperation(sin, result.fpr(), op1FPR);
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ case ArithCos: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRReg op1FPR = op1.fpr();
+
+ flushRegisters();
+
+ FPRResult result(this);
+ callOperation(cos, result.fpr(), op1FPR);
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
case LogicalNot:
compileLogicalNot(node);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -2580,7 +2580,31 @@
doubleResult(result.fpr(), node);
break;
}
+
+ case ArithSin: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRReg op1FPR = op1.fpr();
+ flushRegisters();
+
+ FPRResult result(this);
+ callOperation(sin, result.fpr(), op1FPR);
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
+ case ArithCos: {
+ SpeculateDoubleOperand op1(this, node->child1());
+ FPRReg op1FPR = op1.fpr();
+
+ flushRegisters();
+
+ FPRResult result(this);
+ callOperation(cos, result.fpr(), op1FPR);
+ doubleResult(result.fpr(), node);
+ break;
+ }
+
case LogicalNot:
compileLogicalNot(node);
break;
Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (158383 => 158384)
--- trunk/Source/_javascript_Core/jit/JITOperations.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -120,6 +120,7 @@
typedef JSCell* JIT_OPERATION (*C_JITOperation_EOZ)(ExecState*, JSObject*, int32_t);
typedef JSCell* JIT_OPERATION (*C_JITOperation_ESt)(ExecState*, Structure*);
typedef JSCell* JIT_OPERATION (*C_JITOperation_EZ)(ExecState*, int32_t);
+typedef double JIT_OPERATION (*D_JITOperation_D)(double);
typedef double JIT_OPERATION (*D_JITOperation_DD)(double, double);
typedef double JIT_OPERATION (*D_JITOperation_ZZ)(int32_t, int32_t);
typedef double JIT_OPERATION (*D_JITOperation_EJ)(ExecState*, EncodedJSValue);
Deleted: trunk/Source/_javascript_Core/runtime/CachedTranscendentalFunction.h (158383 => 158384)
--- trunk/Source/_javascript_Core/runtime/CachedTranscendentalFunction.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/runtime/CachedTranscendentalFunction.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CachedTranscendentalFunction_h
-#define CachedTranscendentalFunction_h
-
-#include "JSCJSValue.h"
-
-namespace JSC {
-
-typedef double (*TranscendentalFunctionPtr)(double);
-
-// CachedTranscendentalFunction provides a generic mechanism to cache results
-// for pure functions with the signature "double func(double)", and where NaN
-// maps to NaN.
-template<TranscendentalFunctionPtr orignalFunction>
-class CachedTranscendentalFunction {
- struct CacheEntry {
- double operand;
- double result;
- };
-
-public:
- CachedTranscendentalFunction()
- : m_cache(0)
- {
- }
-
- ~CachedTranscendentalFunction()
- {
- if (m_cache)
- fastFree(m_cache);
- }
-
- JSValue operator() (double operand)
- {
- if (UNLIKELY(!m_cache))
- initialize();
- CacheEntry* entry = &m_cache[hash(operand)];
-
- if (entry->operand == operand)
- return jsDoubleNumber(entry->result);
- double result = orignalFunction(operand);
- entry->operand = operand;
- entry->result = result;
- return jsDoubleNumber(result);
- }
-
-private:
- void initialize()
- {
- // Lazily allocate the table, populate with NaN->NaN mapping.
- m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry)));
- for (unsigned x = 0; x < s_cacheSize; ++x) {
- m_cache[x].operand = QNaN;
- m_cache[x].result = QNaN;
- }
- }
-
- static unsigned hash(double d)
- {
- union doubleAndUInt64 {
- double d;
- uint32_t is[2];
- } u;
- u.d = d;
-
- unsigned x = u.is[0] ^ u.is[1];
- x = (x >> 20) ^ (x >> 8);
- return x & (s_cacheSize - 1);
- }
-
- static const unsigned s_cacheSize = 0x1000;
- CacheEntry* m_cache;
-};
-
-}
-
-#endif // CachedTranscendentalFunction_h
Modified: trunk/Source/_javascript_Core/runtime/DateInstanceCache.h (158383 => 158384)
--- trunk/Source/_javascript_Core/runtime/DateInstanceCache.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/runtime/DateInstanceCache.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -26,6 +26,7 @@
#ifndef DateInstanceCache_h
#define DateInstanceCache_h
+#include "JSCJSValue.h"
#include "JSDateMath.h"
#include <wtf/FixedArray.h>
#include <wtf/HashFunctions.h>
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (158383 => 158384)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -34,6 +34,8 @@
MinIntrinsic,
MaxIntrinsic,
SqrtIntrinsic,
+ SinIntrinsic,
+ CosIntrinsic,
ArrayPushIntrinsic,
ArrayPopIntrinsic,
CharCodeAtIntrinsic,
Modified: trunk/Source/_javascript_Core/runtime/MathObject.cpp (158383 => 158384)
--- trunk/Source/_javascript_Core/runtime/MathObject.cpp 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/runtime/MathObject.cpp 2013-10-31 19:19:15 UTC (rev 158384)
@@ -85,7 +85,7 @@
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "atan"), 1, mathProtoFuncATan, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "atan2"), 2, mathProtoFuncATan2, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "ceil"), 1, mathProtoFuncCeil, CeilIntrinsic, DontEnum | Function);
- putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "cos"), 1, mathProtoFuncCos, NoIntrinsic, DontEnum | Function);
+ putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "cos"), 1, mathProtoFuncCos, CosIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "exp"), 1, mathProtoFuncExp, ExpIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "floor"), 1, mathProtoFuncFloor, FloorIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "log"), 1, mathProtoFuncLog, LogIntrinsic, DontEnum | Function);
@@ -94,7 +94,7 @@
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "pow"), 2, mathProtoFuncPow, PowIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "random"), 0, mathProtoFuncRandom, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "round"), 1, mathProtoFuncRound, RoundIntrinsic, DontEnum | Function);
- putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sin"), 1, mathProtoFuncSin, NoIntrinsic, DontEnum | Function);
+ putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sin"), 1, mathProtoFuncSin, SinIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "sqrt"), 1, mathProtoFuncSqrt, SqrtIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "tan"), 1, mathProtoFuncTan, NoIntrinsic, DontEnum | Function);
putDirectNativeFunctionWithoutTransition(vm, globalObject, Identifier(&vm, "imul"), 1, mathProtoFuncIMul, IMulIntrinsic, DontEnum | Function);
@@ -136,7 +136,7 @@
EncodedJSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec)
{
- return JSValue::encode(exec->vm().cachedCos(exec->argument(0).toNumber(exec)));
+ return JSValue::encode(jsDoubleNumber(cos(exec->argument(0).toNumber(exec))));
}
EncodedJSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec)
@@ -251,7 +251,7 @@
EncodedJSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec)
{
- return JSValue::encode(exec->vm().cachedSin(exec->argument(0).toNumber(exec)));
+ return JSValue::encode(jsDoubleNumber(sin(exec->argument(0).toNumber(exec))));
}
EncodedJSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (158383 => 158384)
--- trunk/Source/_javascript_Core/runtime/VM.h 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2013-10-31 19:19:15 UTC (rev 158384)
@@ -29,7 +29,6 @@
#ifndef VM_h
#define VM_h
-#include "CachedTranscendentalFunction.h"
#include "DateInstanceCache.h"
#include "ExecutableAllocator.h"
#include "Heap.h"
@@ -419,9 +418,6 @@
ThreadIdentifier exclusiveThread;
- CachedTranscendentalFunction<std::sin> cachedSin;
- CachedTranscendentalFunction<std::cos> cachedCos;
-
JS_EXPORT_PRIVATE void resetDateCache();
JS_EXPORT_PRIVATE void startSampling();
Modified: trunk/Tools/ChangeLog (158383 => 158384)
--- trunk/Tools/ChangeLog 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Tools/ChangeLog 2013-10-31 19:19:15 UTC (rev 158384)
@@ -1,3 +1,14 @@
+2013-10-31 Filip Pizlo <[email protected]>
+
+ Remove CachedTranscendentalFunction because caching math functions is an ugly idea
+ https://bugs.webkit.org/show_bug.cgi?id=123574
+
+ Reviewed by Mark Hahnenberg.
+
+ Make it easier to see that a test doesn't have an -expected file.
+
+ * Scripts/run-jsc-stress-tests:
+
2013-10-31 Tamas Gergely <[email protected]>
Run tests as if they are expected to pass when --force is given.
Modified: trunk/Tools/Scripts/run-jsc-stress-tests (158383 => 158384)
--- trunk/Tools/Scripts/run-jsc-stress-tests 2013-10-31 19:17:45 UTC (rev 158383)
+++ trunk/Tools/Scripts/run-jsc-stress-tests 2013-10-31 19:19:15 UTC (rev 158384)
@@ -186,7 +186,8 @@
outp.puts "then"
outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + prefixCommand(plan.name)
outp.puts " " + plan.failCommand
- outp.puts "else"
+ outp.puts "elif test -e #{Shellwords.shellescape(expectedFilename)}"
+ outp.puts "then"
outp.puts " diff -u #{Shellwords.shellescape(expectedFilename)} #{outputFilename} > #{diffFilename}"
outp.puts " if [ $? -eq 0 ]"
outp.puts " then"
@@ -195,6 +196,9 @@
outp.puts " (echo \"DIFF FAILURE!\" && cat #{diffFilename}) | " + prefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts " fi"
+ outp.puts "else"
+ outp.puts " (echo \"NO EXPECTATION!\" && cat #{outputFilename}) | " + prefixCommand(plan.name)
+ outp.puts " " + plan.failCommand
outp.puts "fi"
}
end