mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1244098 - Attempt to fold JSOP_IN to false in IonBuilder based on TI. r=bhackett
This commit is contained in:
parent
e0dba90fc3
commit
7ec509c581
32
js/src/jit-test/tests/ion/fold-in.js
Normal file
32
js/src/jit-test/tests/ion/fold-in.js
Normal file
@ -0,0 +1,32 @@
|
||||
// Singleton
|
||||
function f() {
|
||||
var res = 0;
|
||||
for (var i=0; i<500; i++)
|
||||
res += ("abcd" in Math);
|
||||
return res;
|
||||
}
|
||||
assertEq(f(), 0);
|
||||
Math.abcd = 3;
|
||||
assertEq(f(), 500);
|
||||
delete Math.abcd;
|
||||
assertEq(f(), 0);
|
||||
|
||||
// Non-singleton
|
||||
function O(x) { if (x) this.x = 1; }
|
||||
|
||||
var arr = [];
|
||||
for (var i=0; i<4; i++)
|
||||
arr.push(new O(i % 2));
|
||||
|
||||
function g(arr) {
|
||||
var res = 0;
|
||||
for (var i=0; i<500; i++) {
|
||||
var o = arr[i % arr.length];
|
||||
res += "x" in o;
|
||||
res += "abcd" in o;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
assertEq(g(arr), 250);
|
||||
arr[0].abcd = 3;
|
||||
assertEq(g(arr), 375);
|
@ -13319,21 +13319,13 @@ IonBuilder::jsop_in()
|
||||
MDefinition* obj = convertUnboxedObjects(current->pop());
|
||||
MDefinition* id = current->pop();
|
||||
|
||||
do {
|
||||
if (shouldAbortOnPreliminaryGroups(obj))
|
||||
break;
|
||||
bool emitted = false;
|
||||
|
||||
JSValueType unboxedType = UnboxedArrayElementType(constraints(), obj, id);
|
||||
if (unboxedType == JSVAL_TYPE_MAGIC) {
|
||||
if (!ElementAccessIsDenseNative(constraints(), obj, id))
|
||||
break;
|
||||
}
|
||||
if (!inTryDense(&emitted, obj, id) || emitted)
|
||||
return emitted;
|
||||
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||
break;
|
||||
|
||||
return jsop_in_dense(obj, id, unboxedType);
|
||||
} while (false);
|
||||
if (!inTryFold(&emitted, obj, id) || emitted)
|
||||
return emitted;
|
||||
|
||||
MIn* ins = MIn::New(alloc(), id, obj);
|
||||
|
||||
@ -13344,8 +13336,24 @@ IonBuilder::jsop_in()
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_in_dense(MDefinition* obj, MDefinition* id, JSValueType unboxedType)
|
||||
IonBuilder::inTryDense(bool* emitted, MDefinition* obj, MDefinition* id)
|
||||
{
|
||||
MOZ_ASSERT(!*emitted);
|
||||
|
||||
if (shouldAbortOnPreliminaryGroups(obj))
|
||||
return true;
|
||||
|
||||
JSValueType unboxedType = UnboxedArrayElementType(constraints(), obj, id);
|
||||
if (unboxedType == JSVAL_TYPE_MAGIC) {
|
||||
if (!ElementAccessIsDenseNative(constraints(), obj, id))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ElementAccessHasExtraIndexedProperty(this, obj))
|
||||
return true;
|
||||
|
||||
*emitted = true;
|
||||
|
||||
bool needsHoleCheck = !ElementAccessIsPacked(constraints(), obj);
|
||||
|
||||
// Ensure id is an integer.
|
||||
@ -13375,6 +13383,67 @@ IonBuilder::jsop_in_dense(MDefinition* obj, MDefinition* id, JSValueType unboxed
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::inTryFold(bool* emitted, MDefinition* obj, MDefinition* id)
|
||||
{
|
||||
// Fold |id in obj| to |false|, if we know the object (or an object on its
|
||||
// prototype chain) does not have this property.
|
||||
|
||||
MOZ_ASSERT(!*emitted);
|
||||
|
||||
jsid propId;
|
||||
if (!id->isConstantValue() || !ValueToIdPure(id->constantValue(), &propId))
|
||||
return true;
|
||||
|
||||
if (propId != IdToTypeId(propId))
|
||||
return true;
|
||||
|
||||
TemporaryTypeSet* types = obj->resultTypeSet();
|
||||
if (!types || types->unknownObject())
|
||||
return true;
|
||||
|
||||
for (unsigned i = 0, count = types->getObjectCount(); i < count; i++) {
|
||||
TypeSet::ObjectKey* key = types->getObject(i);
|
||||
if (!key)
|
||||
continue;
|
||||
|
||||
while (true) {
|
||||
if (!key->hasStableClassAndProto(constraints()) || key->unknownProperties())
|
||||
return true;
|
||||
|
||||
const Class* clasp = key->clasp();
|
||||
if (!ClassHasEffectlessLookup(clasp) || ObjectHasExtraOwnProperty(compartment, key, propId))
|
||||
return true;
|
||||
|
||||
// If the object is a singleton, we can do a lookup now to avoid
|
||||
// unnecessary invalidations later on, in case the property types
|
||||
// have not yet been instantiated.
|
||||
if (key->isSingleton() &&
|
||||
key->singleton()->is<NativeObject>() &&
|
||||
key->singleton()->as<NativeObject>().lookupPure(propId))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
HeapTypeSetKey property = key->property(propId);
|
||||
if (property.isOwnProperty(constraints()))
|
||||
return true;
|
||||
|
||||
JSObject* proto = checkNurseryObject(key->proto().toObjectOrNull());
|
||||
if (!proto)
|
||||
break;
|
||||
key = TypeSet::ObjectKey::get(proto);
|
||||
}
|
||||
}
|
||||
|
||||
*emitted = true;
|
||||
|
||||
pushConstant(BooleanValue(false));
|
||||
obj->setImplicitlyUsedUnchecked();
|
||||
id->setImplicitlyUsedUnchecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::hasOnProtoChain(TypeSet::ObjectKey* key, JSObject* protoObject, bool* hasOnProto)
|
||||
{
|
||||
|
@ -502,13 +502,17 @@ class IonBuilder
|
||||
// jsop_bitnot helpers.
|
||||
bool bitnotTrySpecialized(bool* emitted, MDefinition* input);
|
||||
|
||||
// jsop_compare helpes.
|
||||
// jsop_compare helpers.
|
||||
bool compareTrySpecialized(bool* emitted, JSOp op, MDefinition* left, MDefinition* right);
|
||||
bool compareTryBitwise(bool* emitted, JSOp op, MDefinition* left, MDefinition* right);
|
||||
bool compareTrySpecializedOnBaselineInspector(bool* emitted, JSOp op, MDefinition* left,
|
||||
MDefinition* right);
|
||||
bool compareTrySharedStub(bool* emitted, JSOp op, MDefinition* left, MDefinition* right);
|
||||
|
||||
// jsop_in helpers.
|
||||
bool inTryDense(bool* emitted, MDefinition* obj, MDefinition* id);
|
||||
bool inTryFold(bool* emitted, MDefinition* obj, MDefinition* id);
|
||||
|
||||
// binary data lookup helpers.
|
||||
TypedObjectPrediction typedObjectPrediction(MDefinition* typedObj);
|
||||
TypedObjectPrediction typedObjectPrediction(TemporaryTypeSet* types);
|
||||
@ -732,7 +736,6 @@ class IonBuilder
|
||||
bool jsop_isnoiter();
|
||||
bool jsop_iterend();
|
||||
bool jsop_in();
|
||||
bool jsop_in_dense(MDefinition* obj, MDefinition* id, JSValueType unboxedType);
|
||||
bool jsop_instanceof();
|
||||
bool jsop_getaliasedvar(ScopeCoordinate sc);
|
||||
bool jsop_setaliasedvar(ScopeCoordinate sc);
|
||||
|
Loading…
Reference in New Issue
Block a user