Diff
Modified: trunk/JSTests/ChangeLog (210517 => 210518)
--- trunk/JSTests/ChangeLog 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/JSTests/ChangeLog 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,3 +1,16 @@
+2017-01-09 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, rolling out r210476.
+ https://bugs.webkit.org/show_bug.cgi?id=166859
+
+ "4% JSBench regression" (Requested by keith_mi_ on #webkit).
+
+ Reverted changeset:
+
+ "Add a slice intrinsic to the DFG/FTL"
+ https://bugs.webkit.org/show_bug.cgi?id=166707
+ http://trac.webkit.org/changeset/210476
+
2017-01-06 Saam Barati <sbar...@apple.com>
Add a slice intrinsic to the DFG/FTL
Deleted: trunk/JSTests/stress/array-slice-intrinsic.js (210517 => 210518)
--- trunk/JSTests/stress/array-slice-intrinsic.js 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/JSTests/stress/array-slice-intrinsic.js 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,49 +0,0 @@
-function assert(b) {
- if (!b)
- throw new Error("Bad")
-}
-noInline(assert);
-
-function shallowEq(a, b) {
- assert(a.length === b.length);
- for (let i = 0; i < a.length; i++)
- assert(a[i] === b[i]);
-}
-noInline(shallowEq);
-
-let tests = [
- [[1,2,3,4,5], [1,2,3,4,5], 0, 5],
- [[1,2,3,4,5], [1,2,3,4,5], 0],
- [[1,2,3,4,5], [4], -2, -1],
- [[1,2,3,4,5], [5], -1],
- [[1,2,3,4,5], [5], -1, 5],
- [[1,2,3,4,5], [], -10, -20],
- [[1,2,3,4,5], [], -20, -10],
- [[1,2,3,4,5], [], 6, 4],
- [[1,2,3,4,5], [], 3, 2],
- [[1,2,3,4,5], [4,5], 3, 10],
- [[1,2,3,4,5], [3,4,5], 2, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -10, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -5, 10],
- [[1,2,3,4,5], [2,3,4,5], -4, 10],
-];
-
-function runTest1(a, b) {
- return a.slice(b);
-}
-noInline(runTest1);
-
-function runTest2(a, b, c) {
- return a.slice(b, c);
-}
-noInline(runTest2);
-
-for (let i = 0; i < 10000; i++) {
- for (let [input, output, ...args] of tests) {
- assert(args.length === 1 || args.length === 2);
- if (args.length === 1)
- shallowEq(runTest1(input, args[0]), output);
- else
- shallowEq(runTest2(input, args[0], args[1]), output);
- }
-}
Deleted: trunk/JSTests/stress/array-slice-jettison-on-constructor-change.js (210517 => 210518)
--- trunk/JSTests/stress/array-slice-jettison-on-constructor-change.js 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/JSTests/stress/array-slice-jettison-on-constructor-change.js 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,72 +0,0 @@
-function assert(b) {
- if (!b)
- throw new Error("Bad")
-}
-noInline(assert);
-
-let shouldBeNewConstructor = false;
-const newConstructor = {};
-
-function shallowEq(a, b) {
- assert(a.length === b.length);
- if (shouldBeNewConstructor)
- assert(b.constructor === newConstructor);
- for (let i = 0; i < a.length; i++)
- assert(a[i] === b[i]);
-}
-noInline(shallowEq);
-
-let tests = [
- [[1,2,3,4,5], [1,2,3,4,5], 0, 5],
- [[1,2,3,4,5], [1,2,3,4,5], 0],
- [[1,2,3,4,5], [4], -2, -1],
- [[1,2,3,4,5], [5], -1],
- [[1,2,3,4,5], [5], -1, 5],
- [[1,2,3,4,5], [], -10, -20],
- [[1,2,3,4,5], [], -20, -10],
- [[1,2,3,4,5], [], 6, 4],
- [[1,2,3,4,5], [], 3, 2],
- [[1,2,3,4,5], [4,5], 3, 10],
- [[1,2,3,4,5], [3,4,5], 2, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -10, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -5, 10],
- [[1,2,3,4,5], [2,3,4,5], -4, 10],
-];
-
-function runTest1(a, b) {
- let result = a.slice(b);
- return result;
-}
-noInline(runTest1);
-
-function runTest2(a, b, c) {
- let result = a.slice(b, c);
- return result;
-}
-noInline(runTest2);
-
-function addRandomProperties(input) {
- for (let i = 0; i < 4; i++) {
- input["prop" + i + ((Math.random() * 100000) | 0)] = i;
- }
-}
-noInline(addRandomProperties);
-
-function runTests() {
- for (let i = 0; i < 10000; i++) {
- for (let [input, output, ...args] of tests) {
- addRandomProperties(input);
- assert(args.length === 1 || args.length === 2);
- if (args.length === 1)
- shallowEq(runTest1(input, args[0]), output);
- else
- shallowEq(runTest2(input, args[0], args[1]), output);
- }
- }
-}
-
-runTests();
-
-Array.prototype.constructor = newConstructor;
-shouldBeNewConstructor = true;
-runTests();
Deleted: trunk/JSTests/stress/array-slice-osr-exit-2.js (210517 => 210518)
--- trunk/JSTests/stress/array-slice-osr-exit-2.js 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/JSTests/stress/array-slice-osr-exit-2.js 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,76 +0,0 @@
-function assert(b) {
- if (!b)
- throw new Error("Bad")
-}
-noInline(assert);
-
-class Foo extends Array {
- constructor(...args) {
- super(...args);
- }
-};
-function shallowEq(a, b) {
- assert(a.length === b.length);
- for (let i = 0; i < a.length; i++)
- assert(a[i] === b[i]);
-}
-noInline(shallowEq);
-
-let tests = [
- [[1,2,3,4,5], [1,2,3,4,5], 0, 5],
- [[1,2,3,4,5], [1,2,3,4,5], 0],
- [[1,2,3,4,5], [4], -2, -1],
- [[1,2,3,4,5], [5], -1],
- [[1,2,3,4,5], [5], -1, 5],
- [[1,2,3,4,5], [], -10, -20],
- [[1,2,3,4,5], [], -20, -10],
- [[1,2,3,4,5], [], 6, 4],
- [[1,2,3,4,5], [], 3, 2],
- [[1,2,3,4,5], [4,5], 3, 10],
- [[1,2,3,4,5], [3,4,5], 2, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -10, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -5, 10],
- [[1,2,3,4,5], [2,3,4,5], -4, 10],
-];
-
-function runTest1(a, b) {
- let result = a.slice(b);
- assert(a instanceof Foo === result instanceof Foo);
- return result;
-}
-noInline(runTest1);
-
-function runTest2(a, b, c) {
- let result = a.slice(b, c);
- assert(a instanceof Foo === result instanceof Foo);
- return result;
-}
-noInline(runTest2);
-
-function addRandomProperties(input) {
- for (let i = 0; i < 4; i++) {
- input["prop" + i + ((Math.random() * 100000) | 0)] = i;
- }
-}
-noInline(addRandomProperties);
-
-function runTests() {
- for (let i = 0; i < 10000; i++) {
- for (let [input, output, ...args] of tests) {
- addRandomProperties(input);
- assert(args.length === 1 || args.length === 2);
- if (args.length === 1)
- shallowEq(runTest1(input, args[0]), output);
- else
- shallowEq(runTest2(input, args[0], args[1]), output);
- }
- }
-}
-
-runTests();
-
-tests.push([new Foo(1,2,3,4,5), [1,2,3,4,5], -10, 10]);
-tests.push([new Foo(1,2,3,4,5), [1,2,3,4,5], -5, 10]);
-tests.push([new Foo(1,2,3,4,5), [2,3,4,5], -4, 10]);
-tests.push([new Foo(1,2,3,4,5), [2,3,4,5], -4]);
-runTests();
Deleted: trunk/JSTests/stress/array-slice-osr-exit.js (210517 => 210518)
--- trunk/JSTests/stress/array-slice-osr-exit.js 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/JSTests/stress/array-slice-osr-exit.js 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,74 +0,0 @@
-function assert(b) {
- if (!b)
- throw new Error("Bad")
-}
-noInline(assert);
-
-class Foo extends Array {
- constructor(...args) {
- super(...args);
- }
-};
-function shallowEq(a, b) {
- assert(a.length === b.length);
- for (let i = 0; i < a.length; i++)
- assert(a[i] === b[i]);
-}
-noInline(shallowEq);
-
-let tests = [
- [[1,2,3,4,5], [1,2,3,4,5], 0, 5],
- [[1,2,3,4,5], [1,2,3,4,5], 0],
- [[1,2,3,4,5], [4], -2, -1],
- [[1,2,3,4,5], [5], -1],
- [[1,2,3,4,5], [5], -1, 5],
- [[1,2,3,4,5], [], -10, -20],
- [[1,2,3,4,5], [], -20, -10],
- [[1,2,3,4,5], [], 6, 4],
- [[1,2,3,4,5], [], 3, 2],
- [[1,2,3,4,5], [4,5], 3, 10],
- [[1,2,3,4,5], [3,4,5], 2, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -10, 10],
- [[1,2,3,4,5], [1,2,3,4,5], -5, 10],
- [[1,2,3,4,5], [2,3,4,5], -4, 10],
-];
-tests.push([new Foo(1,2,3,4,5), [1,2,3,4,5], -10, 10]);
-tests.push([new Foo(1,2,3,4,5), [1,2,3,4,5], -5, 10]);
-tests.push([new Foo(1,2,3,4,5), [2,3,4,5], -4, 10]);
-tests.push([new Foo(1,2,3,4,5), [2,3,4,5], -4]);
-
-function runTest1(a, b) {
- let result = a.slice(b);
- assert(a instanceof Foo === result instanceof Foo);
- return result;
-}
-noInline(runTest1);
-
-function runTest2(a, b, c) {
- let result = a.slice(b, c);
- assert(a instanceof Foo === result instanceof Foo);
- return result;
-}
-noInline(runTest2);
-
-function addRandomProperties(input) {
- for (let i = 0; i < 4; i++) {
- input["prop" + i + ((Math.random() * 100000) | 0)] = i;
- }
-}
-noInline(addRandomProperties);
-
-function runTests() {
- for (let i = 0; i < 10000; i++) {
- for (let [input, output, ...args] of tests) {
- addRandomProperties(input);
- assert(args.length === 1 || args.length === 2);
- if (args.length === 1)
- shallowEq(runTest1(input, args[0]), output);
- else
- shallowEq(runTest2(input, args[0], args[1]), output);
- }
- }
-}
-
-runTests();
Modified: trunk/Source/_javascript_Core/ChangeLog (210517 => 210518)
--- trunk/Source/_javascript_Core/ChangeLog 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1,3 +1,16 @@
+2017-01-09 Commit Queue <commit-qu...@webkit.org>
+
+ Unreviewed, rolling out r210476.
+ https://bugs.webkit.org/show_bug.cgi?id=166859
+
+ "4% JSBench regression" (Requested by keith_mi_ on #webkit).
+
+ Reverted changeset:
+
+ "Add a slice intrinsic to the DFG/FTL"
+ https://bugs.webkit.org/show_bug.cgi?id=166707
+ http://trac.webkit.org/changeset/210476
+
2017-01-08 Andreas Kling <akl...@apple.com>
Inject MarkedSpace size classes for a few more high-volume objects.
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1650,25 +1650,6 @@
clobberWorld(node->origin.semantic, clobberLimit);
forNode(node).setType(SpecBytecodeNumber);
break;
-
- case ArraySlice:
- IndexingType indexingType;
- switch (node->arrayMode().type()) {
- case Array::Double:
- indexingType = ArrayWithDouble;
- break;
- case Array::Int32:
- indexingType = ArrayWithInt32;
- break;
- case Array::Contiguous:
- indexingType = ArrayWithContiguous;
- break;
- default:
- DFG_CRASH(m_graph, node, "Bad array mode.");
- }
-
- forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(indexingType));
- break;
case ArrayPop:
clobberWorld(node->origin.semantic, clobberLimit);
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -2246,92 +2246,6 @@
return false;
}
}
-
- case ArraySliceIntrinsic: {
-#if USE(JSVALUE32_64)
- if (isX86()) {
- // There aren't enough registers for this to be done easily.
- return false;
- }
-#endif
- if (argumentCountIncludingThis < 2)
- return false;
-
- if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIndexingType)
- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadConstantCache)
- || m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCache))
- return false;
-
- ArrayMode arrayMode = getArrayMode(m_currentInstruction[OPCODE_LENGTH(op_call) - 2].u.arrayProfile);
- if (!arrayMode.isJSArray())
- return false;
-
- if (arrayMode.arrayClass() != Array::OriginalArray)
- return false;
-
- switch (arrayMode.type()) {
- case Array::Double:
- case Array::Int32:
- case Array::Contiguous: {
- JSGlobalObject* globalObject = m_graph.globalObjectFor(currentNodeOrigin().semantic);
-
- InlineWatchpointSet& objectPrototypeTransition = globalObject->objectPrototype()->structure()->transitionWatchpointSet();
- InlineWatchpointSet& arrayPrototypeTransition = globalObject->arrayPrototype()->structure()->transitionWatchpointSet();
-
- // FIXME: We could easily relax the Array/Object.prototype transition as long as we OSR exitted if we saw a hole.
- if (globalObject->arraySpeciesWatchpoint().isStillValid()
- && globalObject->havingABadTimeWatchpoint()->isStillValid()
- && arrayPrototypeTransition.isStillValid()
- && objectPrototypeTransition.isStillValid()
- && globalObject->arrayPrototypeChainIsSane()) {
-
- m_graph.watchpoints().addLazily(globalObject->arraySpeciesWatchpoint());
- m_graph.watchpoints().addLazily(globalObject->havingABadTimeWatchpoint());
- m_graph.watchpoints().addLazily(arrayPrototypeTransition);
- m_graph.watchpoints().addLazily(objectPrototypeTransition);
-
- insertChecks();
-
- Node* array = get(virtualRegisterForArgument(0, registerOffset));
- // We do a few things here to prove that we aren't skipping doing side-effects in an observable way:
- // 1. We ensure that the "constructor" property hasn't been changed (because the observable
- // effects of slice require that we perform a Get(array, "constructor") and we can skip
- // that if we're an original array structure.
- //
- // 2. We check that the array we're calling slice on has the same global object as the lexical
- // global object that this code is running in. This requirement is necessary because we setup the
- // watchpoints above on the lexical global object. This means that code that calls slice on
- // arrays produced by other global objects won't get this optimization. We could relax this
- // requirement in the future by checking that the watchpoint hasn't fired at runtime in the code
- // we generate instead of registering it as a watchpoint that would invalidate the compilation.
- //
- // 3. By proving we're an original array structure, we guarantee that the incoming array
- // isn't a subclass of Array.
-
- Structure* structure = arrayMode.originalArrayStructure(m_graph, currentNodeOrigin().semantic);
- RELEASE_ASSERT(structure);
- addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), array);
-
- addVarArgChild(array);
- addVarArgChild(get(virtualRegisterForArgument(1, registerOffset))); // Start index.
- if (argumentCountIncludingThis >= 3)
- addVarArgChild(get(virtualRegisterForArgument(2, registerOffset))); // End index.
- addVarArgChild(addToGraph(GetButterfly, array));
-
- Node* arraySlice = addToGraph(Node::VarArg, ArraySlice, OpInfo(arrayMode.asWord()), OpInfo(prediction));
- set(VirtualRegister(resultOperand), arraySlice);
- return true;
- }
-
- return false;
- }
- default:
- return false;
- }
-
- RELEASE_ASSERT_NOT_REACHED();
- return false;
- }
case ArrayPopIntrinsic: {
if (argumentCountIncludingThis != 1)
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -503,29 +503,6 @@
read(MiscFields);
def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node));
return;
-
- case ArraySlice:
- read(MiscFields);
- read(JSCell_indexingType);
- read(JSCell_structureID);
- read(JSObject_butterfly);
- read(Butterfly_publicLength);
- switch (node->arrayMode().type()) {
- case Array::Double:
- read(IndexedDoubleProperties);
- break;
- case Array::Int32:
- read(IndexedInt32Properties);
- break;
- case Array::Contiguous:
- read(IndexedContiguousProperties);
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
- read(HeapObjectCount);
- write(HeapObjectCount);
- return;
case GetById:
case GetByIdFlush:
Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -309,7 +309,6 @@
case ToLowerCase:
case CallDOMGetter:
case CallDOM:
- case ArraySlice:
return true;
case MultiPutByOffset:
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -931,14 +931,6 @@
fixEdge<KnownCellUse>(node->child1());
break;
}
-
- case ArraySlice: {
- fixEdge<KnownCellUse>(m_graph.varArgChild(node, 0));
- fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
- if (node->numChildren() == 4)
- fixEdge<Int32Use>(m_graph.varArgChild(node, 2));
- break;
- }
case RegExpExec:
case RegExpTest: {
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -1472,7 +1472,6 @@
case GetArgument:
case ArrayPop:
case ArrayPush:
- case ArraySlice:
case RegExpExec:
case RegExpTest:
case GetGlobalVar:
@@ -1797,7 +1796,6 @@
case Arrayify:
case ArrayifyToStructure:
case ArrayPush:
- case ArraySlice:
case ArrayPop:
case HasIndexedProperty:
return true;
Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -248,7 +248,6 @@
/* Optimizations for array mutation. */\
macro(ArrayPush, NodeResultJS | NodeMustGenerate) \
macro(ArrayPop, NodeResultJS | NodeMustGenerate) \
- macro(ArraySlice, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
\
/* Optimizations for regular _expression_ matching. */\
macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -678,7 +678,6 @@
case ArrayPop:
case ArrayPush:
- case ArraySlice:
case RegExpExec:
case RegExpTest:
case StringReplace:
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -402,7 +402,6 @@
case GetArrayLength:
case ArrayPush:
case ArrayPop:
- case ArraySlice:
case StringCharAt:
case StringCharCodeAt:
return node->arrayMode().alreadyChecked(graph, node, state.forNode(node->child1()));
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -7171,127 +7171,6 @@
int32Result(resultGPR, node);
}
-void SpeculativeJIT::compileArraySlice(Node* node)
-{
- ASSERT(node->op() == ArraySlice);
-
- JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
-
- GPRTemporary temp(this);
- StorageOperand storage(this, node->numChildren() == 3 ? m_jit.graph().varArgChild(node, 2) : m_jit.graph().varArgChild(node, 3));
- GPRTemporary result(this);
-
- GPRReg storageGPR = storage.gpr();
- GPRReg resultGPR = result.gpr();
- GPRReg tempGPR = temp.gpr();
-
- IndexingType indexingType;
- switch (node->arrayMode().type()) {
- case Array::Int32:
- indexingType = ArrayWithInt32;
- break;
- case Array::Contiguous:
- indexingType = ArrayWithContiguous;
- break;
- case Array::Double:
- indexingType = ArrayWithDouble;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
-
- auto populateIndex = [&] (unsigned childIndex, GPRReg length, GPRReg result) {
- SpeculateInt32Operand index(this, m_jit.graph().varArgChild(node, childIndex));
- GPRReg indexGPR = index.gpr();
- MacroAssembler::JumpList done;
- auto isPositive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, indexGPR, TrustedImm32(0));
- m_jit.move(length, result);
- done.append(m_jit.branchAdd32(MacroAssembler::PositiveOrZero, indexGPR, result));
- m_jit.move(TrustedImm32(0), result);
- done.append(m_jit.jump());
-
- isPositive.link(&m_jit);
- m_jit.move(indexGPR, result);
- done.append(m_jit.branch32(MacroAssembler::BelowOrEqual, result, length));
- m_jit.move(length, result);
-
- done.link(&m_jit);
- };
-
- {
- GPRTemporary tempLength(this);
- GPRReg lengthGPR = tempLength.gpr();
- m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), lengthGPR);
-
- if (node->numChildren() == 4)
- populateIndex(2, lengthGPR, tempGPR);
- else
- m_jit.move(lengthGPR, tempGPR);
-
- GPRTemporary tempStartIndex(this);
- GPRReg startGPR = tempStartIndex.gpr();
- populateIndex(1, lengthGPR, startGPR);
-
- auto tooBig = m_jit.branch32(MacroAssembler::Above, startGPR, tempGPR);
- m_jit.sub32(startGPR, tempGPR); // the size of the array we'll make.
- auto done = m_jit.jump();
-
- tooBig.link(&m_jit);
- m_jit.move(TrustedImm32(0), tempGPR);
- done.link(&m_jit);
- }
-
- const bool shouldConvertLargeSizeToArrayStorage = false;
- compileAllocateNewArrayWithSize(globalObject, resultGPR, tempGPR, indexingType, shouldConvertLargeSizeToArrayStorage);
-
- GPRTemporary temp3(this);
- GPRTemporary temp4(this);
- GPRReg tempValue = temp3.gpr();
- GPRReg loadIndex = temp4.gpr();
-
- m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), tempValue);
- if (node->numChildren() == 4)
- populateIndex(2, tempValue, tempGPR);
- else
- m_jit.move(tempValue, tempGPR);
- populateIndex(1, tempValue, loadIndex);
-
- GPRTemporary temp5(this);
- GPRReg storeIndex = temp5.gpr();
- m_jit.move(TrustedImmPtr(0), storeIndex);
-
- GPRTemporary temp2(this);
- GPRReg resultButterfly = temp2.gpr();
-
- m_jit.loadPtr(MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()), resultButterfly);
- m_jit.zeroExtend32ToPtr(tempGPR, tempGPR);
- m_jit.zeroExtend32ToPtr(loadIndex, loadIndex);
- auto done = m_jit.branchPtr(MacroAssembler::AboveOrEqual, loadIndex, tempGPR);
-
- auto loop = m_jit.label();
-#if USE(JSVALUE64)
- m_jit.load64(
- MacroAssembler::BaseIndex(storageGPR, loadIndex, MacroAssembler::TimesEight), tempValue);
- m_jit.store64(
- tempValue, MacroAssembler::BaseIndex(resultButterfly, storeIndex, MacroAssembler::TimesEight));
-#else
- m_jit.load32(
- MacroAssembler::BaseIndex(storageGPR, loadIndex, MacroAssembler::TimesEight, PayloadOffset), tempValue);
- m_jit.store32(
- tempValue, MacroAssembler::BaseIndex(resultButterfly, storeIndex, MacroAssembler::TimesEight, PayloadOffset));
- m_jit.load32(
- MacroAssembler::BaseIndex(storageGPR, loadIndex, MacroAssembler::TimesEight, TagOffset), tempValue);
- m_jit.store32(
- tempValue, MacroAssembler::BaseIndex(resultButterfly, storeIndex, MacroAssembler::TimesEight, TagOffset));
-#endif // USE(JSVALUE64)
- m_jit.addPtr(TrustedImm32(1), loadIndex);
- m_jit.addPtr(TrustedImm32(1), storeIndex);
- m_jit.branchPtr(MacroAssembler::Below, loadIndex, tempGPR).linkTo(loop, &m_jit);
-
- done.link(&m_jit);
- cellResult(resultGPR, node);
-}
-
void SpeculativeJIT::compileNotifyWrite(Node* node)
{
WatchpointSet* set = node->watchpointSet();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -2680,7 +2680,6 @@
void compileSpread(Node*);
void compileNewArrayWithSpread(Node*);
void compileGetRestLength(Node*);
- void compileArraySlice(Node*);
void compileNotifyWrite(Node*);
bool compileRegExpExec(Node*);
void compileIsObjectOrNull(Node*);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -3550,11 +3550,6 @@
break;
}
- case ArraySlice: {
- compileArraySlice(node);
- break;
- }
-
case DFG::Jump: {
jump(node->targetBlock());
noResult(node);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -3462,11 +3462,6 @@
}
break;
}
-
- case ArraySlice: {
- compileArraySlice(node);
- break;
- }
case ArrayPop: {
ASSERT(node->arrayMode().isJSArray());
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -282,7 +282,6 @@
case CheckDOM:
case CallDOM:
case CallDOMGetter:
- case ArraySlice:
// These are OK.
break;
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -706,9 +706,6 @@
case ArrayPop:
compileArrayPop();
break;
- case ArraySlice:
- compileArraySlice();
- break;
case CreateActivation:
compileCreateActivation();
break;
@@ -3863,83 +3860,6 @@
return;
}
}
-
- void compileArraySlice()
- {
- JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
-
- LValue sourceStorage = lowStorage(m_node->numChildren() == 3 ? m_graph.varArgChild(m_node, 2) : m_graph.varArgChild(m_node, 3));
- LValue inputLength = m_out.load32(sourceStorage, m_heaps.Butterfly_publicLength);
-
- LValue endBoundary;
- if (m_node->numChildren() == 3)
- endBoundary = m_out.load32(sourceStorage, m_heaps.Butterfly_publicLength);
- else {
- endBoundary = lowInt32(m_graph.varArgChild(m_node, 2));
- endBoundary = m_out.select(m_out.greaterThanOrEqual(endBoundary, m_out.constInt32(0)),
- m_out.select(m_out.above(endBoundary, inputLength), inputLength, endBoundary),
- m_out.select(m_out.lessThan(m_out.add(inputLength, endBoundary), m_out.constInt32(0)), m_out.constInt32(0), m_out.add(inputLength, endBoundary)));
- }
-
- LValue startIndex = lowInt32(m_graph.varArgChild(m_node, 1));
- startIndex = m_out.select(m_out.greaterThanOrEqual(startIndex, m_out.constInt32(0)),
- m_out.select(m_out.above(startIndex, inputLength), inputLength, startIndex),
- m_out.select(m_out.lessThan(m_out.add(inputLength, startIndex), m_out.constInt32(0)), m_out.constInt32(0), m_out.add(inputLength, startIndex)));
-
- LValue resultLength = m_out.select(m_out.below(startIndex, endBoundary),
- m_out.sub(endBoundary, startIndex),
- m_out.constInt32(0));
-
- IndexingType indexingType;
- switch (m_node->arrayMode().type()) {
- case Array::Int32:
- indexingType = ArrayWithInt32;
- break;
- case Array::Contiguous:
- indexingType = ArrayWithContiguous;
- break;
- case Array::Double:
- indexingType = ArrayWithDouble;
- break;
- default:
- RELEASE_ASSERT_NOT_REACHED();
- }
-
- Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType);
- auto arrayResult = allocateJSArray(resultLength, structure, false, false);
-
- LBasicBlock loop = m_out.newBlock();
- LBasicBlock continuation = m_out.newBlock();
-
- resultLength = m_out.zeroExtPtr(resultLength);
- ValueFromBlock startLoadIndex = m_out.anchor(m_out.zeroExtPtr(startIndex));
- ValueFromBlock startStoreIndex = m_out.anchor(m_out.constIntPtr(0));
-
- m_out.branch(
- m_out.below(m_out.constIntPtr(0), resultLength), unsure(loop), unsure(continuation));
-
- LBasicBlock lastNext = m_out.appendTo(loop, continuation);
- LValue storeIndex = m_out.phi(pointerType(), startStoreIndex);
- LValue loadIndex = m_out.phi(pointerType(), startLoadIndex);
- IndexedAbstractHeap& heap = m_heaps.forArrayType(m_node->arrayMode().type());
- if (indexingType == ArrayWithDouble) {
- LValue value = m_out.loadDouble(m_out.baseIndex(heap, sourceStorage, loadIndex));
- m_out.storeDouble(value, m_out.baseIndex(heap, arrayResult.butterfly, storeIndex));
- } else {
- LValue value = m_out.load64(m_out.baseIndex(heap, sourceStorage, loadIndex));
- m_out.store64(value, m_out.baseIndex(heap, arrayResult.butterfly, storeIndex));
- }
- LValue nextStoreIndex = m_out.add(storeIndex, m_out.constIntPtr(1));
- m_out.addIncomingToPhi(storeIndex, m_out.anchor(nextStoreIndex));
- m_out.addIncomingToPhi(loadIndex, m_out.anchor(m_out.add(loadIndex, m_out.constIntPtr(1))));
- m_out.branch(
- m_out.below(nextStoreIndex, resultLength), unsure(loop), unsure(continuation));
-
- m_out.appendTo(continuation, lastNext);
-
- mutatorFence();
- setJSValue(arrayResult.array);
- }
void compileArrayPop()
{
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -447,7 +447,6 @@
void AssemblyHelpers::emitLoadStructure(RegisterID source, RegisterID dest, RegisterID scratch)
{
#if USE(JSVALUE64)
- ASSERT(dest != scratch);
load32(MacroAssembler::Address(source, JSCell::structureIDOffset()), dest);
loadPtr(vm()->heap.structureIDTable().base(), scratch);
loadPtr(MacroAssembler::BaseIndex(scratch, dest, MacroAssembler::TimesEight), dest);
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -98,7 +98,7 @@
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("reverse", arrayProtoFuncReverse, DontEnum, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().shiftPublicName(), arrayProtoFuncShift, DontEnum, 0);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().shiftPrivateName(), arrayProtoFuncShift, DontEnum | DontDelete | ReadOnly, 0);
- JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, arrayProtoFuncSlice, DontEnum, 2, ArraySliceIntrinsic);
+ JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->slice, arrayProtoFuncSlice, DontEnum, 2);
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("sort", arrayPrototypeSortCodeGenerator, DontEnum);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("splice", arrayProtoFuncSplice, DontEnum, 2);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("unshift", arrayProtoFuncUnShift, DontEnum, 1);
@@ -191,12 +191,21 @@
throwTypeError(exec, scope, ASCIILiteral(ReadonlyPropertyWriteError));
}
-inline bool speciesWatchpointIsValid(JSObject* thisObject)
+inline bool speciesWatchpointsValid(ExecState* exec, JSObject* thisObject)
{
+ VM& vm = exec->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
ArrayPrototype* arrayPrototype = thisObject->globalObject()->arrayPrototype();
+ ArrayPrototype::SpeciesWatchpointStatus status = arrayPrototype->speciesWatchpointStatus();
+ if (UNLIKELY(status == ArrayPrototype::SpeciesWatchpointStatus::Uninitialized)) {
+ status = arrayPrototype->attemptToInitializeSpeciesWatchpoint(exec);
+ RETURN_IF_EXCEPTION(scope, false);
+ }
+ ASSERT(status != ArrayPrototype::SpeciesWatchpointStatus::Uninitialized);
return !thisObject->hasCustomProperties()
&& arrayPrototype == thisObject->getPrototypeDirect()
- && arrayPrototype->globalObject()->arraySpeciesWatchpoint().isStillValid();
+ && status == ArrayPrototype::SpeciesWatchpointStatus::Initialized;
}
enum class SpeciesConstructResult {
@@ -221,7 +230,8 @@
if (LIKELY(thisIsArray)) {
// Fast path in the normal case where the user has not set an own constructor and the Array.prototype.constructor is normal.
// We need prototype check for subclasses of Array, which are Array objects but have a different prototype by default.
- bool isValid = speciesWatchpointIsValid(thisObject);
+ bool isValid = speciesWatchpointsValid(exec, thisObject);
+ RETURN_IF_EXCEPTION(scope, exceptionResult());
if (LIKELY(isValid))
return std::make_pair(SpeciesConstructResult::FastPath, nullptr);
@@ -910,29 +920,29 @@
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
{
- // https://tc39.github.io/ecma262/#sec-array.prototype.slice
+ // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
ASSERT(!!scope.exception() == !thisObj);
if (UNLIKELY(!thisObj))
- return { };
+ return encodedJSValue();
unsigned length = getLength(exec, thisObj);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
std::pair<SpeciesConstructResult, JSObject*> speciesResult = speciesConstructArray(exec, thisObj, end - begin);
// We can only get an exception if we call some user function.
ASSERT(!!scope.exception() == (speciesResult.first == SpeciesConstructResult::Exception));
if (UNLIKELY(speciesResult.first == SpeciesConstructResult::Exception))
- return { };
+ return encodedJSValue();
bool okToDoFastPath = speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj) && length == getLength(exec, thisObj);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
if (LIKELY(okToDoFastPath)) {
if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin))
return JSValue::encode(result);
@@ -943,16 +953,16 @@
result = speciesResult.second;
else {
result = constructEmptyArray(exec, nullptr, end - begin);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
}
unsigned n = 0;
for (unsigned k = begin; k < end; k++, n++) {
JSValue v = getProperty(exec, thisObj, k);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
if (v) {
result->putDirectIndex(exec, n, v, 0, PutDirectIndexShouldThrow);
- RETURN_IF_EXCEPTION(scope, { });
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
}
}
scope.release();
@@ -1239,7 +1249,8 @@
return JSValue::encode(jsNull());
// We need to check the species constructor here since checking it in the JS wrapper is too expensive for the non-optimizing tiers.
- bool isValid = speciesWatchpointIsValid(firstArray);
+ bool isValid = speciesWatchpointsValid(exec, firstArray);
+ ASSERT(!scope.exception() || !isValid);
if (UNLIKELY(!isValid))
return JSValue::encode(jsNull());
@@ -1331,18 +1342,15 @@
ArrayPrototype* m_arrayPrototype;
};
-void ArrayPrototype::initializeSpeciesWatchpoint(ExecState* exec)
+ArrayPrototype::SpeciesWatchpointStatus ArrayPrototype::attemptToInitializeSpeciesWatchpoint(ExecState* exec)
{
+ ASSERT(m_speciesWatchpointStatus == SpeciesWatchpointStatus::Uninitialized);
+
VM& vm = exec->vm();
-
- RELEASE_ASSERT(!m_constructorWatchpoint);
- RELEASE_ASSERT(!m_constructorSpeciesWatchpoint);
-
auto scope = DECLARE_THROW_SCOPE(vm);
- UNUSED_PARAM(scope);
if (verbose)
- dataLog("Initializing Array species watchpoints for Array.prototype: ", pointerDump(this), " with structure: ", pointerDump(this->structure()), "\nand Array: ", pointerDump(this->globalObject()->arrayConstructor()), " with structure: ", pointerDump(this->globalObject()->arrayConstructor()->structure()), "\n");
+ dataLog("Attempting to initialize Array species watchpoints for Array.prototype: ", pointerDump(this), " with structure: ", pointerDump(this->structure()), "\nand Array: ", pointerDump(this->globalObject()->arrayConstructor()), " with structure: ", pointerDump(this->globalObject()->arrayConstructor()->structure()), "\n");
// First we need to make sure that the Array.prototype.constructor property points to Array
// and that Array[Symbol.species] is the primordial GetterSetter.
@@ -1356,11 +1364,12 @@
ArrayConstructor* arrayConstructor = globalObject->arrayConstructor();
PropertySlot constructorSlot(this, PropertySlot::InternalMethodType::VMInquiry);
- this->getOwnPropertySlot(this, exec, vm.propertyNames->constructor, constructorSlot);
- ASSERT(!scope.exception());
- ASSERT(constructorSlot.slotBase() == this);
- ASSERT(constructorSlot.isCacheableValue());
- RELEASE_ASSERT(constructorSlot.getValue(exec, vm.propertyNames->constructor) == arrayConstructor);
+ JSValue(this).get(exec, vm.propertyNames->constructor, constructorSlot);
+ if (UNLIKELY(scope.exception())
+ || constructorSlot.slotBase() != this
+ || !constructorSlot.isCacheableValue()
+ || constructorSlot.getValue(exec, vm.propertyNames->constructor) != arrayConstructor)
+ return m_speciesWatchpointStatus = SpeciesWatchpointStatus::Fired;
Structure* constructorStructure = arrayConstructor->structure(vm);
if (constructorStructure->isDictionary())
@@ -1367,11 +1376,12 @@
constructorStructure = constructorStructure->flattenDictionaryStructure(vm, arrayConstructor);
PropertySlot speciesSlot(arrayConstructor, PropertySlot::InternalMethodType::VMInquiry);
- arrayConstructor->getOwnPropertySlot(arrayConstructor, exec, vm.propertyNames->speciesSymbol, speciesSlot);
- ASSERT(!scope.exception());
- ASSERT(speciesSlot.slotBase() == arrayConstructor);
- ASSERT(speciesSlot.isCacheableGetter());
- RELEASE_ASSERT(speciesSlot.getterSetter() == globalObject->speciesGetterSetter());
+ JSValue(arrayConstructor).get(exec, vm.propertyNames->speciesSymbol, speciesSlot);
+ if (UNLIKELY(scope.exception())
+ || speciesSlot.slotBase() != arrayConstructor
+ || !speciesSlot.isCacheableGetter()
+ || speciesSlot.getterSetter() != globalObject->speciesGetterSetter())
+ return m_speciesWatchpointStatus = SpeciesWatchpointStatus::Fired;
// Now we need to setup the watchpoints to make sure these conditions remain valid.
prototypeStructure->startWatchingPropertyForReplacements(vm, constructorSlot.cachedOffset());
@@ -1380,8 +1390,8 @@
ObjectPropertyCondition constructorCondition = ObjectPropertyCondition::equivalence(vm, this, this, vm.propertyNames->constructor.impl(), arrayConstructor);
ObjectPropertyCondition speciesCondition = ObjectPropertyCondition::equivalence(vm, this, arrayConstructor, vm.propertyNames->speciesSymbol.impl(), globalObject->speciesGetterSetter());
- RELEASE_ASSERT(constructorCondition.isWatchable());
- RELEASE_ASSERT(speciesCondition.isWatchable());
+ if (!constructorCondition.isWatchable() || !speciesCondition.isWatchable())
+ return m_speciesWatchpointStatus = SpeciesWatchpointStatus::Fired;
m_constructorWatchpoint = std::make_unique<ArrayPrototypeAdaptiveInferredPropertyWatchpoint>(constructorCondition, this);
m_constructorWatchpoint->install();
@@ -1388,6 +1398,8 @@
m_constructorSpeciesWatchpoint = std::make_unique<ArrayPrototypeAdaptiveInferredPropertyWatchpoint>(speciesCondition, this);
m_constructorSpeciesWatchpoint->install();
+
+ return m_speciesWatchpointStatus = SpeciesWatchpointStatus::Initialized;
}
ArrayPrototypeAdaptiveInferredPropertyWatchpoint::ArrayPrototypeAdaptiveInferredPropertyWatchpoint(const ObjectPropertyCondition& key, ArrayPrototype* prototype)
@@ -1406,8 +1418,7 @@
if (verbose)
WTF::dataLog(stringDetail, "\n");
- JSGlobalObject* globalObject = m_arrayPrototype->globalObject();
- globalObject->arraySpeciesWatchpoint().fireAll(globalObject->vm(), stringDetail);
+ m_arrayPrototype->m_speciesWatchpointStatus = ArrayPrototype::SpeciesWatchpointStatus::Fired;
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.h (210517 => 210518)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -49,7 +49,8 @@
return Structure::create(vm, globalObject, prototype, TypeInfo(DerivedArrayType, StructureFlags), info(), ArrayClass);
}
- void initializeSpeciesWatchpoint(ExecState*);
+ SpeciesWatchpointStatus speciesWatchpointStatus() const { return m_speciesWatchpointStatus; }
+ SpeciesWatchpointStatus attemptToInitializeSpeciesWatchpoint(ExecState*);
static const bool needsDestruction = false;
// We don't need destruction since we use a finalizer.
@@ -63,6 +64,7 @@
friend ArrayPrototypeAdaptiveInferredPropertyWatchpoint;
std::unique_ptr<ArrayPrototypeAdaptiveInferredPropertyWatchpoint> m_constructorWatchpoint;
std::unique_ptr<ArrayPrototypeAdaptiveInferredPropertyWatchpoint> m_constructorSpeciesWatchpoint;
+ SpeciesWatchpointStatus m_speciesWatchpointStatus { SpeciesWatchpointStatus::Uninitialized };
};
EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*);
Modified: trunk/Source/_javascript_Core/runtime/Intrinsic.h (210517 => 210518)
--- trunk/Source/_javascript_Core/runtime/Intrinsic.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/runtime/Intrinsic.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -40,7 +40,6 @@
TanIntrinsic,
ArrayPushIntrinsic,
ArrayPopIntrinsic,
- ArraySliceIntrinsic,
CharCodeAtIntrinsic,
CharAtIntrinsic,
FromCharCodeIntrinsic,
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (210517 => 210518)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-01-09 21:09:04 UTC (rev 210518)
@@ -332,7 +332,6 @@
, m_varInjectionWatchpoint(adoptRef(new WatchpointSet(IsWatched)))
, m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_arrayIteratorProtocolWatchpoint(IsWatched)
- , m_arraySpeciesWatchpoint(IsWatched)
, m_templateRegistry(vm)
, m_evalEnabled(true)
, m_runtimeFlags()
@@ -945,8 +944,6 @@
m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ArrayIteratorAdaptiveWatchpoint>(condition, this);
m_arrayPrototypeSymbolIteratorWatchpoint->install();
}
-
- this->arrayPrototype()->initializeSpeciesWatchpoint(exec);
}
resetPrototype(vm, getPrototypeDirect());
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (210517 => 210518)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-01-09 19:34:48 UTC (rev 210517)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-01-09 21:09:04 UTC (rev 210518)
@@ -399,11 +399,9 @@
WeakRandom m_weakRandom;
InlineWatchpointSet& arrayIteratorProtocolWatchpoint() { return m_arrayIteratorProtocolWatchpoint; }
- InlineWatchpointSet& arraySpeciesWatchpoint() { return m_arraySpeciesWatchpoint; }
// If this hasn't been invalidated, it means the array iterator protocol
// is not observable to user code yet.
InlineWatchpointSet m_arrayIteratorProtocolWatchpoint;
- InlineWatchpointSet m_arraySpeciesWatchpoint;
std::unique_ptr<ArrayIteratorAdaptiveWatchpoint> m_arrayPrototypeSymbolIteratorWatchpoint;
std::unique_ptr<ArrayIteratorAdaptiveWatchpoint> m_arrayIteratorPrototypeNext;