WebKit Bugzilla
Attachment 360242 Details for
Bug 193869
: [BigInt] Support constant fold of BigInts on DFG
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP - Patch
big-int-const-fold.diff (text/plain), 16.90 KB, created by
Caio Lima
on 2019-01-26 10:33:08 PST
(
hide
)
Description:
WIP - Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-01-26 10:33:08 PST
Size:
16.90 KB
patch
obsolete
>diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index 7581a1a7746..67ae353b956 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -258,6 +258,9 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case LazyJSValue::NewStringImpl: > setTypeForNode(node, SpecString); > break; >+ case LazyJSValue::NewBigIntAdd: >+ setTypeForNode(node, SpecBigInt); >+ break; > } > break; > } >diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h >index 151f5736c7a..828c5904d5b 100644 >--- a/Source/JavaScriptCore/dfg/DFGGraph.h >+++ b/Source/JavaScriptCore/dfg/DFGGraph.h >@@ -38,6 +38,7 @@ > #include "DFGPropertyTypeKey.h" > #include "DFGScannable.h" > #include "FullBytecodeLiveness.h" >+#include "DFGLazyJSValue.h" > #include "MethodOfGettingAValueProfile.h" > #include <wtf/BitVector.h> > #include <wtf/HashMap.h> >@@ -1066,6 +1067,7 @@ public: > unsigned m_parameterSlots; > > HashSet<String> m_localStrings; >+ Vector<LazyBigIntValue> m_localLazyBigInts; > HashMap<const StringImpl*, String> m_copiedStrings; > > #if USE(JSVALUE32_64) >diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >index 43bead62ff9..5653c4322f9 100644 >--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.cpp >@@ -30,6 +30,7 @@ > > #include "CCallHelpers.h" > #include "DFGGraph.h" >+#include "JSBigInt.h" > #include "JSCInlines.h" > #include "LinkBuffer.h" > >@@ -43,6 +44,20 @@ LazyJSValue LazyJSValue::newString(Graph& graph, const String& string) > return result; > } > >+LazyJSValue LazyJSValue::newBigInt(Graph& graph, LazyJSValue lhs, LazyJSValue rhs, LazyJSValue::BigIntOperationType opType) >+{ >+ LazyBigIntValue lazyBigInt; >+ lazyBigInt.left = lhs; >+ lazyBigInt.right = rhs; >+ lazyBigInt.opType = opType; >+ graph.m_localLazyBigInts.append(lazyBigInt); >+ >+ LazyJSValue result; >+ result.m_kind = NewBigIntAdd; >+ result.u.bigIntInfo = &graph.m_localLazyBigInts.last(); >+ return result; >+} >+ > JSValue LazyJSValue::getValue(VM& vm) const > { > switch (m_kind) { >@@ -54,6 +69,13 @@ JSValue LazyJSValue::getValue(VM& vm) const > return jsString(&vm, u.stringImpl); > case NewStringImpl: > return jsString(&vm, AtomicStringImpl::add(u.stringImpl)); >+ case NewBigIntAdd: { >+ JSValue leftValue = this->u.bigIntInfo->left.getValue(vm); >+ ASSERT(leftValue.isBigInt()); >+ JSValue rightValue = this->u.bigIntInfo->right.getValue(vm); >+ ASSERT(rightValue.isBigInt()); >+ return JSBigInt::uncheckedAdd(vm, asBigInt(leftValue), asBigInt(rightValue)); >+ } > } > RELEASE_ASSERT_NOT_REACHED(); > return JSValue(); >@@ -142,6 +164,8 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const > case KnownStringImpl: > case NewStringImpl: > return equalToStringImpl(value()->value(), other.stringImpl()); >+ case NewBigIntAdd: >+ return FalseTriState; > } > break; > case SingleCharacterString: >@@ -167,6 +191,8 @@ TriState LazyJSValue::strictEqual(const LazyJSValue& other) const > return other.strictEqual(*this); > } > break; >+ case NewBigIntAdd: >+ return FalseTriState; > } > RELEASE_ASSERT_NOT_REACHED(); > return FalseTriState; >@@ -258,6 +284,9 @@ void LazyJSValue::dumpInContext(PrintStream& out, DumpContext* context) const > case NewStringImpl: > out.print("Lazy:NewString(", stringImpl(), ")"); > return; >+ case NewBigIntAdd: >+ out.print("Lazy:NewBigIntAdd()"); >+ return; > } > RELEASE_ASSERT_NOT_REACHED(); > } >diff --git a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h >index 18bb5960fc3..b28888962c5 100644 >--- a/Source/JavaScriptCore/dfg/DFGLazyJSValue.h >+++ b/Source/JavaScriptCore/dfg/DFGLazyJSValue.h >@@ -38,6 +38,7 @@ class CCallHelpers; > namespace DFG { > > class Graph; >+class LazyBigIntValue; > > // Represents either a JSValue, or for JSValues that require allocation in the heap, > // it tells you everything you'd need to know in order to allocate it. >@@ -48,7 +49,12 @@ public: > KnownValue, > SingleCharacterString, > KnownStringImpl, >- NewStringImpl >+ NewStringImpl, >+ NewBigIntAdd >+ }; >+ >+ enum class BigIntOperationType { >+ Add > }; > > LazyJSValue(FrozenValue* value = FrozenValue::emptySingleton()) >@@ -74,6 +80,7 @@ public: > } > > static LazyJSValue newString(Graph&, const String&); >+ static LazyJSValue newBigInt(Graph&, LazyJSValue lhs, LazyJSValue rhs, BigIntOperationType); > > LazinessKind kind() const { return m_kind; } > >@@ -122,10 +129,18 @@ private: > FrozenValue* value; > UChar character; > StringImpl* stringImpl; >+ LazyBigIntValue* bigIntInfo; > } u; > LazinessKind m_kind; > }; > >+class LazyBigIntValue { >+public: >+ LazyJSValue left; >+ LazyJSValue right; >+ LazyJSValue::BigIntOperationType opType; >+}; >+ > } } // namespace JSC::DFG > > #endif // ENABLE(DFG_JIT) >diff --git a/Source/JavaScriptCore/dfg/DFGNode.cpp b/Source/JavaScriptCore/dfg/DFGNode.cpp >index 3d1c3ba1376..334385fe5cd 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.cpp >+++ b/Source/JavaScriptCore/dfg/DFGNode.cpp >@@ -309,6 +309,15 @@ String Node::tryGetString(Graph& graph) > return String(); > } > >+LazyJSValue Node::getLazyJSValue() >+{ >+ ASSERT(isConstantOrLazyConstant()); >+ if (hasConstant()) >+ return LazyJSValue(constant()); >+ if (hasLazyJSValue()) >+ return lazyJSValue(); >+} >+ > PromotedLocationDescriptor Node::promotedLocationDescriptor() > { > return PromotedLocationDescriptor(static_cast<PromotedLocationKind>(m_opInfo.as<uint32_t>()), m_opInfo2.as<uint32_t>()); >diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h >index 4c7deb6ad68..b0e69ff7457 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.h >+++ b/Source/JavaScriptCore/dfg/DFGNode.h >@@ -501,6 +501,11 @@ public: > } > } > >+ bool isConstantOrLazyConstant() >+ { >+ return isConstant() || hasLazyJSValue(); >+ } >+ > bool hasConstant() > { > switch (op()) { >@@ -880,6 +885,8 @@ public: > > String tryGetString(Graph&); > >+ LazyJSValue getLazyJSValue(); >+ > JSValue initializationValueForActivation() const > { > ASSERT(op() == CreateActivation); >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index d4a0a7aeee8..3810522fd28 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -1382,7 +1382,7 @@ JSCell* JIT_OPERATION operationAddBigInt(ExecState* exec, JSCell* op1, JSCell* o > JSBigInt* leftOperand = jsCast<JSBigInt*>(op1); > JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); > >- return JSBigInt::add(exec, leftOperand, rightOperand); >+ return JSBigInt::tryAdd(exec, leftOperand, rightOperand); > } > > JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell* op2) >diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >index 18bec693e2d..1607d750260 100644 >--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >@@ -375,8 +375,16 @@ private: > break; > } > >- if (m_node->binaryUseKind() == BigIntUse) >+ if (m_node->binaryUseKind() == BigIntUse) { >+ // handle constant propagation >+ if (m_node->child1()->isConstantOrLazyConstant() && m_node->child2()->isConstantOrLazyConstant()) { >+ // FIXME: Check if constant is a BigInt >+ convertToLazyJSValue(m_node, LazyJSValue::newBigInt(m_graph, m_node->child1()->getLazyJSValue(), m_node->child2()->getLazyJSValue(), LazyJSValue::BigIntOperationType::Add)); >+ m_changed = true; >+ break; >+ } > handleCommutativity(); >+ } > > break; > } >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.cpp b/Source/JavaScriptCore/runtime/JSBigInt.cpp >index 2bcaa9b6762..cc9f98f7fdf 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.cpp >+++ b/Source/JavaScriptCore/runtime/JSBigInt.cpp >@@ -90,17 +90,16 @@ inline size_t JSBigInt::allocationSize(unsigned length) > return sizeWithPadding + length * sizeof(Digit); > } > >-JSBigInt* JSBigInt::tryCreateWithLength(ExecState* exec, unsigned length) >+JSBigInt* JSBigInt::tryCreateWithLength(ExecState* exec, VM& vm, unsigned length) > { >- VM& vm = exec->vm(); >- auto scope = DECLARE_THROW_SCOPE(vm); >- >- if (UNLIKELY(length > maxLength)) { >- throwOutOfMemoryError(exec, scope); >- return nullptr; >- } >+ if (exec) { >+ auto scope = DECLARE_THROW_SCOPE(vm); > >- scope.release(); >+ if (UNLIKELY(length > maxLength)) { >+ throwOutOfMemoryError(exec, scope); >+ return nullptr; >+ } >+ } > > return createWithLengthUnchecked(vm, length); > } >@@ -248,7 +247,7 @@ JSBigInt* JSBigInt::multiply(ExecState* exec, JSBigInt* x, JSBigInt* y) > return y; > > unsigned resultLength = x->length() + y->length(); >- JSBigInt* result = JSBigInt::tryCreateWithLength(exec, resultLength); >+ JSBigInt* result = JSBigInt::tryCreateWithLength(exec, vm, resultLength); > RETURN_IF_EXCEPTION(scope, nullptr); > result->initialize(InitializationType::WithZero); > >@@ -352,15 +351,14 @@ JSBigInt* JSBigInt::remainder(ExecState* exec, JSBigInt* x, JSBigInt* y) > return remainder->rightTrim(vm); > } > >-JSBigInt* JSBigInt::add(ExecState* exec, JSBigInt* x, JSBigInt* y) >+JSBigInt* JSBigInt::add(ExecState* exec, VM& vm, JSBigInt* x, JSBigInt* y) > { >- VM& vm = exec->vm(); > bool xSign = x->sign(); > > // x + y == x + y > // -x + -y == -(x + y) > if (xSign == y->sign()) >- return absoluteAdd(exec, x, y, xSign); >+ return absoluteAdd(exec, vm, x, y, xSign); > > // x + -y == x - y == -(y - x) > // -x + y == y - x == -(x - y) >@@ -371,6 +369,19 @@ JSBigInt* JSBigInt::add(ExecState* exec, JSBigInt* x, JSBigInt* y) > return absoluteSub(vm, y, x, !xSign); > } > >+JSBigInt* JSBigInt::tryAdd(ExecState* exec, JSBigInt* x, JSBigInt* y) >+{ >+ VM& vm = exec->vm(); >+ return add(exec, vm, x, y); >+} >+ >+JSBigInt* JSBigInt::uncheckedAdd(VM& vm, JSBigInt* x, JSBigInt* y) >+{ >+ JSBigInt* result = add(nullptr, vm, x, y); >+ RELEASE_ASSERT(result); >+ return result; >+} >+ > JSBigInt* JSBigInt::sub(ExecState* exec, JSBigInt* x, JSBigInt* y) > { > VM& vm = exec->vm(); >@@ -378,7 +389,7 @@ JSBigInt* JSBigInt::sub(ExecState* exec, JSBigInt* x, JSBigInt* y) > if (xSign != y->sign()) { > // x - (-y) == x + y > // (-x) - y == -(x + y) >- return absoluteAdd(exec, x, y, xSign); >+ return absoluteAdd(exec, vm, x, y, xSign); > } > // x - y == -(y - x) > // (-x) - (-y) == y - x == -(x - y) >@@ -822,12 +833,10 @@ inline JSBigInt::ComparisonResult JSBigInt::absoluteCompare(JSBigInt* x, JSBigIn > return x->digit(i) > y->digit(i) ? ComparisonResult::GreaterThan : ComparisonResult::LessThan; > } > >-JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, JSBigInt* x, JSBigInt* y, bool resultSign) >+JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, VM& vm, JSBigInt* x, JSBigInt* y, bool resultSign) > { >- VM& vm = exec->vm(); >- > if (x->length() < y->length()) >- return absoluteAdd(exec, y, x, resultSign); >+ return absoluteAdd(exec, vm, y, x, resultSign); > > if (x->isZero()) { > ASSERT(y->isZero()); >@@ -837,7 +846,7 @@ JSBigInt* JSBigInt::absoluteAdd(ExecState* exec, JSBigInt* x, JSBigInt* y, bool > if (y->isZero()) > return resultSign == x->sign() ? x : unaryMinus(vm, x); > >- JSBigInt* result = JSBigInt::tryCreateWithLength(exec, x->length() + 1); >+ JSBigInt* result = JSBigInt::tryCreateWithLength(exec, vm, x->length() + 1); > if (!result) > return nullptr; > Digit carry = 0; >@@ -965,7 +974,7 @@ void JSBigInt::absoluteDivWithBigIntDivisor(ExecState* exec, JSBigInt* dividend, > > // In each iteration, {qhatv} holds {divisor} * {current quotient digit}. > // "v" is the book's name for {divisor}, "qhat" the current quotient digit. >- JSBigInt* qhatv = tryCreateWithLength(exec, n + 1); >+ JSBigInt* qhatv = tryCreateWithLength(exec, vm, n + 1); > RETURN_IF_EXCEPTION(scope, void()); > > // D1. >@@ -1119,7 +1128,7 @@ JSBigInt* JSBigInt::absoluteLeftShiftAlwaysCopy(ExecState* exec, JSBigInt* x, un > > unsigned n = x->length(); > unsigned resultLength = mode == LeftShiftMode::AlwaysAddOneDigit ? n + 1 : n; >- JSBigInt* result = tryCreateWithLength(exec, resultLength); >+ JSBigInt* result = tryCreateWithLength(exec, exec->vm(), resultLength); > if (!result) > return nullptr; > >@@ -1240,7 +1249,7 @@ JSBigInt* JSBigInt::absoluteAddOne(ExecState* exec, JSBigInt* x, SignOption sign > } > > unsigned resultLength = inputLength + willOverflow; >- JSBigInt* result = tryCreateWithLength(exec, resultLength); >+ JSBigInt* result = tryCreateWithLength(exec, exec->vm(), resultLength); > if (!result) > return nullptr; > >@@ -1266,7 +1275,7 @@ JSBigInt* JSBigInt::absoluteSubOne(ExecState* exec, JSBigInt* x, unsigned result > VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >- JSBigInt* result = tryCreateWithLength(exec, resultLength); >+ JSBigInt* result = tryCreateWithLength(exec, vm, resultLength); > RETURN_IF_EXCEPTION(scope, nullptr); > > unsigned length = x->length(); >@@ -1305,7 +1314,7 @@ JSBigInt* JSBigInt::leftShiftByAbsolute(ExecState* exec, JSBigInt* x, JSBigInt* > return nullptr; > } > >- JSBigInt* result = tryCreateWithLength(exec, resultLength); >+ JSBigInt* result = tryCreateWithLength(exec, vm, resultLength); > RETURN_IF_EXCEPTION(scope, nullptr); > if (!bitsShift) { > unsigned i = 0; >diff --git a/Source/JavaScriptCore/runtime/JSBigInt.h b/Source/JavaScriptCore/runtime/JSBigInt.h >index dbbf63ded1c..7a32e663007 100644 >--- a/Source/JavaScriptCore/runtime/JSBigInt.h >+++ b/Source/JavaScriptCore/runtime/JSBigInt.h >@@ -51,7 +51,7 @@ public: > > static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype); > static JSBigInt* createZero(VM&); >- static JSBigInt* tryCreateWithLength(ExecState*, unsigned length); >+ static JSBigInt* tryCreateWithLength(ExecState*, VM&, unsigned length); > static JSBigInt* createWithLengthUnchecked(VM&, unsigned length); > > static JSBigInt* createFrom(VM&, int32_t value); >@@ -115,12 +115,16 @@ public: > > ComparisonResult static compareToDouble(JSBigInt* x, double y); > >- static JSBigInt* add(ExecState*, JSBigInt* x, JSBigInt* y); >+ static JSBigInt* add(ExecState*, VM&, JSBigInt* x, JSBigInt* y); >+ >+ static JSBigInt* tryAdd(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* sub(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* divide(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* remainder(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* unaryMinus(VM&, JSBigInt* x); > >+ static JSBigInt* uncheckedAdd(VM&, JSBigInt* x, JSBigInt* y); >+ > static JSBigInt* bitwiseAnd(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* bitwiseOr(ExecState*, JSBigInt* x, JSBigInt* y); > static JSBigInt* bitwiseXor(ExecState*, JSBigInt* x, JSBigInt* y); >@@ -218,7 +222,7 @@ private: > JSBigInt* rightTrim(VM&); > > void inplaceMultiplyAdd(Digit multiplier, Digit part); >- static JSBigInt* absoluteAdd(ExecState*, JSBigInt* x, JSBigInt* y, bool resultSign); >+ static JSBigInt* absoluteAdd(ExecState*, VM&, JSBigInt* x, JSBigInt* y, bool resultSign); > static JSBigInt* absoluteSub(VM&, JSBigInt* x, JSBigInt* y, bool resultSign); > > static JSBigInt* leftShiftByAbsolute(ExecState*, JSBigInt* x, JSBigInt* y); >diff --git a/Source/JavaScriptCore/runtime/Operations.cpp b/Source/JavaScriptCore/runtime/Operations.cpp >index 836f953c3a8..87275f2e5da 100644 >--- a/Source/JavaScriptCore/runtime/Operations.cpp >+++ b/Source/JavaScriptCore/runtime/Operations.cpp >@@ -71,7 +71,7 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2) > if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { > if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { > scope.release(); >- return JSBigInt::add(callFrame, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); >+ return JSBigInt::tryAdd(callFrame, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); > } > > return throwTypeError(callFrame, scope, "Invalid mix of BigInt and other type in addition."_s);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 193869
: 360242