Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (239098 => 239099)
--- trunk/Source/_javascript_Core/ChangeLog 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-12-12 08:38:45 UTC (rev 239099)
@@ -1,3 +1,30 @@
+2018-12-11 Yusuke Suzuki <[email protected]>
+
+ [BigInt] Simplify boolean context evaluation by leveraging JSString::offsetOfLength() == JSBigInt::offsetOfLength()
+ https://bugs.webkit.org/show_bug.cgi?id=192615
+
+ Reviewed by Saam Barati.
+
+ JSString and JSBigInt have similar concept in terms of the implementation.
+ Both are immutable, JSCells, and have length information. m_length is located
+ just after JSCell header part, we can ensure `JSString::offsetOfLength() == JSBigInt::offsetOfLength()`,
+ and it allows us to optimize the boolean context evaluation.
+
+ This patch leverages the above information to reduce the code size for the boolean context evaluation.
+
+ * ftl/FTLAbstractHeapRepository.cpp:
+ (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
+ * ftl/FTLAbstractHeapRepository.h:
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::boolify):
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::emitConvertValueToBoolean):
+ (JSC::AssemblyHelpers::branchIfValue):
+ * runtime/JSBigInt.cpp:
+ (JSC::JSBigInt::JSBigInt):
+ (JSC::JSBigInt::offsetOfLength): Deleted.
+ * runtime/JSBigInt.h:
+
2018-12-11 Justin Michaud <[email protected]>
Implement feature flag for CSS Typed OM
Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp (239098 => 239099)
--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp 2018-12-12 08:38:45 UTC (rev 239099)
@@ -61,6 +61,8 @@
, JSCell_freeListNext(JSCell_header)
, ArrayStorage_publicLength(Butterfly_publicLength)
, ArrayStorage_vectorLength(Butterfly_vectorLength)
+ , JSBigInt_length(JSBigIntOrString_length)
+ , JSString_length(JSBigIntOrString_length)
#define INDEXED_ABSTRACT_HEAP_INITIALIZATION(name, offset, size) , name(&root, #name, offset, size)
FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_INITIALIZATION)
@@ -78,6 +80,8 @@
RELEASE_ASSERT(JSCell_indexingTypeAndMisc.offset() + 2 == JSCell_typeInfoFlags.offset());
RELEASE_ASSERT(JSCell_indexingTypeAndMisc.offset() + 3 == JSCell_cellState.offset());
+ RELEASE_ASSERT(JSBigInt::offsetOfLength() == JSString::offsetOfLength());
+
JSCell_structureID.changeParent(&JSCell_header);
JSCell_usefulBytes.changeParent(&JSCell_header);
JSCell_indexingTypeAndMisc.changeParent(&JSCell_usefulBytes);
Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (239098 => 239099)
--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2018-12-12 08:38:45 UTC (rev 239099)
@@ -63,6 +63,7 @@
macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \
macro(JSArrayBufferView_mode, JSArrayBufferView::offsetOfMode()) \
macro(JSArrayBufferView_vector, JSArrayBufferView::offsetOfVector()) \
+ macro(JSBigIntOrString_length, JSBigInt::offsetOfLength()) \
macro(JSCell_cellState, JSCell::cellStateOffset()) \
macro(JSCell_header, 0) \
macro(JSCell_indexingTypeAndMisc, JSCell::indexingTypeAndMiscOffset()) \
@@ -83,9 +84,7 @@
macro(JSPropertyNameEnumerator_indexLength, JSPropertyNameEnumerator::indexedLengthOffset()) \
macro(JSScope_next, JSScope::offsetOfNext()) \
macro(JSString_flags, JSString::offsetOfFlags()) \
- macro(JSString_length, JSString::offsetOfLength()) \
macro(JSString_value, JSString::offsetOfValue()) \
- macro(JSBigInt_length, JSBigInt::offsetOfLength()) \
macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
macro(RegExpConstructor_cachedResult_lastRegExp, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastRegExp()) \
@@ -178,6 +177,8 @@
AbstractHeap& JSCell_freeListNext;
AbstractHeap& ArrayStorage_publicLength;
AbstractHeap& ArrayStorage_vectorLength;
+ AbstractHeap& JSBigInt_length;
+ AbstractHeap& JSString_length;
#define INDEXED_ABSTRACT_HEAP_DECLARATION(name, offset, size) IndexedAbstractHeap name;
FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_DECLARATION)
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (239098 => 239099)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-12-12 08:38:45 UTC (rev 239099)
@@ -13605,10 +13605,9 @@
// }
LBasicBlock cellCase = m_out.newBlock();
- LBasicBlock stringCase = m_out.newBlock();
LBasicBlock notStringCase = m_out.newBlock();
- LBasicBlock bigIntCase = m_out.newBlock();
- LBasicBlock notBigIntCase = m_out.newBlock();
+ LBasicBlock stringOrBigIntCase = m_out.newBlock();
+ LBasicBlock notStringOrBigIntCase = m_out.newBlock();
LBasicBlock notCellCase = m_out.newBlock();
LBasicBlock int32Case = m_out.newBlock();
LBasicBlock notInt32Case = m_out.newBlock();
@@ -13620,29 +13619,23 @@
m_out.branch(isCell(value, provenType(edge)), unsure(cellCase), unsure(notCellCase));
- LBasicBlock lastNext = m_out.appendTo(cellCase, stringCase);
+ LBasicBlock lastNext = m_out.appendTo(cellCase, notStringCase);
m_out.branch(
isString(value, provenType(edge) & SpecCell),
- unsure(stringCase), unsure(notStringCase));
+ unsure(stringOrBigIntCase), unsure(notStringCase));
- m_out.appendTo(stringCase, notStringCase);
- LValue nonEmptyString = m_out.notZero32(
- m_out.load32NonNegative(value, m_heaps.JSString_length));
- results.append(m_out.anchor(nonEmptyString));
- m_out.jump(continuation);
-
- m_out.appendTo(notStringCase, bigIntCase);
+ m_out.appendTo(notStringCase, stringOrBigIntCase);
m_out.branch(
isBigInt(value, provenType(edge) & SpecCell),
- unsure(bigIntCase), unsure(notBigIntCase));
+ unsure(stringOrBigIntCase), unsure(notStringOrBigIntCase));
- m_out.appendTo(bigIntCase, notBigIntCase);
- LValue nonZeroBigInt = m_out.notZero32(
- m_out.load32NonNegative(value, m_heaps.JSBigInt_length));
- results.append(m_out.anchor(nonZeroBigInt));
+ m_out.appendTo(stringOrBigIntCase, notStringOrBigIntCase);
+ LValue nonZeroCell = m_out.notZero32(
+ m_out.load32NonNegative(value, m_heaps.JSBigIntOrString_length));
+ results.append(m_out.anchor(nonZeroCell));
m_out.jump(continuation);
- m_out.appendTo(notBigIntCase, notCellCase);
+ m_out.appendTo(notStringOrBigIntCase, notCellCase);
LValue isTruthyObject;
if (masqueradesAsUndefinedWatchpointIsStillValid())
isTruthyObject = m_out.booleanTrue;
Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp (239098 => 239099)
--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2018-12-12 08:38:45 UTC (rev 239099)
@@ -775,18 +775,9 @@
JumpList done;
auto notCell = branchIfNotCell(value);
- auto isCellButNotString = branchIfNotString(value.payloadGPR());
- load32(Address(value.payloadGPR(), JSString::offsetOfLength()), result);
- compare32(invert ? Equal : NotEqual, result, TrustedImm32(0), result);
- done.append(jump());
+ auto isString = branchIfString(value.payloadGPR());
+ auto isBigInt = branchIfBigInt(value.payloadGPR());
- isCellButNotString.link(this);
- auto isCellButNotBigIntOrString = branchIfNotBigInt(value.payloadGPR());
- load32(Address(value.payloadGPR(), JSBigInt::offsetOfLength()), result);
- compare32(invert ? Equal : NotEqual, result, TrustedImm32(0), result);
- done.append(jump());
-
- isCellButNotBigIntOrString.link(this);
if (shouldCheckMasqueradesAsUndefined) {
ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg);
JumpList isNotMasqueradesAsUndefined;
@@ -803,6 +794,13 @@
move(invert ? TrustedImm32(0) : TrustedImm32(1), result);
done.append(jump());
+ isString.link(this);
+ isBigInt.link(this);
+ RELEASE_ASSERT(JSString::offsetOfLength() == JSBigInt::offsetOfLength());
+ load32(Address(value.payloadGPR(), JSBigInt::offsetOfLength()), result);
+ compare32(invert ? Equal : NotEqual, result, TrustedImm32(0), result);
+ done.append(jump());
+
notCell.link(this);
auto notInt32 = branchIfNotInt32(value);
compare32(invert ? Equal : NotEqual, value.payloadGPR(), TrustedImm32(0), result);
@@ -855,16 +853,10 @@
JumpList truthy;
auto notCell = branchIfNotCell(value);
- auto isCellButNotString = branchIfNotString(value.payloadGPR());
- truthy.append(branchTest32(invert ? Zero : NonZero, Address(value.payloadGPR(), JSString::offsetOfLength())));
- done.append(jump());
- isCellButNotString.link(this);
- auto isCellButNotBigIntOrString = branchIfNotBigInt(value.payloadGPR());
- truthy.append(branchTest32(invert ? Zero : NonZero, Address(value.payloadGPR(), JSBigInt::offsetOfLength())));
- done.append(jump());
+ auto isString = branchIfString(value.payloadGPR());
+ auto isBigInt = branchIfBigInt(value.payloadGPR());
if (shouldCheckMasqueradesAsUndefined) {
- isCellButNotBigIntOrString.link(this);
ASSERT(scratchIfShouldCheckMasqueradesAsUndefined != InvalidGPRReg);
JumpList isNotMasqueradesAsUndefined;
isNotMasqueradesAsUndefined.append(branchTest8(Zero, Address(value.payloadGPR(), JSCell::typeInfoFlagsOffset()), TrustedImm32(MasqueradesAsUndefined)));
@@ -884,11 +876,17 @@
truthy.append(isNotMasqueradesAsUndefined);
} else {
if (invert)
- done.append(isCellButNotBigIntOrString);
+ done.append(jump());
else
- truthy.append(isCellButNotBigIntOrString);
+ truthy.append(jump());
}
+ isString.link(this);
+ isBigInt.link(this);
+ RELEASE_ASSERT(JSString::offsetOfLength() == JSBigInt::offsetOfLength());
+ truthy.append(branchTest32(invert ? Zero : NonZero, Address(value.payloadGPR(), JSBigInt::offsetOfLength())));
+ done.append(jump());
+
notCell.link(this);
auto notInt32 = branchIfNotInt32(value);
truthy.append(branchTest32(invert ? Zero : NonZero, value.payloadGPR()));
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.cpp (239098 => 239099)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.cpp 2018-12-12 08:38:45 UTC (rev 239099)
@@ -65,7 +65,6 @@
JSBigInt::JSBigInt(VM& vm, Structure* structure, unsigned length)
: Base(vm, structure)
, m_length(length)
- , m_sign(false)
{ }
void JSBigInt::initialize(InitializationType initType)
@@ -1694,11 +1693,6 @@
return WTF::roundUpToMultipleOf<sizeof(Digit)>(sizeof(JSBigInt));
}
-size_t JSBigInt::offsetOfLength()
-{
- return OBJECT_OFFSETOF(JSBigInt, m_length);
-}
-
template <typename CharType>
JSBigInt* JSBigInt::parseInt(ExecState* exec, CharType* data, unsigned length, ErrorParseMode errorParseMode)
{
Modified: trunk/Source/_javascript_Core/runtime/JSBigInt.h (239098 => 239099)
--- trunk/Source/_javascript_Core/runtime/JSBigInt.h 2018-12-12 05:54:17 UTC (rev 239098)
+++ trunk/Source/_javascript_Core/runtime/JSBigInt.h 2018-12-12 08:38:45 UTC (rev 239099)
@@ -58,7 +58,10 @@
static JSBigInt* createFrom(VM&, int64_t value);
static JSBigInt* createFrom(VM&, bool value);
- static size_t offsetOfLength();
+ static size_t offsetOfLength()
+ {
+ return OBJECT_OFFSETOF(JSBigInt, m_length);
+ }
DECLARE_EXPORT_INFO;
@@ -232,7 +235,7 @@
void setDigit(unsigned, Digit);
unsigned m_length;
- bool m_sign;
+ bool m_sign { false };
};
inline JSBigInt* asBigInt(JSValue value)