Abort recording on some more global operations (bug 597940, r=luke).

This commit is contained in:
David Anderson 2011-01-05 19:53:08 -08:00
parent fe23536656
commit 9e176a411b
3 changed files with 19 additions and 77 deletions

View File

@ -1,19 +1,6 @@
/* Touch/init early so global shape doesn't change in loop */
var SetOnIter = HOTLOOP - 1;
var x = 3;
var i = 0;
assertEq(true, true);
for (i = 0; i < SetOnIter + 10; ++i) {
x = 3;
setGlobalPropIf(i == SetOnIter, 'x', 'pretty');
assertEq(x == 'pretty', i == SetOnIter);
x = 3;
}
for (i = 0; i < SetOnIter + 10; ++i) {
x = 3;
defGlobalPropIf(i == SetOnIter, 'x', { value:'pretty' });
assertEq(x == 'pretty', i == SetOnIter);
x = 3;
X = { value: "" }
z = 0;
for (var i = 0; i < 20; i++) {
Object.defineProperty(this, "z", X);
z = 1;
}

View File

@ -1612,7 +1612,20 @@ class TraceRecorder
* Do slot arithmetic manually to avoid getSlotRef assertions which
* do not need to be satisfied for this purpose.
*/
return !tracker.has(globalObj->getSlots() + slot);
Value *vp = globalObj->getSlots() + slot;
/* If this global is definitely being tracked, then the write is unexpected. */
if (tracker.has(vp))
return false;
/*
* Otherwise, only abort if the global is not present in the
* import typemap. Just deep aborting false here is not acceptable,
* because the recorder does not guard on every operation that
* could lazily resolve. Since resolving adds properties to
* reserved slots, the tracer will never have imported them.
*/
return tree->globalSlots->offsetOf(nativeGlobalSlot(vp)) == -1;
}
pendingGlobalSlotToSet = -1;
return true;

View File

@ -4246,59 +4246,6 @@ Deserialize(JSContext *cx, uintN argc, jsval *vp)
return true;
}
JSBool
SetGlobalPropIf(JSContext *cx, uintN argc, jsval *vp)
{
if (argc != 3) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "setGlobalPropIf");
return false;
}
jsval *argv = JS_ARGV(cx, vp);
JSBool doSet;
if (!JS_ValueToBoolean(cx, argv[0], &doSet))
return false;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
if (!doSet)
return true;
jsid id;
if (!JS_ValueToId(cx, argv[1], &id))
return false;
JSObject *global = JS_GetGlobalForScopeChain(cx);
return global && JS_SetPropertyById(cx, global, id, &argv[2]);
}
JSBool
DefGlobalPropIf(JSContext *cx, uintN argc, jsval *vp)
{
if (argc != 3) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_INVALID_ARGS, "setGlobalPropIf");
return false;
}
jsval *argv = JS_ARGV(cx, vp);
JSBool doSet;
if (!JS_ValueToBoolean(cx, argv[0], &doSet))
return false;
JS_SET_RVAL(cx, vp, JSVAL_VOID);
if (!doSet)
return true;
jsid id;
if (!JS_ValueToId(cx, argv[1], &id))
return false;
JSObject *global = JS_GetGlobalForScopeChain(cx);
JSBool ignore;
return global && JS_DefineOwnProperty(cx, global, id, argv[2], &ignore);
}
JSBool
MJitStats(JSContext *cx, uintN argc, jsval *vp)
{
@ -4410,8 +4357,6 @@ static JSFunctionSpec shell_functions[] = {
JS_FN("wrap", Wrap, 1,0),
JS_FN("serialize", Serialize, 1,0),
JS_FN("deserialize", Deserialize, 1,0),
JS_FN("setGlobalPropIf",SetGlobalPropIf,3,0),
JS_FN("defGlobalPropIf",DefGlobalPropIf,3,0),
#ifdef JS_METHODJIT
JS_FN("mjitstats", MJitStats, 0,0),
#endif
@ -4545,9 +4490,6 @@ static const char *const shell_help_messages[] = {
"wrap(obj) Wrap an object into a noop wrapper.\n",
"serialize(sd) Serialize sd using JS_WriteStructuredClone. Returns a TypedArray.\n",
"deserialize(a) Deserialize data generated by serialize.\n",
"setGlobalPropIf(b,id,v) If b, get the global object o and perform o[id] = v.\n",
"defGlobalPropIf(b,id,dsc)If b, get the global object o and perform\n"
" Object.defineProperty(o, id, dsc).\n",
#ifdef JS_METHODJIT
"mjitstats() Return stats on mjit memory usage.\n",
#endif