Diff
Modified: trunk/JSTests/ChangeLog (239141 => 239142)
--- trunk/JSTests/ChangeLog 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/JSTests/ChangeLog 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1,5 +1,26 @@
2018-12-12 Yusuke Suzuki <yusukesuz...@slowstart.org>
+ [DFG][FTL] Add NewSymbol
+ https://bugs.webkit.org/show_bug.cgi?id=192620
+
+ Reviewed by Saam Barati.
+
+ * microbenchmarks/symbol-creation.js: Added.
+ (test):
+ * stress/symbol-description-identity.js: Added.
+ (shouldBe):
+ (test):
+ * stress/symbol-identity.js: Added.
+ (shouldBe):
+ (test):
+ * stress/symbol-with-description-throw-error.js: Added.
+ (shouldBe):
+ (shouldThrow):
+ (test):
+ (object.toString):
+
+2018-12-12 Yusuke Suzuki <yusukesuz...@slowstart.org>
+
[BigInt] Implement DFG/FTL typeof for BigInt
https://bugs.webkit.org/show_bug.cgi?id=192619
Added: trunk/JSTests/microbenchmarks/symbol-creation.js (0 => 239142)
--- trunk/JSTests/microbenchmarks/symbol-creation.js (rev 0)
+++ trunk/JSTests/microbenchmarks/symbol-creation.js 2018-12-13 02:09:28 UTC (rev 239142)
@@ -0,0 +1,8 @@
+function test()
+{
+ return Symbol();
+}
+noInline(test);
+
+for (var i = 0; i < 4e5; ++i)
+ test();
Added: trunk/JSTests/stress/symbol-description-identity.js (0 => 239142)
--- trunk/JSTests/stress/symbol-description-identity.js (rev 0)
+++ trunk/JSTests/stress/symbol-description-identity.js 2018-12-13 02:09:28 UTC (rev 239142)
@@ -0,0 +1,21 @@
+function shouldBe(actual, expected)
+{
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+noInline(shouldBe);
+
+function test(description)
+{
+ return Symbol(description);
+}
+noInline(test);
+
+var set = new Set;
+for (var i = 0; i < 1e4; ++i) {
+ var description = String(i);
+ var symbol = test(description);
+ set.add(symbol);
+ shouldBe(set.size, i + 1);
+ shouldBe(symbol.description, description);
+}
Added: trunk/JSTests/stress/symbol-identity.js (0 => 239142)
--- trunk/JSTests/stress/symbol-identity.js (rev 0)
+++ trunk/JSTests/stress/symbol-identity.js 2018-12-13 02:09:28 UTC (rev 239142)
@@ -0,0 +1,20 @@
+function shouldBe(actual, expected)
+{
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+noInline(shouldBe);
+
+function test()
+{
+ return Symbol();
+}
+noInline(test);
+
+var set = new Set;
+for (var i = 0; i < 1e4; ++i) {
+ var symbol = test();
+ set.add(symbol);
+ shouldBe(set.size, i + 1);
+ shouldBe(symbol.description, undefined);
+}
Added: trunk/JSTests/stress/symbol-with-description-throw-error.js (0 => 239142)
--- trunk/JSTests/stress/symbol-with-description-throw-error.js (rev 0)
+++ trunk/JSTests/stress/symbol-with-description-throw-error.js 2018-12-13 02:09:28 UTC (rev 239142)
@@ -0,0 +1,52 @@
+function shouldBe(actual, expected)
+{
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+noInline(shouldBe);
+
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+noInline(shouldThrow);
+
+function test(description)
+{
+ return Symbol(description);
+}
+noInline(test);
+
+var count = 0;
+var flag = false;
+var object = {
+ toString()
+ {
+ count++;
+ if (flag) {
+ throw new Error("out");
+ }
+ return "Cocoa";
+ }
+};
+
+for (var i = 0; i < 1e4; ++i) {
+ shouldBe(test(object).description, "Cocoa");
+ shouldBe(count, i + 1);
+}
+flag = true;
+
+shouldThrow(() => {
+ shouldBe(test(object).description, "Cocoa");
+ shouldBe(count, 1e4 + 1);
+}, `Error: out`);
Modified: trunk/Source/_javascript_Core/ChangeLog (239141 => 239142)
--- trunk/Source/_javascript_Core/ChangeLog 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1,5 +1,54 @@
2018-12-12 Yusuke Suzuki <yusukesuz...@slowstart.org>
+ [DFG][FTL] Add NewSymbol
+ https://bugs.webkit.org/show_bug.cgi?id=192620
+
+ Reviewed by Saam Barati.
+
+ This patch introduces NewSymbol DFG node into DFG and FTL tiers. The main goal of this patch is not optimize
+ NewSymbol code faster. Rather than that, this patch intends to offer SpecSymbol type information into DFG's
+ data flow to optimize generated code in FTL backend.
+
+ We add NewSymbol DFG node, which may take an argument. If an argument is not given, NewSymbol is for `Symbol()`.
+ If an argument is given, ToString is emitted to this argument before passing it to NewSymbol. So NewSymbol node
+ itself does not perform any type checks. ToString performs effects, but NewSymbol doesn't have any side observable
+ effects. So we can decouple Symbol(description) call into NewSymbol(ToString(description)).
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleConstantInternalFunction):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGClobbersExitState.cpp:
+ (JSC::DFG::clobbersExitState):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGMayExit.cpp:
+ * dfg/DFGNodeType.h:
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileNewSymbol):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGStoreBarrierInsertionPhase.cpp:
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+ (JSC::FTL::DFG::LowerDFGToB3::compileNewSymbol):
+
+2018-12-12 Yusuke Suzuki <yusukesuz...@slowstart.org>
+
[BigInt] Implement DFG/FTL typeof for BigInt
https://bugs.webkit.org/show_bug.cgi?id=192619
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -2424,6 +2424,11 @@
setForNode(node, node->structure());
break;
}
+
+ case NewSymbol: {
+ setForNode(node, m_vm.symbolStructure.get());
+ break;
+ }
case NewArray:
ASSERT(node->indexingMode() == node->indexingType()); // Copy on write arrays should only be created by NewArrayBuffer.
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -65,6 +65,7 @@
#include "StackAlignment.h"
#include "StringConstructor.h"
#include "StructureStubInfo.h"
+#include "SymbolConstructor.h"
#include "Watchdog.h"
#include <wtf/CommaPrinter.h>
#include <wtf/HashMap.h>
@@ -3712,6 +3713,20 @@
return true;
}
+ if (function->classInfo() == SymbolConstructor::info() && kind == CodeForCall) {
+ insertChecks();
+
+ Node* resultNode;
+
+ if (argumentCountIncludingThis <= 1)
+ resultNode = addToGraph(NewSymbol);
+ else
+ resultNode = addToGraph(NewSymbol, addToGraph(ToString, get(virtualRegisterForArgument(1, registerOffset))));
+
+ set(result, resultNode);
+ return true;
+ }
+
// FIXME: This should handle construction as well. https://bugs.webkit.org/show_bug.cgi?id=155591
if (function->classInfo() == ObjectConstructor::info() && kind == CodeForCall) {
insertChecks();
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1531,6 +1531,7 @@
case NewObject:
case NewRegexp:
+ case NewSymbol:
case NewStringObject:
case PhantomNewObject:
case MaterializeNewObject:
Modified: trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -58,6 +58,7 @@
case Arrayify:
case NewObject:
case NewRegexp:
+ case NewSymbol:
case NewStringObject:
case PhantomNewObject:
case MaterializeNewObject:
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -350,6 +350,7 @@
case NewArrayBuffer:
case NewRegexp:
case NewStringObject:
+ case NewSymbol:
case MakeRope:
case NewFunction:
case NewGeneratorFunction:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1274,6 +1274,12 @@
break;
}
+ case NewSymbol: {
+ if (node->child1())
+ fixEdge<KnownStringUse>(node->child1());
+ break;
+ }
+
case NewArrayWithSpread: {
watchHavingABadTime(node);
Modified: trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGMayExit.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -124,6 +124,7 @@
case NewAsyncFunction:
case NewAsyncGeneratorFunction:
case NewStringObject:
+ case NewSymbol:
case NewRegexp:
case ToNumber:
case RegExpExecNonGlobalOrSticky:
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -336,6 +336,8 @@
macro(NewArrayBuffer, NodeResultJS) \
macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
macro(NewRegexp, NodeResultJS) \
+ macro(NewSymbol, NodeResultJS) \
+ macro(NewStringObject, NodeResultJS) \
/* Rest Parameter */\
macro(GetRestLength, NodeResultInt32) \
macro(CreateRest, NodeResultJS | NodeMustGenerate) \
@@ -380,7 +382,6 @@
macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
macro(NumberToStringWithRadix, NodeResultJS | NodeMustGenerate) \
macro(NumberToStringWithValidRadixConstant, NodeResultJS) \
- macro(NewStringObject, NodeResultJS) \
macro(MakeRope, NodeResultJS) \
macro(InByVal, NodeResultBoolean | NodeMustGenerate) \
macro(InById, NodeResultBoolean | NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -2230,6 +2230,22 @@
return jsSingleCharacterString(exec, static_cast<UChar>(character));
}
+Symbol* JIT_OPERATION operationNewSymbol(ExecState* exec)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return Symbol::create(vm);
+}
+
+Symbol* JIT_OPERATION operationNewSymbolWithDescription(ExecState* exec, JSString* description)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return Symbol::create(exec, description);
+}
+
JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
{
VM& vm = exec->vm();
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -219,6 +219,8 @@
EncodedJSValue JIT_OPERATION operationParseIntString(ExecState*, JSString*, int32_t);
EncodedJSValue JIT_OPERATION operationParseIntGeneric(ExecState*, EncodedJSValue, int32_t);
+Symbol* JIT_OPERATION operationNewSymbol(ExecState*);
+Symbol* JIT_OPERATION operationNewSymbolWithDescription(ExecState*, JSString*);
JSCell* JIT_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
JSString* JIT_OPERATION operationToStringOnCell(ExecState*, JSCell*);
JSString* JIT_OPERATION operationToString(ExecState*, EncodedJSValue);
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1019,6 +1019,10 @@
setPrediction(SpecStringObject);
break;
}
+ case NewSymbol: {
+ setPrediction(SpecSymbol);
+ break;
+ }
case CreateDirectArguments: {
setPrediction(SpecDirectArguments);
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -315,6 +315,7 @@
case NewArrayWithSpread:
case Spread:
case NewRegexp:
+ case NewSymbol:
case ProfileType:
case ProfileControlFlow:
case CheckTypeInfoFlags:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -9647,6 +9647,32 @@
cellResult(resultGPR, node);
}
+void SpeculativeJIT::compileNewSymbol(Node* node)
+{
+ if (!node->child1()) {
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ GPRReg resultGPR = result.gpr();
+ callOperation(operationNewSymbol, resultGPR);
+ m_jit.exceptionCheck();
+ cellResult(resultGPR, node);
+ return;
+ }
+
+
+ ASSERT(node->child1().useKind() == KnownStringUse);
+ SpeculateCellOperand operand(this, node->child1());
+
+ GPRReg stringGPR = operand.gpr();
+
+ flushRegisters();
+ GPRFlushedCallResult result(this);
+ GPRReg resultGPR = result.gpr();
+ callOperation(operationNewSymbolWithDescription, resultGPR, stringGPR);
+ m_jit.exceptionCheck();
+ cellResult(resultGPR, node);
+}
+
void SpeculativeJIT::compileNewTypedArrayWithSize(Node* node)
{
JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2018-12-13 02:09:28 UTC (rev 239142)
@@ -1253,6 +1253,7 @@
void compileNumberToStringWithValidRadixConstant(Node*);
void compileNumberToStringWithValidRadixConstant(Node*, int32_t radix);
void compileNewStringObject(Node*);
+ void compileNewSymbol(Node*);
void compileNewTypedArrayWithSize(Node*);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -3105,6 +3105,11 @@
compileNewStringObject(node);
break;
}
+
+ case NewSymbol: {
+ compileNewSymbol(node);
+ break;
+ }
case NewArray: {
compileNewArray(node);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -3347,6 +3347,11 @@
compileNewStringObject(node);
break;
}
+
+ case NewSymbol: {
+ compileNewSymbol(node);
+ break;
+ }
case NewArray: {
compileNewArray(node);
Modified: trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -325,9 +325,10 @@
case NewArrayBuffer:
case NewTypedArray:
case NewRegexp:
+ case NewStringObject:
+ case NewSymbol:
case MaterializeNewObject:
case MaterializeCreateActivation:
- case NewStringObject:
case MakeRope:
case CreateActivation:
case CreateDirectArguments:
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -74,6 +74,7 @@
case GetButterfly:
case NewObject:
case NewStringObject:
+ case NewSymbol:
case NewArray:
case NewArrayWithSpread:
case Spread:
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (239141 => 239142)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-12-13 02:01:37 UTC (rev 239141)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-12-13 02:09:28 UTC (rev 239142)
@@ -869,6 +869,9 @@
case NewStringObject:
compileNewStringObject();
break;
+ case NewSymbol:
+ compileNewSymbol();
+ break;
case NewArray:
compileNewArray();
break;
@@ -5535,7 +5538,17 @@
m_out.appendTo(continuation, lastNext);
setJSValue(m_out.phi(pointerType(), fastResult, slowResult));
}
-
+
+ void compileNewSymbol()
+ {
+ if (!m_node->child1()) {
+ setJSValue(vmCall(pointerType(), m_out.operation(operationNewSymbol), m_callFrame));
+ return;
+ }
+ ASSERT(m_node->child1().useKind() == KnownStringUse);
+ setJSValue(vmCall(pointerType(), m_out.operation(operationNewSymbolWithDescription), m_callFrame, lowString(m_node->child1())));
+ }
+
void compileNewArray()
{
// First speculate appropriately on all of the children. Do this unconditionally up here