Bug 905999 - Part 3: Only generate Array.length stubs in idempotent caches with accurate TI. (r=bhackett)

Relanding after erroneous backout on a CLOSED TREE.
This commit is contained in:
Eric Faust 2013-08-28 16:12:59 -07:00
parent a1a174ee4f
commit b009ff6372
3 changed files with 44 additions and 1 deletions

View File

@ -0,0 +1,11 @@
// |jit-test| ion-eager
function reportCompare (expected) {
typeof expected;
}
var expect = 'No Crash';
var array = new Array(10);
for (var i = 0; i != array.length; ++i) {
gc();
}
var expect = array.length;
reportCompare(expect);

View File

@ -1130,7 +1130,7 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca
return GetPropertyIC::CanAttachReadSlot;
}
if (cx->names().length == name &&
if (cx->names().length == name && cache.allowArrayLength(cx, obj) &&
IsCacheableArrayLength(cx, obj, name, cache.output()))
{
// The array length property is non-configurable, which means both that
@ -1152,6 +1152,29 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca
return GetPropertyIC::CanAttachNone;
}
bool
GetPropertyIC::allowArrayLength(Context cx, HandleObject obj) const
{
if (!idempotent())
return true;
uint32_t locationIndex, numLocations;
getLocationInfo(&locationIndex, &numLocations);
IonScript *ion = GetTopIonJSScript(cx)->ionScript();
CacheLocation *locs = ion->getCacheLocs(locationIndex);
for (size_t i = 0; i < numLocations; i++) {
CacheLocation &curLoc = locs[i];
types::StackTypeSet *bcTypes =
types::TypeScript::BytecodeTypes(curLoc.script, curLoc.pc);
if (!bcTypes->hasType(types::Type::Int32Type()))
return false;
}
return true;
}
bool
GetPropertyIC::canMonitorSingletonUndefinedSlot(HandleObject holder, HandleShape shape) const
{

View File

@ -590,6 +590,11 @@ class GetPropertyIC : public RepatchIonCache
locationsIndex_ = locationsIndex;
numLocations_ = numLocations;
}
void getLocationInfo(uint32_t *index, uint32_t *num) const {
JS_ASSERT(idempotent());
*index = locationsIndex_;
*num = numLocations_;
}
enum NativeGetPropCacheability {
CanAttachError,
@ -609,6 +614,7 @@ class GetPropertyIC : public RepatchIonCache
return idempotent();
}
bool canMonitorSingletonUndefinedSlot(HandleObject holder, HandleShape shape) const;
bool allowArrayLength(Context cx, HandleObject obj) const;
// Attach the proper stub, if possible
bool tryAttachStub(JSContext *cx, IonScript *ion, HandleObject obj,
@ -745,6 +751,7 @@ class GetElementIC : public RepatchIonCache
return JSObject::lookupProperty(cx, obj, name, holder, shape);
}
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return false; }
bool lookupNeedsIdempotentChain() const { return false; }
bool canMonitorSingletonUndefinedSlot(HandleObject holder, HandleShape shape) const {
return monitoredResult();
@ -1030,6 +1037,7 @@ class GetPropertyParIC : public ParallelIonCache
bool lookupNeedsIdempotentChain() const { return true; }
bool canMonitorSingletonUndefinedSlot(HandleObject, HandleShape) const { return true; }
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return true; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, JSObject *holder,
Shape *shape);
@ -1089,6 +1097,7 @@ class GetElementParIC : public ParallelIonCache
bool lookupNeedsIdempotentChain() const { return true; }
bool canMonitorSingletonUndefinedSlot(HandleObject, HandleShape) const { return true; }
bool allowGetters() const { return false; }
bool allowArrayLength(Context, HandleObject) const { return false; }
bool attachReadSlot(LockedJSContext &cx, IonScript *ion, JSObject *obj, const Value &idval,
PropertyName *name, JSObject *holder, Shape *shape);