Bug 503694 - TM: Code run off an event handler is never traced, r=brendan.

--HG--
extra : rebase_source : da2e900baac68f88f06eaa8554b245f7d403153f
This commit is contained in:
Graydon Hoare 2009-08-06 12:40:51 -07:00
parent fe2bbefd24
commit fd8a117e2f
4 changed files with 57 additions and 57 deletions

View File

@ -1423,17 +1423,6 @@ js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
JSBool ok;
js_LeaveTrace(cx);
#ifdef JS_TRACER
/*
* The JIT requires that the scope chain here is equal to its global
* object. Disable the JIT for this call if this condition is not true.
*/
uint32 oldOptions = cx->options;
if ((oldOptions & JSOPTION_JIT) && obj != JS_GetGlobalForObject(cx, obj))
cx->options &= ~JSOPTION_JIT;
#endif
invokevp = js_AllocStack(cx, 2 + argc, &mark);
if (!invokevp)
return JS_FALSE;
@ -1463,13 +1452,6 @@ js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags,
}
js_FreeStack(cx, mark);
#ifdef JS_TRACER
/* Possibly re-enable JIT, if disabled above. */
if (oldOptions & JSOPTION_JIT)
cx->options |= JSOPTION_JIT;
#endif
return ok;
}
@ -1527,16 +1509,6 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
js_LeaveTrace(cx);
#ifdef JS_TRACER
/*
* The JIT requires that the scope chain here is equal to its global
* object. Disable the JIT for this call if this condition is not true.
*/
uint32 oldOptions = cx->options;
if ((oldOptions & JSOPTION_JIT) && chain != JS_GetGlobalForObject(cx, chain))
cx->options &= ~JSOPTION_JIT;
#endif
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_START_ENABLED())
jsdtrace_execute_start(script);
@ -1661,13 +1633,6 @@ out:
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
jsdtrace_execute_done(script);
#endif
#ifdef JS_TRACER
/* Possibly re-enable JIT, if disabled above. */
if (oldOptions & JSOPTION_JIT)
cx->options |= JSOPTION_JIT;
#endif
return ok;
}

View File

@ -3942,25 +3942,6 @@ out:
return protoIndex;
}
/*
* We cache name lookup results only for the global object or for native
* non-global objects without prototype or with prototype that never mutates,
* see bug 462734 and bug 487039.
*/
static inline bool
IsCacheableNonGlobalScope(JSObject *obj)
{
JS_ASSERT(STOBJ_GET_PARENT(obj));
JSClass *clasp = STOBJ_GET_CLASS(obj);
bool cacheable = (clasp == &js_CallClass ||
clasp == &js_BlockClass ||
clasp == &js_DeclEnvClass);
JS_ASSERT_IF(cacheable, obj->map->ops->lookupProperty == js_LookupProperty);
return cacheable;
}
JSPropCacheEntry *
js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
JSObject **objp, JSObject **pobjp, JSProperty **propp)
@ -3979,7 +3960,7 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
parent = OBJ_GET_PARENT(cx, obj);
for (scopeIndex = 0;
parent
? IsCacheableNonGlobalScope(obj)
? js_IsCacheableNonGlobalScope(obj)
: obj->map->ops->lookupProperty == js_LookupProperty;
++scopeIndex) {
protoIndex =
@ -4078,7 +4059,7 @@ js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id)
* farther checks or lookups. For details see the JSOP_BINDNAME case of
* js_Interpret.
*/
for (int scopeIndex = 0; IsCacheableNonGlobalScope(obj); scopeIndex++) {
for (int scopeIndex = 0; js_IsCacheableNonGlobalScope(obj); scopeIndex++) {
JSObject *pobj;
JSProperty *prop;
int protoIndex = js_LookupPropertyWithFlags(cx, obj, id,

View File

@ -719,6 +719,28 @@ extern int
js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
JSObject **objp, JSProperty **propp);
/*
* We cache name lookup results only for the global object or for native
* non-global objects without prototype or with prototype that never mutates,
* see bug 462734 and bug 487039.
*/
static inline bool
js_IsCacheableNonGlobalScope(JSObject *obj)
{
extern JS_FRIEND_DATA(JSClass) js_CallClass;
extern JS_FRIEND_DATA(JSClass) js_DeclEnvClass;
JS_ASSERT(STOBJ_GET_PARENT(obj));
JSClass *clasp = STOBJ_GET_CLASS(obj);
bool cacheable = (clasp == &js_CallClass ||
clasp == &js_BlockClass ||
clasp == &js_DeclEnvClass);
JS_ASSERT_IF(cacheable, obj->map->ops->lookupProperty == js_LookupProperty);
return cacheable;
}
/*
* If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
*/

View File

@ -5407,8 +5407,40 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
JS_ASSERT(f->root == f && f->code() && f->vmprivate);
/*
* The JIT records and expects to execute with two scope-chain
* assumptions baked-in:
*
* 1. That the bottom of the scope chain is global, in the sense of
* JSCLASS_IS_GLOBAL.
*
* 2. That the scope chain between fp and the global is free of
* "unusual" native objects such as HTML forms or other funny
* things.
*
* #2 is checked here while following the scope-chain links, via
* js_IsCacheableNonGlobalScope, which consults a whitelist of known
* class types; once a global is found, it's checked for #1. Failing
* either check causes an early return from execution.
*/
JSObject* parent;
JSObject* child = cx->fp->scopeChain;
while ((parent = OBJ_GET_PARENT(cx, child)) != NULL) {
if (!js_IsCacheableNonGlobalScope(child)) {
debug_only_print0(LC_TMTracer,"Blacklist: non-cacheable object on scope chain.\n");
Blacklist((jsbytecode*) f->root->ip);
return NULL;
}
child = parent;
}
JSObject* globalObj = child;
if (!(OBJ_GET_CLASS(cx, globalObj)->flags & JSCLASS_IS_GLOBAL)) {
debug_only_print0(LC_TMTracer, "Blacklist: non-global at root of scope chain.\n");
Blacklist((jsbytecode*) f->root->ip);
return NULL;
}
JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx);
JSObject* globalObj = JS_GetGlobalForObject(cx, cx->fp->scopeChain);
TreeInfo* ti = (TreeInfo*)f->vmprivate;
unsigned ngslots = ti->globalSlots->length();
uint16* gslots = ti->globalSlots->data();