Commit b3336c7b authored by fpizlo@apple.com's avatar fpizlo@apple.com

Remove CachedTranscendentalFunction because caching math functions is an ugly idea

https://bugs.webkit.org/show_bug.cgi?id=123574

Source/JavaScriptCore: 

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.

* JavaScriptCore.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:

Tools: 

Reviewed by Mark Hahnenberg.

Make it easier to see that a test doesn't have an -expected file.

* Scripts/run-jsc-stress-tests:

LayoutTests: 

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):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@158384 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 53abe1aa
2013-10-31 Filip Pizlo <fpizlo@apple.com>
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 <barraclough@apple.com>
WebPageCreationParameters should be consistent in Window.open
......
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
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
</head>
<body>
<script src="script-tests/dfg-cos-constant.js"></script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
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
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
</head>
<body>
<script src="script-tests/dfg-sin-constant.js"></script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>
description(
"Tests that Math.cos() on a constant works in the DFG."
);
function foo() { return Math.cos(0); }
dfgShouldBe(foo, "foo()", "1");
description(
"Tests that Math.sin() on a constant works in the DFG."
);
function foo() { return Math.sin(0); }
dfgShouldBe(foo, "foo()", "0");
2013-10-31 Filip Pizlo <fpizlo@apple.com>
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.
* JavaScriptCore.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 <fpizlo@apple.com>
Assertion failure in js/dom/global-constructors-attributes-dedicated-worker.html
......
......@@ -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 */,
......
......@@ -547,7 +547,27 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
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);
......
......@@ -383,6 +383,12 @@ private:
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;
......
......@@ -1454,8 +1454,6 @@ bool ByteCodeParser::handleMinMax(int resultOperand, NodeType op, int registerOf
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 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
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: {
......
......@@ -1059,6 +1059,8 @@ private:
case ArithMin:
case ArithMax:
case ArithSqrt:
case ArithSin:
case ArithCos:
case StringCharAt:
case StringCharCodeAt:
case IsUndefined:
......
......@@ -97,6 +97,8 @@ void clobberize(Graph& graph, Node* node, ReadFunctor& read, WriteFunctor& write
case ArithMin:
case ArithMax:
case ArithSqrt:
case ArithSin:
case ArithCos:
case GetScope:
case SkipScope:
case CheckFunction:
......
......@@ -278,7 +278,9 @@ private:
break;
}
case ArithSqrt: {
case ArithSqrt:
case ArithSin:
case ArithCos: {
fixEdge<NumberUse>(node->child1());
break;
}
......
......@@ -129,6 +129,8 @@ namespace JSC { namespace DFG {
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) \
......
......@@ -329,7 +329,9 @@ private:
break;
}
case ArithSqrt: {
case ArithSqrt:
case ArithSin:
case ArithCos: {
changed |= setPrediction(SpecDouble);
break;
}
......@@ -714,6 +716,8 @@ private:
break;
case ArithSqrt:
case ArithCos:
case ArithSin:
m_graph.voteNode(node->child1(), VoteDouble);
break;
......
......@@ -150,6 +150,8 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
case ArithMin:
case ArithMax:
case ArithSqrt:
case ArithSin:
case ArithCos:
case ValueAdd:
case GetById:
case GetByIdFlush:
......
......@@ -1133,6 +1133,11 @@ public:
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);
......
......@@ -2260,6 +2260,30 @@ void SpeculativeJIT::compile(Node* 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;
......
......@@ -2580,6 +2580,30 @@ void SpeculativeJIT::compile(Node* node)
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);
......
......@@ -120,6 +120,7 @@ typedef JSCell* JIT_OPERATION (*C_JITOperation_EO)(ExecState*, JSObject*);
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);
......
/*
* 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
......@@ -26,6 +26,7 @@
#ifndef DateInstanceCache_h
#define DateInstanceCache_h
#include "JSCJSValue.h"
#include "JSDateMath.h"
#include <wtf/FixedArray.h>
#include <wtf/HashFunctions.h>
......
......@@ -34,6 +34,8 @@ enum Intrinsic {
MinIntrinsic,
MaxIntrinsic,
SqrtIntrinsic,
SinIntrinsic,
CosIntrinsic,
ArrayPushIntrinsic,
ArrayPopIntrinsic,
CharCodeAtIntrinsic,
......
......@@ -85,7 +85,7 @@ void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
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 @@ void MathObject::finishCreation(VM& vm, JSGlobalObject* globalObject)
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 mathProtoFuncCeil(ExecState* exec)
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 mathProtoFuncRound(ExecState* exec)
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)
......
......@@ -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 @@ namespace JSC {
ThreadIdentifier exclusiveThread;
CachedTranscendentalFunction<std::sin> cachedSin;
CachedTranscendentalFunction<std::cos> cachedCos;
JS_EXPORT_PRIVATE void resetDateCache();
JS_EXPORT_PRIVATE void startSampling();
......
2013-10-31 Filip Pizlo <fpizlo@apple.com>
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 <gertom@inf.u-szeged.hu>
Run tests as if they are expected to pass when --force is given.
......
......@@ -186,7 +186,8 @@ def diffErrorHandler(expectedFilename)
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 @@ def diffErrorHandler(expectedFilename)
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment