Bug 522817: move on-trace method write barrier after shape guard, r=brendan

This commit is contained in:
David Mandelin 2009-10-20 10:55:15 -07:00
parent 5860669cc9
commit 1e4ad3b192
2 changed files with 34 additions and 17 deletions

View File

@ -11141,23 +11141,6 @@ TraceRecorder::setProp(jsval &l, JSPropCacheEntry* entry, JSScopeProperty* sprop
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass)
return setCallProp(obj, obj_ins, sprop, v_ins, v);
/*
* Setting a function-valued property might need to rebrand the object, so
* we emit a call to the method write barrier. There's no need to guard on
* this, because functions have distinct trace-type from other values and
* branded-ness is implied by the shape, which we've already guarded on.
*/
if (scope->branded() && VALUE_IS_FUNCTION(cx, v) && entry->directHit()) {
if (obj == globalObj)
RETURN_STOP("can't trace function-valued property set in branded global scope");
enterDeepBailCall();
LIns* args[] = { v_ins, INS_CONSTSPROP(sprop), obj_ins, cx_ins };
LIns* ok_ins = lir->insCall(&MethodWriteBarrier_ci, args);
guard(false, lir->ins_eq0(ok_ins), OOM_EXIT);
leaveDeepBailCall();
}
// Find obj2. If entry->adding(), the TAG bits are all 0.
JSObject* obj2 = obj;
for (jsuword i = PCVCAP_TAG(entry->vcap) >> PCVCAP_PROTOBITS; i; i--)
@ -11176,6 +11159,23 @@ TraceRecorder::setProp(jsval &l, JSPropCacheEntry* entry, JSScopeProperty* sprop
JS_ASSERT(scope->has(sprop));
JS_ASSERT_IF(obj2 != obj, sprop->attrs & JSPROP_SHARED);
/*
* Setting a function-valued property might need to rebrand the object, so
* we emit a call to the method write barrier. There's no need to guard on
* this, because functions have distinct trace-type from other values and
* branded-ness is implied by the shape, which we've already guarded on.
*/
if (scope->branded() && VALUE_IS_FUNCTION(cx, v) && entry->directHit()) {
if (obj == globalObj)
RETURN_STOP("can't trace function-valued property set in branded global scope");
enterDeepBailCall();
LIns* args[] = { v_ins, INS_CONSTSPROP(sprop), obj_ins, cx_ins };
LIns* ok_ins = lir->insCall(&MethodWriteBarrier_ci, args);
guard(false, lir->ins_eq0(ok_ins), OOM_EXIT);
leaveDeepBailCall();
}
// Add a property to the object if necessary.
if (entry->adding()) {
JS_ASSERT(!(sprop->attrs & JSPROP_SHARED));

View File

@ -0,0 +1,17 @@
// This test should not assert in a debug build.
var q1={};
var $native = function () {
for (var i = 0, l = arguments.length; i < l; i++) {
arguments[i].extend = function (props) {};
}
};
$native(q1, Array, String, Number);
Array.extend({});
Number.extend({});
Object.Native = function () {
for (var i = 0; i < arguments.length; i++) {
arguments[i].eeeeee = (function(){});
}
};
new Object.Native(q1, Array, String, Number);