Bug 557652 - Eliminate redundant guard that incProp/getProp operand is not the global object. r=brendan.

--HG--
extra : rebase_source : 8da6192aedb78f6096d83a161698b27e43d30c30
This commit is contained in:
Jason Orendorff 2010-04-12 08:27:16 -05:00
parent eea611fd7f
commit 8c46df6c46
5 changed files with 31 additions and 22 deletions

View File

@ -1218,6 +1218,13 @@ JSScope::shadowingShapeChange(JSContext *cx, JSScopeProperty *sprop)
generateOwnShape(cx);
}
bool
JSScope::globalObjectOwnShapeChange(JSContext *cx)
{
generateOwnShape(cx);
return !js_IsPropertyCacheDisabled(cx);
}
void
js_TraceId(JSTracer *trc, jsid id)
{

View File

@ -278,7 +278,11 @@ struct JSScope : public JSObjectMap
bool createTable(JSContext *cx, bool report);
bool changeTable(JSContext *cx, int change);
void reportReadOnlyScope(JSContext *cx);
void setOwnShape() { flags |= OWN_SHAPE; }
void clearOwnShape() { flags &= ~OWN_SHAPE; }
void generateOwnShape(JSContext *cx);
JSScopeProperty **searchTable(jsid id, bool adding);
inline JSScopeProperty **search(jsid id, bool adding);
inline JSEmptyScope *createEmptyScope(JSContext *cx, JSClass *clasp);
@ -373,6 +377,7 @@ struct JSScope : public JSObjectMap
bool methodShapeChange(JSContext *cx, uint32 slot, jsval toval);
void protoShapeChange(JSContext *cx);
void shadowingShapeChange(JSContext *cx, JSScopeProperty *sprop);
bool globalObjectOwnShapeChange(JSContext *cx);
/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift)
@ -436,8 +441,6 @@ struct JSScope : public JSObjectMap
void setIndexedProperties() { flags |= INDEXED_PROPERTIES; }
bool hasOwnShape() { return flags & OWN_SHAPE; }
void setOwnShape() { flags |= OWN_SHAPE; }
void clearOwnShape() { flags &= ~OWN_SHAPE; }
bool hasRegenFlag(uint8 regenFlag) { return (flags & SHAPE_REGEN) == regenFlag; }

View File

@ -2174,6 +2174,7 @@ TraceRecorder::TraceRecorder(JSContext* cx, VMSideExit* anchor, VMFragment* frag
tempTypeMap(cx)
{
JS_ASSERT(globalObj == cx->fp->scopeChain->getGlobal());
JS_ASSERT(globalObj->scope()->hasOwnShape());
JS_ASSERT(cx->fp->regs->pc == (jsbytecode*)fragment->ip);
fragment->lirbuf = lirbuf;
@ -5300,6 +5301,20 @@ CheckGlobalObjectShape(JSContext* cx, TraceMonitor* tm, JSObject* globalObj,
return false;
}
/*
* The global object must have a unique shape. That way, if an operand
* isn't the global at record time, a shape guard suffices to ensure
* that it isn't the global at run time.
*/
if (!globalObj->scope()->hasOwnShape()) {
JSScope *scope = js_GetMutableScope(cx, globalObj);
if (!scope || !scope->globalObjectOwnShapeChange(cx)) {
debug_only_print0(LC_TMTracer,
"Can't record: failed to give globalObj a unique shape.\n");
return false;
}
}
uint32 globalShape = globalObj->shape();
if (tm->recorder) {
@ -9571,15 +9586,6 @@ TraceRecorder::guardPrototypeHasNoIndexedProperties(JSObject* obj, LIns* obj_ins
return RECORD_CONTINUE;
}
RecordingStatus
TraceRecorder::guardNotGlobalObject(JSObject* obj, LIns* obj_ins)
{
if (obj == globalObj)
RETURN_STOP("reference aliases global object");
guard(false, lir->ins2(LIR_peq, obj_ins, INS_CONSTOBJ(globalObj)), MISMATCH_EXIT);
return RECORD_CONTINUE;
}
// Helper for clearXEntryFrameSlotsFromTracker.
// Clear out slots of the given frame in the NativeFrameTracker. All argument slots
// are cleared. |nslots| local slots are cleared.
@ -12259,7 +12265,8 @@ TraceRecorder::upvar(JSScript* script, JSUpvarArray* uva, uintN index, jsval& v)
* Generate LIR to load a value from the native stack. This method ensures that
* the correct LIR load operator is used.
*/
LIns* TraceRecorder::stackLoad(LIns* base, AccSet accSet, uint8 type)
LIns*
TraceRecorder::stackLoad(LIns* base, AccSet accSet, uint8 type)
{
LOpcode loadOp;
switch (type) {
@ -12800,12 +12807,6 @@ TraceRecorder::prop(JSObject* obj, LIns* obj_ins, uint32 *slotp, LIns** v_insp,
JS_ASSERT((slotp && v_insp && !outp) || (!slotp && !v_insp && outp));
/*
* Can't specialize to assert obj != global, must guard to avoid aliasing
* stale homes of stacked global variables.
*/
CHECK_STATUS_A(guardNotGlobalObject(obj, obj_ins));
/*
* Property cache ensures that we are dealing with an existing property,
* and guards the shape for us.

View File

@ -1305,8 +1305,6 @@ class TraceRecorder
JS_REQUIRES_STACK RecordingStatus guardPrototypeHasNoIndexedProperties(JSObject* obj,
nanojit::LIns* obj_ins,
ExitType exitType);
JS_REQUIRES_STACK RecordingStatus guardNotGlobalObject(JSObject* obj,
nanojit::LIns* obj_ins);
JS_REQUIRES_STACK JSStackFrame* entryFrame() const;
JS_REQUIRES_STACK void clearEntryFrameSlotsFromTracker(Tracker& which);
JS_REQUIRES_STACK void clearCurrentFrameSlotsFromTracker(Tracker& which);