Skip to content

Commit

Permalink
Merge r228421 - Support GetArrayLength on ArrayStorage in the FTL
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=182625

Reviewed by Saam Barati.

JSTests:

* stress/array-storage-length.js: Added.
(shouldBe):
(testInBound):
(testUncountable):
(testSlowPutInBound):
(testSlowPutUncountable):
* stress/undecided-length.js: Added.
(shouldBe):
(test2):

Source/JavaScriptCore:

This patch adds GetArrayLength and CheckArray + ArrayStorage & SlowPutArrayStorage support for FTL.
The implementation is trivial; just porting one in DFG to FTL.

This fixes several FTL compilation failures in web-tooling-benchmarks while we still need to support
ArrayPush, ArrayPop, Arrayify, and PutByVal.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkArray):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
(JSC::FTL::DFG::LowerDFGToB3::isArrayTypeForArrayify):
(JSC::FTL::DFG::LowerDFGToB3::isArrayTypeForCheckArray):
  • Loading branch information
Constellation authored and carlosgcampos committed Feb 20, 2018
1 parent fbd872c commit b1a973e
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 18 deletions.
17 changes: 17 additions & 0 deletions JSTests/ChangeLog
@@ -1,3 +1,20 @@
2018-02-13 Yusuke Suzuki <utatane.tea@gmail.com>

Support GetArrayLength on ArrayStorage in the FTL
https://bugs.webkit.org/show_bug.cgi?id=182625

Reviewed by Saam Barati.

* stress/array-storage-length.js: Added.
(shouldBe):
(testInBound):
(testUncountable):
(testSlowPutInBound):
(testSlowPutUncountable):
* stress/undecided-length.js: Added.
(shouldBe):
(test2):

2018-02-16 Saam Barati <sbarati@apple.com>

Fix bugs from r228411
Expand Down
60 changes: 60 additions & 0 deletions JSTests/stress/array-storage-length.js
@@ -0,0 +1,60 @@
'use strict';

function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error('bad value: ' + actual);
}

var object = { a: 10 };
Object.defineProperties(object, {
"0": {
get: function() { return this.a; },
set: function(x) { this.a = x; },
},
});

var array = [ 0, 1, 2, 3, 4, 5 ];
ensureArrayStorage(array);

function testInBound(array)
{
return array.length;
}
noInline(testInBound);
for (var i = 0; i < 1e5; ++i)
shouldBe(testInBound(array), 6);

function testUncountable(array)
{
return array.length;
}
noInline(testUncountable);
for (var i = 0; i < 1e5; ++i)
shouldBe(testUncountable(array), 6);
array.length = 0xffffffff - 1;
for (var i = 0; i < 1e5; ++i)
shouldBe(testUncountable(array), 0xffffffff - 1);


var slowPutArray = [ 0, 1, 2, 3, 4, 5 ];
ensureArrayStorage(slowPutArray);
slowPutArray.__proto__ = object;

function testSlowPutInBound(array)
{
return array.length;
}
noInline(testSlowPutInBound);
for (var i = 0; i < 1e5; ++i)
shouldBe(testSlowPutInBound(slowPutArray), 6);

function testSlowPutUncountable(array)
{
return array.length;
}
noInline(testSlowPutUncountable);
for (var i = 0; i < 1e5; ++i)
shouldBe(testSlowPutUncountable(slowPutArray), 6);
slowPutArray.length = 0xffffffff - 1;
for (var i = 0; i < 1e5; ++i)
shouldBe(testSlowPutUncountable(slowPutArray), 0xffffffff - 1);
25 changes: 25 additions & 0 deletions JSTests/stress/undecided-length.js
@@ -0,0 +1,25 @@
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error('bad value: ' + actual);
}

var array = [];

function test1(array)
{
return array.length;
}
noInline(test1);
for (var i = 0; i < 1e5; ++i)
shouldBe(test1(array), 0);

var array = [];
array.ok = 42;

function test2(array)
{
return array.length;
}
noInline(test2);
for (var i = 0; i < 1e5; ++i)
shouldBe(test2(array), 0);
22 changes: 22 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,25 @@
2018-02-13 Yusuke Suzuki <utatane.tea@gmail.com>

Support GetArrayLength on ArrayStorage in the FTL
https://bugs.webkit.org/show_bug.cgi?id=182625

Reviewed by Saam Barati.

This patch adds GetArrayLength and CheckArray + ArrayStorage & SlowPutArrayStorage support for FTL.
The implementation is trivial; just porting one in DFG to FTL.

This fixes several FTL compilation failures in web-tooling-benchmarks while we still need to support
ArrayPush, ArrayPop, Arrayify, and PutByVal.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkArray):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
(JSC::FTL::DFG::LowerDFGToB3::isArrayTypeForArrayify):
(JSC::FTL::DFG::LowerDFGToB3::isArrayTypeForCheckArray):

2018-02-10 Filip Pizlo <fpizlo@apple.com>

Lock down JSFunction
Expand Down
18 changes: 1 addition & 17 deletions Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Expand Up @@ -822,13 +822,11 @@ void SpeculativeJIT::checkArray(Node* node)
return;
}

const ClassInfo* expectedClassInfo = 0;

switch (node->arrayMode().type()) {
case Array::AnyTypedArray:
case Array::String:
RELEASE_ASSERT_NOT_REACHED(); // Should have been a Phantom(String:)
break;
return;
case Array::Int32:
case Array::Double:
case Array::Contiguous:
Expand Down Expand Up @@ -860,20 +858,6 @@ void SpeculativeJIT::checkArray(Node* node)
noResult(m_currentNode);
return;
}

RELEASE_ASSERT(expectedClassInfo);

GPRTemporary temp(this);
GPRTemporary temp2(this);
m_jit.emitLoadStructure(*m_jit.vm(), baseReg, temp.gpr(), temp2.gpr());
speculationCheck(
BadType, JSValueSource::unboxedCell(baseReg), node,
m_jit.branchPtr(
MacroAssembler::NotEqual,
MacroAssembler::Address(temp.gpr(), Structure::classInfoOffset()),
TrustedImmPtr(PoisonedClassInfoPtr(expectedClassInfo).bits())));

noResult(m_currentNode);
}

void SpeculativeJIT::arrayify(Node* node, GPRReg baseReg, GPRReg propertyReg)
Expand Down
5 changes: 5 additions & 0 deletions Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Expand Up @@ -355,6 +355,9 @@ inline CapabilityLevel canCompile(Node* node)
case Array::Int32:
case Array::Double:
case Array::Contiguous:
case Array::Undecided:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage:
case Array::DirectArguments:
case Array::ScopedArguments:
break;
Expand All @@ -370,6 +373,8 @@ inline CapabilityLevel canCompile(Node* node)
case Array::Int32:
case Array::Double:
case Array::Contiguous:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage:
case Array::String:
case Array::DirectArguments:
case Array::ScopedArguments:
Expand Down
16 changes: 15 additions & 1 deletion Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Expand Up @@ -3644,6 +3644,14 @@ class LowerDFGToB3 {
setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
return;
}

case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
LValue length = m_out.load32(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength);
speculate(Uncountable, noValue(), nullptr, m_out.lessThan(length, m_out.int32Zero));
setInt32(length);
return;
}

case Array::String: {
LValue string = lowCell(m_node->child1());
Expand Down Expand Up @@ -14540,7 +14548,10 @@ class LowerDFGToB3 {
switch (arrayMode.type()) {
case Array::Int32:
case Array::Double:
case Array::Contiguous: {
case Array::Contiguous:
case Array::Undecided:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage: {
IndexingType shape = arrayMode.shapeMask();
LValue indexingType = m_out.load8ZeroExt32(cell, m_heaps.JSCell_indexingTypeAndMisc);

Expand Down Expand Up @@ -14580,6 +14591,9 @@ class LowerDFGToB3 {
case Array::Int32:
case Array::Double:
case Array::Contiguous:
case Array::Undecided:
case Array::ArrayStorage:
case Array::SlowPutArrayStorage:
return isArrayTypeForArrayify(cell, arrayMode);

case Array::DirectArguments:
Expand Down

0 comments on commit b1a973e

Please sign in to comment.