Skip to content

Commit

Permalink
Merge r228727 - [FTL] Support ArrayPop for ArrayStorage
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=182783

Reviewed by Saam Barati.

JSTests:

* stress/array-pop-array-storage.js: Added.
(shouldBe):
(test):

Source/JavaScriptCore:

This patch adds ArrayPop(ArrayStorage) support to FTL. We port the implementation in DFG to FTL.

* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArrayPop):
  • Loading branch information
Constellation authored and carlosgcampos committed Feb 26, 2018
1 parent 08abb10 commit 6d62173
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 1 deletion.
11 changes: 11 additions & 0 deletions JSTests/ChangeLog
@@ -1,3 +1,14 @@
2018-02-14 Yusuke Suzuki <utatane.tea@gmail.com>

[FTL] Support ArrayPop for ArrayStorage
https://bugs.webkit.org/show_bug.cgi?id=182783

Reviewed by Saam Barati.

* stress/array-pop-array-storage.js: Added.
(shouldBe):
(test):

2018-02-14 Yusuke Suzuki <utatane.tea@gmail.com>

[FTL] Add Arrayify for ArrayStorage and SlowPutArrayStorage
Expand Down
65 changes: 65 additions & 0 deletions JSTests/stress/array-pop-array-storage.js
@@ -0,0 +1,65 @@
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error('bad value: ' + actual);
}

function test(array) {
return [array.pop(), array.pop(), array.pop(), array.pop()];
}

noInline(test);

for (var i = 0; i < 1e4; ++i) {
var array = ["foo", "bar", "baz"];
ensureArrayStorage(array);
var result = test(array);
shouldBe(result[0], "baz");
shouldBe(result[1], "bar");
shouldBe(result[2], "foo");
shouldBe(result[3], undefined);
shouldBe(array.length, 0);
}

for (var i = 0; i < 1e4; ++i) {
var array = ["foo", "bar", , "baz"];
ensureArrayStorage(array);
var result = test(array);
shouldBe(result[0], "baz");
shouldBe(result[1], undefined);
shouldBe(result[2], "bar");
shouldBe(result[3], "foo");
shouldBe(array.length, 0);
}

for (var i = 0; i < 1e4; ++i) {
var array = ["foo", "bar", , "baz", , , "OK"];
ensureArrayStorage(array);
shouldBe(array.length, 7);
var result = test(array);
shouldBe(result[0], "OK");
shouldBe(result[1], undefined);
shouldBe(result[2], undefined);
shouldBe(result[3], "baz");
shouldBe(array.length, 3);
shouldBe(array[0], "foo");
shouldBe(array[1], "bar");
shouldBe(array[2], undefined);
shouldBe(array[3], undefined);
}

for (var i = 0; i < 1e4; ++i) {
var array = ["foo", "bar", "baz"];
ensureArrayStorage(array);
array.length = 0xffffffff - 1;
shouldBe(array.length, 0xffffffff - 1);
var result = test(array);
shouldBe(result[0], undefined);
shouldBe(result[1], undefined);
shouldBe(result[2], undefined);
shouldBe(result[3], undefined);
shouldBe(array.length, 0xffffffff - 5);
shouldBe(array[0], "foo");
shouldBe(array[1], "bar");
shouldBe(array[2], "baz");
shouldBe(array[3], undefined);
}
15 changes: 15 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
2018-02-14 Yusuke Suzuki <utatane.tea@gmail.com>

[FTL] Support ArrayPop for ArrayStorage
https://bugs.webkit.org/show_bug.cgi?id=182783

Reviewed by Saam Barati.

This patch adds ArrayPop(ArrayStorage) support to FTL. We port the implementation in DFG to FTL.

* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileArrayPop):

2018-02-14 Yusuke Suzuki <utatane.tea@gmail.com>

[FTL] Add Arrayify for ArrayStorage and SlowPutArrayStorage
Expand Down
1 change: 1 addition & 0 deletions Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
Expand Up @@ -45,6 +45,7 @@ namespace JSC { namespace FTL {

#define FOR_EACH_ABSTRACT_FIELD(macro) \
macro(ArrayBuffer_data, ArrayBuffer::offsetOfData()) \
macro(ArrayStorage_numValuesInVector, ArrayStorage::numValuesInVectorOffset()) \
macro(Butterfly_arrayBuffer, Butterfly::offsetOfArrayBuffer()) \
macro(Butterfly_publicLength, Butterfly::offsetOfPublicLength()) \
macro(Butterfly_vectorLength, Butterfly::offsetOfVectorLength()) \
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Expand Up @@ -318,6 +318,7 @@ inline CapabilityLevel canCompile(Node* node)
case CallDOMGetter:
case ArraySlice:
case ArrayIndexOf:
case ArrayPop:
case ParseInt:
case AtomicsAdd:
case AtomicsAnd:
Expand Down Expand Up @@ -437,7 +438,6 @@ inline CapabilityLevel canCompile(Node* node)
case PutByValWithThis:
break;
case ArrayPush:
case ArrayPop:
switch (node->arrayMode().type()) {
case Array::Int32:
case Array::Contiguous:
Expand Down
43 changes: 43 additions & 0 deletions Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Expand Up @@ -4748,6 +4748,49 @@ class LowerDFGToB3 {
return;
}

case Array::ArrayStorage: {
LBasicBlock vectorLengthCheckCase = m_out.newBlock();
LBasicBlock popCheckCase = m_out.newBlock();
LBasicBlock fastCase = m_out.newBlock();
LBasicBlock slowCase = m_out.newBlock();
LBasicBlock continuation = m_out.newBlock();

LValue prevLength = m_out.load32(storage, m_heaps.Butterfly_publicLength);

Vector<ValueFromBlock, 3> results;
results.append(m_out.anchor(m_out.constInt64(JSValue::encode(jsUndefined()))));
m_out.branch(
m_out.isZero32(prevLength), rarely(continuation), usually(vectorLengthCheckCase));

LBasicBlock lastNext = m_out.appendTo(vectorLengthCheckCase, popCheckCase);
LValue newLength = m_out.sub(prevLength, m_out.int32One);
m_out.branch(
m_out.aboveOrEqual(newLength, m_out.load32(storage, m_heaps.Butterfly_vectorLength)), rarely(slowCase), usually(popCheckCase));

m_out.appendTo(popCheckCase, fastCase);
TypedPointer pointer = m_out.baseIndex(m_heaps.ArrayStorage_vector, storage, m_out.zeroExtPtr(newLength));
LValue result = m_out.load64(pointer);
m_out.branch(m_out.notZero64(result), usually(fastCase), rarely(slowCase));

m_out.appendTo(fastCase, slowCase);
m_out.store32(newLength, storage, m_heaps.Butterfly_publicLength);
m_out.store64(m_out.int64Zero, pointer);
m_out.store32(
m_out.sub(m_out.load32(storage, m_heaps.ArrayStorage_numValuesInVector), m_out.int32One),
storage, m_heaps.ArrayStorage_numValuesInVector);
results.append(m_out.anchor(result));
m_out.jump(continuation);

m_out.appendTo(slowCase, continuation);
results.append(m_out.anchor(vmCall(
Int64, m_out.operation(operationArrayPop), m_callFrame, base)));
m_out.jump(continuation);

m_out.appendTo(continuation, lastNext);
setJSValue(m_out.phi(Int64, results));
return;
}

default:
DFG_CRASH(m_graph, m_node, "Bad array type");
return;
Expand Down

0 comments on commit 6d62173

Please sign in to comment.