WebKit Bugzilla
Attachment 340466 Details for
Bug 185670
: Constant fold CheckTypeInfoFlags on ImplementsDefaultHasInstance
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch
c-backup.diff (text/plain), 30.04 KB, created by
Saam Barati
on 2018-05-15 20:09:26 PDT
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2018-05-15 20:09:26 PDT
Size:
30.04 KB
patch
obsolete
>Index: JSTests/ChangeLog >=================================================================== >--- JSTests/ChangeLog (revision 231834) >+++ JSTests/ChangeLog (working copy) >@@ -1,3 +1,39 @@ >+2018-05-15 Saam Barati <sbarati@apple.com> >+ >+ Constant fold CheckTypeInfoFlags on ImplementsDefaultHasInstance >+ https://bugs.webkit.org/show_bug.cgi?id=185670 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * microbenchmarks/constant-fold-check-type-info-flags.js: Added. >+ (clobber): >+ (C): >+ (D): >+ (foo): >+ (access): >+ (theClass): >+ * stress/dont-constant-fold-check-type-info-on-bound-function.js: Added. >+ (C): >+ (foo): >+ >+2018-05-15 Saam Barati <sbarati@apple.com> >+ >+ OverridesHasInstance should not rely on OSR exit information and should be in ConstantFoldingPhase >+ https://bugs.webkit.org/show_bug.cgi?id=154832 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * microbenchmarks/constant-fold-check-type-info-flags.js: Added. >+ (clobber): >+ (C): >+ (D): >+ (foo): >+ (access): >+ (theClass): >+ * stress/dont-constant-fold-check-type-info-on-bound-function.js: Added. >+ (C): >+ (foo): >+ > 2018-05-14 Leo Balter <leonardo.balter@gmail.com> > > Fix a legacy CRLF eol from Test262 >Index: JSTests/microbenchmarks/constant-fold-check-type-info-flags.js >=================================================================== >--- JSTests/microbenchmarks/constant-fold-check-type-info-flags.js (nonexistent) >+++ JSTests/microbenchmarks/constant-fold-check-type-info-flags.js (working copy) >@@ -0,0 +1,41 @@ >+"use strict"; >+ >+function clobber() { } >+noInline(clobber); >+ >+class C { } >+class D { } >+ >+function foo(x, C) { >+ clobber(); >+ return x instanceof C; >+} >+noInline(foo); >+ >+function access(o) { >+ return o.foo0; >+} >+noInline(access); >+ >+function theClass(i) { >+ if (i & 1) >+ return C; >+ return D; >+} >+noInline(theClass); >+ >+let x = new C; >+for (let i = 0; i < 1000; ++i) { >+ let k = theClass(i); >+ if (i < 20) >+ k["foo" + i] = i; >+ if (i >= 20) >+ access(k); >+ if (i === 100) >+ k["foo" + i] = i; >+ let result = foo(x, k); >+ if (k === C && result !== true) >+ throw new Error("Bad") >+ if (k !== C && result !== false) >+ throw new Error("Bad") >+} >Index: JSTests/stress/dont-constant-fold-check-type-info-on-bound-function.js >=================================================================== >--- JSTests/stress/dont-constant-fold-check-type-info-on-bound-function.js (nonexistent) >+++ JSTests/stress/dont-constant-fold-check-type-info-on-bound-function.js (working copy) >@@ -0,0 +1,17 @@ >+"use strict"; >+ >+class C { } >+let x = new C; >+C = C.bind(this); >+ >+function foo(x) { >+ x.foo; >+ return x instanceof C; >+} >+noInline(foo); >+ >+for (let i = 0; i < 1000; ++i) { >+ let r = foo(x); >+ if (r !== true) >+ throw new Error("Bad") >+} >Index: Source/JavaScriptCore/ChangeLog >=================================================================== >--- Source/JavaScriptCore/ChangeLog (revision 231819) >+++ Source/JavaScriptCore/ChangeLog (working copy) >@@ -1,3 +1,41 @@ >+2018-05-15 Saam Barati <sbarati@apple.com> >+ >+ Constant fold CheckTypeInfoFlags on ImplementsDefaultHasInstance >+ https://bugs.webkit.org/show_bug.cgi?id=185670 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch makes it so that we constant fold CheckTypeInfoFlags for >+ ImplementsDefaultHasInstance inside of AI/constant folding. We constant >+ fold in three ways: >+ - When the incoming value is a constant, we just look at its inline type >+ flags. Since those flags never change after an object is created, this >+ is sound. >+ - Based on the incoming value having a finite structure set. We just iterate >+ all structures and ensure they have the bit set. >+ - Based on speculated type. To do this, I split up SpecFunction into two >+ subheaps where one is for functions that have the bit set, and one for >+ functions that don't have the bit set. The latter is currently only comprised >+ of JSBoundFunctions. To constant fold, we check that the incoming >+ value only has the SpecFunction type with ImplementsDefaultHasInstance set. >+ >+ * bytecode/SpeculatedType.cpp: >+ (JSC::speculationFromClassInfo): >+ * bytecode/SpeculatedType.h: >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ * dfg/DFGConstantFoldingPhase.cpp: >+ (JSC::DFG::ConstantFoldingPhase::foldConstants): >+ * dfg/DFGStrengthReductionPhase.cpp: >+ (JSC::DFG::StrengthReductionPhase::handleNode): >+ * runtime/JSFunction.cpp: >+ (JSC::JSFunction::JSFunction): >+ (JSC::JSFunction::assertTypeInfoFlagInvariants): >+ * runtime/JSFunction.h: >+ (JSC::JSFunction::assertTypeInfoFlagInvariants): >+ * runtime/JSFunctionInlines.h: >+ (JSC::JSFunction::JSFunction): >+ > 2018-05-15 Devin Rousso <webkit@devinrousso.com> > > Web Inspector: Add rulers and guides >Index: Source/JavaScriptCore/bytecode/SpeculatedType.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/SpeculatedType.cpp (revision 231813) >+++ Source/JavaScriptCore/bytecode/SpeculatedType.cpp (working copy) >@@ -34,6 +34,7 @@ > #include "JSBigInt.h" > #include "JSCInlines.h" > #include "JSFunction.h" >+#include "JSBoundFunction.h" > #include "JSMap.h" > #include "JSSet.h" > #include "JSWeakMap.h" >@@ -432,8 +433,11 @@ SpeculatedType speculationFromClassInfo( > if (classInfo == ProxyObject::info()) > return SpecProxyObject; > >- if (classInfo->isSubClassOf(JSFunction::info())) >- return SpecFunction; >+ if (classInfo->isSubClassOf(JSFunction::info())) { >+ if (classInfo == JSBoundFunction::info()) >+ return SpecFunctionWithNonDefaultHasInstance; >+ return SpecFunctionWithDefaultHasInstance; >+ } > > if (isTypedView(classInfo->typedArrayStorageType)) > return speculationFromTypedArrayType(classInfo->typedArrayStorageType); >Index: Source/JavaScriptCore/bytecode/SpeculatedType.h >=================================================================== >--- Source/JavaScriptCore/bytecode/SpeculatedType.h (revision 231813) >+++ Source/JavaScriptCore/bytecode/SpeculatedType.h (working copy) >@@ -38,64 +38,66 @@ namespace JSC { > class Structure; > > typedef uint64_t SpeculatedType; >-static const SpeculatedType SpecNone = 0; // We don't know anything yet. >-static const SpeculatedType SpecFinalObject = 1ull << 0; // It's definitely a JSFinalObject. >-static const SpeculatedType SpecArray = 1ull << 1; // It's definitely a JSArray. >-static const SpeculatedType SpecFunction = 1ull << 2; // It's definitely a JSFunction. >-static const SpeculatedType SpecInt8Array = 1ull << 3; // It's definitely an Int8Array or one of its subclasses. >-static const SpeculatedType SpecInt16Array = 1ull << 4; // It's definitely an Int16Array or one of its subclasses. >-static const SpeculatedType SpecInt32Array = 1ull << 5; // It's definitely an Int32Array or one of its subclasses. >-static const SpeculatedType SpecUint8Array = 1ull << 6; // It's definitely an Uint8Array or one of its subclasses. >-static const SpeculatedType SpecUint8ClampedArray = 1ull << 7; // It's definitely an Uint8ClampedArray or one of its subclasses. >-static const SpeculatedType SpecUint16Array = 1ull << 8; // It's definitely an Uint16Array or one of its subclasses. >-static const SpeculatedType SpecUint32Array = 1ull << 9; // It's definitely an Uint32Array or one of its subclasses. >-static const SpeculatedType SpecFloat32Array = 1ull << 10; // It's definitely an Uint16Array or one of its subclasses. >-static const SpeculatedType SpecFloat64Array = 1ull << 11; // It's definitely an Uint16Array or one of its subclasses. >-static const SpeculatedType SpecTypedArrayView = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array; >-static const SpeculatedType SpecDirectArguments = 1ull << 12; // It's definitely a DirectArguments object. >-static const SpeculatedType SpecScopedArguments = 1ull << 13; // It's definitely a ScopedArguments object. >-static const SpeculatedType SpecStringObject = 1ull << 14; // It's definitely a StringObject. >-static const SpeculatedType SpecRegExpObject = 1ull << 15; // It's definitely a RegExpObject (and not any subclass of RegExpObject). >-static const SpeculatedType SpecMapObject = 1ull << 16; // It's definitely a Map object or one of its subclasses. >-static const SpeculatedType SpecSetObject = 1ull << 17; // It's definitely a Set object or one of its subclasses. >-static const SpeculatedType SpecWeakMapObject = 1ull << 18; // It's definitely a WeakMap object or one of its subclasses. >-static const SpeculatedType SpecWeakSetObject = 1ull << 19; // It's definitely a WeakSet object or one of its subclasses. >-static const SpeculatedType SpecProxyObject = 1ull << 20; // It's definitely a Proxy object or one of its subclasses. >-static const SpeculatedType SpecDerivedArray = 1ull << 21; // It's definitely a DerivedArray object. >-static const SpeculatedType SpecObjectOther = 1ull << 22; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. >-static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther; // Bitmask used for testing for any kind of object prediction. >-static const SpeculatedType SpecStringIdent = 1ull << 23; // It's definitely a JSString, and it's an identifier. >-static const SpeculatedType SpecStringVar = 1ull << 24; // It's definitely a JSString, and it's not an identifier. >-static const SpeculatedType SpecString = SpecStringIdent | SpecStringVar; // It's definitely a JSString. >-static const SpeculatedType SpecSymbol = 1ull << 25; // It's definitely a Symbol. >-static const SpeculatedType SpecCellOther = 1ull << 26; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString, BigInt, or Symbol. >-static const SpeculatedType SpecBoolInt32 = 1ull << 27; // It's definitely an Int32 with value 0 or 1. >-static const SpeculatedType SpecNonBoolInt32 = 1ull << 28; // It's definitely an Int32 with value other than 0 or 1. >-static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32. >-static const SpeculatedType SpecInt52Only = 1ull << 29; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32. >-static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on. >-static const SpeculatedType SpecAnyIntAsDouble = 1ull << 30; // It's definitely an Int52 and it's inside a double. >-static const SpeculatedType SpecNonIntAsDouble = 1ull << 31; // It's definitely not an Int52 but it's a real number and it's a double. >-static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double. >-static const SpeculatedType SpecDoublePureNaN = 1ull << 32; // It's definitely a NaN that is safe to tag (i.e. pure). >-static const SpeculatedType SpecDoubleImpureNaN = 1ull << 33; // It's definitely a NaN that is unsafe to tag (i.e. impure). >-static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN. >-static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN. >-static const SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double. >-static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal. >-static const SpeculatedType SpecFullRealNumber = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52. >-static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN. >-static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN. >-static const SpeculatedType SpecBoolean = 1ull << 34; // It's definitely a Boolean. >-static const SpeculatedType SpecOther = 1ull << 35; // It's definitely either Null or Undefined. >-static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined. >-static const SpeculatedType SpecEmpty = 1ull << 36; // It's definitely an empty value marker. >-static const SpeculatedType SpecBigInt = 1ull << 37; // It's definitely a BigInt. >-static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue. >-static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell. >-static const SpeculatedType SpecHeapTop = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. >-static const SpeculatedType SpecBytecodeTop = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local. >-static const SpeculatedType SpecFullTop = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers. >+static const SpeculatedType SpecNone = 0; // We don't know anything yet. >+static const SpeculatedType SpecFinalObject = 1ull << 0; // It's definitely a JSFinalObject. >+static const SpeculatedType SpecArray = 1ull << 1; // It's definitely a JSArray. >+static const SpeculatedType SpecFunctionWithDefaultHasInstance = 1ull << 2; // It's definitely a JSFunction that has its ImplementsDefaultHasInstance type info flags bit set. >+static const SpeculatedType SpecFunctionWithNonDefaultHasInstance = 1ull << 3; // It's definitely a JSFunction that has does not have its ImplementsDefaultHasInstance bit set. >+static const SpeculatedType SpecFunction = SpecFunctionWithDefaultHasInstance | SpecFunctionWithNonDefaultHasInstance; // It's definitely a JSFunction. >+static const SpeculatedType SpecInt8Array = 1ull << 4; // It's definitely an Int8Array or one of its subclasses. >+static const SpeculatedType SpecInt16Array = 1ull << 5; // It's definitely an Int16Array or one of its subclasses. >+static const SpeculatedType SpecInt32Array = 1ull << 6; // It's definitely an Int32Array or one of its subclasses. >+static const SpeculatedType SpecUint8Array = 1ull << 7; // It's definitely an Uint8Array or one of its subclasses. >+static const SpeculatedType SpecUint8ClampedArray = 1ull << 8; // It's definitely an Uint8ClampedArray or one of its subclasses. >+static const SpeculatedType SpecUint16Array = 1ull << 9; // It's definitely an Uint16Array or one of its subclasses. >+static const SpeculatedType SpecUint32Array = 1ull << 10; // It's definitely an Uint32Array or one of its subclasses. >+static const SpeculatedType SpecFloat32Array = 1ull << 11; // It's definitely an Uint16Array or one of its subclasses. >+static const SpeculatedType SpecFloat64Array = 1ull << 12; // It's definitely an Uint16Array or one of its subclasses. >+static const SpeculatedType SpecTypedArrayView = SpecInt8Array | SpecInt16Array | SpecInt32Array | SpecUint8Array | SpecUint8ClampedArray | SpecUint16Array | SpecUint32Array | SpecFloat32Array | SpecFloat64Array; >+static const SpeculatedType SpecDirectArguments = 1ull << 13; // It's definitely a DirectArguments object. >+static const SpeculatedType SpecScopedArguments = 1ull << 14; // It's definitely a ScopedArguments object. >+static const SpeculatedType SpecStringObject = 1ull << 15; // It's definitely a StringObject. >+static const SpeculatedType SpecRegExpObject = 1ull << 16; // It's definitely a RegExpObject (and not any subclass of RegExpObject). >+static const SpeculatedType SpecMapObject = 1ull << 17; // It's definitely a Map object or one of its subclasses. >+static const SpeculatedType SpecSetObject = 1ull << 18; // It's definitely a Set object or one of its subclasses. >+static const SpeculatedType SpecWeakMapObject = 1ull << 19; // It's definitely a WeakMap object or one of its subclasses. >+static const SpeculatedType SpecWeakSetObject = 1ull << 20; // It's definitely a WeakSet object or one of its subclasses. >+static const SpeculatedType SpecProxyObject = 1ull << 21; // It's definitely a Proxy object or one of its subclasses. >+static const SpeculatedType SpecDerivedArray = 1ull << 22; // It's definitely a DerivedArray object. >+static const SpeculatedType SpecObjectOther = 1ull << 23; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction. >+static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther; // Bitmask used for testing for any kind of object prediction. >+static const SpeculatedType SpecStringIdent = 1ull << 24; // It's definitely a JSString, and it's an identifier. >+static const SpeculatedType SpecStringVar = 1ull << 25; // It's definitely a JSString, and it's not an identifier. >+static const SpeculatedType SpecString = SpecStringIdent | SpecStringVar; // It's definitely a JSString. >+static const SpeculatedType SpecSymbol = 1ull << 26; // It's definitely a Symbol. >+static const SpeculatedType SpecCellOther = 1ull << 27; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString, BigInt, or Symbol. >+static const SpeculatedType SpecBoolInt32 = 1ull << 28; // It's definitely an Int32 with value 0 or 1. >+static const SpeculatedType SpecNonBoolInt32 = 1ull << 29; // It's definitely an Int32 with value other than 0 or 1. >+static const SpeculatedType SpecInt32Only = SpecBoolInt32 | SpecNonBoolInt32; // It's definitely an Int32. >+static const SpeculatedType SpecInt52Only = 1ull << 30; // It's definitely an Int52 and we intend it to unbox it. It's also definitely not an Int32. >+static const SpeculatedType SpecAnyInt = SpecInt32Only | SpecInt52Only; // It's something that we can do machine int arithmetic on. >+static const SpeculatedType SpecAnyIntAsDouble = 1ull << 31; // It's definitely an Int52 and it's inside a double. >+static const SpeculatedType SpecNonIntAsDouble = 1ull << 32; // It's definitely not an Int52 but it's a real number and it's a double. >+static const SpeculatedType SpecDoubleReal = SpecNonIntAsDouble | SpecAnyIntAsDouble; // It's definitely a non-NaN double. >+static const SpeculatedType SpecDoublePureNaN = 1ull << 33; // It's definitely a NaN that is safe to tag (i.e. pure). >+static const SpeculatedType SpecDoubleImpureNaN = 1ull << 34; // It's definitely a NaN that is unsafe to tag (i.e. impure). >+static const SpeculatedType SpecDoubleNaN = SpecDoublePureNaN | SpecDoubleImpureNaN; // It's definitely some kind of NaN. >+static const SpeculatedType SpecBytecodeDouble = SpecDoubleReal | SpecDoublePureNaN; // It's either a non-NaN or a NaN double, but it's definitely not impure NaN. >+static const SpeculatedType SpecFullDouble = SpecDoubleReal | SpecDoubleNaN; // It's either a non-NaN or a NaN double. >+static const SpeculatedType SpecBytecodeRealNumber = SpecInt32Only | SpecDoubleReal; // It's either an Int32 or a DoubleReal. >+static const SpeculatedType SpecFullRealNumber = SpecAnyInt | SpecDoubleReal; // It's either an Int32 or a DoubleReal, or a Int52. >+static const SpeculatedType SpecBytecodeNumber = SpecInt32Only | SpecBytecodeDouble; // It's either an Int32 or a Double, and the Double cannot be an impure NaN. >+static const SpeculatedType SpecFullNumber = SpecAnyInt | SpecFullDouble; // It's either an Int32, Int52, or a Double, and the Double can be impure NaN. >+static const SpeculatedType SpecBoolean = 1ull << 35; // It's definitely a Boolean. >+static const SpeculatedType SpecOther = 1ull << 36; // It's definitely either Null or Undefined. >+static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined. >+static const SpeculatedType SpecEmpty = 1ull << 37; // It's definitely an empty value marker. >+static const SpeculatedType SpecBigInt = 1ull << 38; // It's definitely a BigInt. >+static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue. >+static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell. >+static const SpeculatedType SpecHeapTop = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. >+static const SpeculatedType SpecBytecodeTop = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local. >+static const SpeculatedType SpecFullTop = SpecBytecodeTop | SpecFullNumber; // It can be anything that bytecode could see plus exotic encodings of numbers. > > // SpecCellCheck is the type set representing the values that can flow through a cell check. > // On 64-bit platforms, the empty value passes a cell check. Also, ~SpecCellCheck is the type >Index: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (revision 231813) >+++ Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (working copy) >@@ -3437,7 +3437,6 @@ bool AbstractInterpreter<AbstractStateTy > case CountExecution: > case CheckTierUpInLoop: > case CheckTierUpAtReturn: >- case CheckTypeInfoFlags: > case SuperSamplerBegin: > case SuperSamplerEnd: > case CheckTierUpAndOSREnter: >@@ -3446,6 +3445,40 @@ bool AbstractInterpreter<AbstractStateTy > case ExitOK: > break; > >+ case CheckTypeInfoFlags: { >+ if (node->typeInfoOperand() != ImplementsDefaultHasInstance) >+ break; >+ >+ const AbstractValue& abstractValue = forNode(node->child1()); >+ >+ if (abstractValue.m_type == SpecFunctionWithDefaultHasInstance) { >+ m_state.setFoundConstants(true); >+ break; >+ } >+ >+ if (JSValue value = abstractValue.value()) { >+ if (value.isCell()) { >+ // This works because if we see a cell here, we know it's fully constructed >+ // and we can read its inline type info flags. These flags don't change over the >+ // object's lifetime. >+ if (value.asCell()->inlineTypeFlags() & ImplementsDefaultHasInstance) { >+ m_state.setFoundConstants(true); >+ break; >+ } >+ } >+ } >+ >+ if (abstractValue.m_structure.isFinite()) { >+ bool ok = true; >+ abstractValue.m_structure.forEach([&] (RegisteredStructure structure) { >+ ok &= structure->typeInfo().implementsDefaultHasInstance(); >+ }); >+ if (ok) >+ m_state.setFoundConstants(true); >+ } >+ break; >+ } >+ > case ParseInt: { > AbstractValue value = forNode(node->child1()); > if (value.m_type && !(value.m_type & ~SpecInt32Only)) { >Index: Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (revision 231813) >+++ Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp (working copy) >@@ -806,6 +806,46 @@ private: > } > break; > } >+ >+ case CheckTypeInfoFlags: { >+ if (node->typeInfoOperand() != ImplementsDefaultHasInstance) >+ break; >+ >+ const AbstractValue& abstractValue = m_state.forNode(node->child1()); >+ >+ if (abstractValue.m_type == SpecFunctionWithDefaultHasInstance) { >+ node->remove(m_graph); >+ changed = true; >+ break; >+ } >+ >+ if (JSValue value = abstractValue.value()) { >+ if (value.isCell()) { >+ // This works because if we see a cell here, we know it's fully constructed >+ // and we can read its inline type info flags. These flags don't change over the >+ // object's lifetime. >+ if (value.asCell()->inlineTypeFlags() & ImplementsDefaultHasInstance) { >+ node->remove(m_graph); >+ changed = true; >+ break; >+ } >+ } >+ } >+ >+ if (abstractValue.m_structure.isFinite()) { >+ bool ok = true; >+ abstractValue.m_structure.forEach([&] (RegisteredStructure structure) { >+ ok &= structure->typeInfo().implementsDefaultHasInstance(); >+ }); >+ if (ok) { >+ node->remove(m_graph); >+ changed = true; >+ break; >+ } >+ } >+ >+ break; >+ } > > case PhantomNewObject: > case PhantomNewFunction: >Index: Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (revision 231813) >+++ Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp (working copy) >@@ -303,7 +303,7 @@ private: > break; > } > >- // FIXME: we should probably do this in constant folding but this currently relies on an OSR exit rule. >+ // FIXME: we should probably do this in constant folding but this currently relies on OSR exit history: > // https://bugs.webkit.org/show_bug.cgi?id=154832 > case OverridesHasInstance: { > if (!m_node->child2().node()->isCellConstant()) >Index: Source/JavaScriptCore/runtime/JSFunction.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/JSFunction.cpp (revision 231813) >+++ Source/JavaScriptCore/runtime/JSFunction.cpp (working copy) >@@ -100,6 +100,7 @@ JSFunction::JSFunction(VM& vm, JSGlobalO > : Base(vm, globalObject, structure) > , m_executable() > { >+ assertTypeInfoFlagInvariants(); > } > > >@@ -789,4 +790,16 @@ JSFunction::PropertyStatus JSFunction::r > return PropertyStatus::Reified; > } > >+#if !ASSERT_DISABLED >+void JSFunction::assertTypeInfoFlagInvariants() >+{ >+ // If you change this, you'll need to update speculationFromClassInfo. >+ const ClassInfo* info = classInfo(*vm()); >+ if (!(inlineTypeFlags() & ImplementsDefaultHasInstance)) >+ RELEASE_ASSERT(info == JSBoundFunction::info()); >+ else >+ RELEASE_ASSERT(info != JSBoundFunction::info()); >+} >+#endif >+ > } // namespace JSC >Index: Source/JavaScriptCore/runtime/JSFunction.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSFunction.h (revision 231813) >+++ Source/JavaScriptCore/runtime/JSFunction.h (working copy) >@@ -208,6 +208,12 @@ private: > PropertyStatus reifyLazyNameIfNeeded(VM&, ExecState*, PropertyName); > PropertyStatus reifyLazyBoundNameIfNeeded(VM&, ExecState*, PropertyName); > >+#if ASSERT_DISABLED >+ void assertTypeInfoFlagInvariants() { } >+#else >+ void assertTypeInfoFlagInvariants(); >+#endif >+ > friend class LLIntOffsetsExtractor; > > static EncodedJSValue argumentsGetter(ExecState*, EncodedJSValue, PropertyName); >Index: Source/JavaScriptCore/runtime/JSFunctionInlines.h >=================================================================== >--- Source/JavaScriptCore/runtime/JSFunctionInlines.h (revision 231813) >+++ Source/JavaScriptCore/runtime/JSFunctionInlines.h (working copy) >@@ -43,6 +43,7 @@ inline JSFunction::JSFunction(VM& vm, Fu > , m_executable(vm, this, executable) > , m_rareData() > { >+ assertTypeInfoFlagInvariants(); > } > > inline FunctionExecutable* JSFunction::jsExecutable() const
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
Flags:
ysuzuki
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185670
:
340466
|
340543