+2018-05-16 Saam Barati <sbarati@apple.com>
+
+ Constant fold CheckTypeInfoFlags on ImplementsDefaultHasInstance
+ https://bugs.webkit.org/show_bug.cgi?id=185670
+
+ Reviewed by Yusuke Suzuki.
+
+ 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/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileCheckTypeInfoFlags):
+ * 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-16 Devin Rousso <webkit@devinrousso.com>
Web Inspector: create a navigation item for toggling the overlay rulers/guides
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 does not have its ImplementsDefaultHasInstance type info flags 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