mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 04:35:33 +00:00
Merge tracemonkey to mozilla-central
This commit is contained in:
commit
d819a61312
@ -4105,6 +4105,17 @@ if test -n "$GC_LEAK_DETECTOR"; then
|
|||||||
AC_DEFINE(GC_LEAK_DETECTOR)
|
AC_DEFINE(GC_LEAK_DETECTOR)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
dnl ========================================================
|
||||||
|
dnl Enable Narcissus
|
||||||
|
dnl ========================================================
|
||||||
|
MOZ_ARG_ENABLE_BOOL(narcissus,
|
||||||
|
[ --enable-narcissus Build with Narcissus code enabled],
|
||||||
|
NARCISSUS=1,
|
||||||
|
NARCISSUS= )
|
||||||
|
if test -n "$NARCISSUS"; then
|
||||||
|
AC_DEFINE(NARCISSUS)
|
||||||
|
fi
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl = Enable trace malloc
|
dnl = Enable trace malloc
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
@ -2828,19 +2828,7 @@ JS_PUBLIC_API(JSBool)
|
|||||||
JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
|
JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
JS_ASSERT(obj != proto);
|
return js_SetProtoOrParent(cx, obj, JSSLOT_PROTO, proto, JS_FALSE);
|
||||||
if (OBJ_IS_NATIVE(obj)) {
|
|
||||||
JS_LOCK_OBJ(cx, obj);
|
|
||||||
if (!js_GetMutableScope(cx, obj)) {
|
|
||||||
JS_UNLOCK_OBJ(cx, obj);
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
LOCKED_OBJ_SET_PROTO(obj, proto);
|
|
||||||
JS_UNLOCK_OBJ(cx, obj);
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
|
||||||
OBJ_SET_PROTO(cx, obj, proto);
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSObject *)
|
JS_PUBLIC_API(JSObject *)
|
||||||
@ -2858,9 +2846,7 @@ JS_PUBLIC_API(JSBool)
|
|||||||
JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
|
JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
JS_ASSERT(obj != parent);
|
return js_SetProtoOrParent(cx, obj, JSSLOT_PARENT, parent, JS_FALSE);
|
||||||
OBJ_SET_PARENT(cx, obj, parent);
|
|
||||||
return JS_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSObject *)
|
JS_PUBLIC_API(JSObject *)
|
||||||
|
@ -336,7 +336,7 @@ struct JSSetSlotRequest {
|
|||||||
JSObject *obj; /* object containing slot to set */
|
JSObject *obj; /* object containing slot to set */
|
||||||
JSObject *pobj; /* new proto or parent reference */
|
JSObject *pobj; /* new proto or parent reference */
|
||||||
uint16 slot; /* which to set, proto or parent */
|
uint16 slot; /* which to set, proto or parent */
|
||||||
uint16 errnum; /* JSMSG_NO_ERROR or error result */
|
JSPackedBool cycle; /* true if a cycle was detected */
|
||||||
JSSetSlotRequest *next; /* next request in GC worklist */
|
JSSetSlotRequest *next; /* next request in GC worklist */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3200,76 +3200,26 @@ js_TriggerGC(JSContext *cx, JSBool gcLocked)
|
|||||||
static void
|
static void
|
||||||
ProcessSetSlotRequest(JSContext *cx, JSSetSlotRequest *ssr)
|
ProcessSetSlotRequest(JSContext *cx, JSSetSlotRequest *ssr)
|
||||||
{
|
{
|
||||||
JSObject *obj, *pobj;
|
JSObject *obj = ssr->obj;
|
||||||
uint32 slot;
|
JSObject *pobj = ssr->pobj;
|
||||||
|
uint32 slot = ssr->slot;
|
||||||
obj = ssr->obj;
|
|
||||||
pobj = ssr->pobj;
|
|
||||||
slot = ssr->slot;
|
|
||||||
|
|
||||||
while (pobj) {
|
while (pobj) {
|
||||||
pobj = js_GetWrappedObject(cx, pobj);
|
pobj = js_GetWrappedObject(cx, pobj);
|
||||||
if (pobj == obj) {
|
if (pobj == obj) {
|
||||||
ssr->errnum = JSMSG_CYCLIC_VALUE;
|
ssr->cycle = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pobj = JSVAL_TO_OBJECT(STOBJ_GET_SLOT(pobj, slot));
|
pobj = JSVAL_TO_OBJECT(STOBJ_GET_SLOT(pobj, slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
pobj = ssr->pobj;
|
pobj = ssr->pobj;
|
||||||
|
if (slot == JSSLOT_PROTO) {
|
||||||
if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) {
|
STOBJ_SET_PROTO(obj, pobj);
|
||||||
JSScope *scope, *newscope;
|
} else {
|
||||||
JSObject *oldproto;
|
JS_ASSERT(slot == JSSLOT_PARENT);
|
||||||
|
STOBJ_SET_PARENT(obj, pobj);
|
||||||
/* Check to see whether obj shares its prototype's scope. */
|
|
||||||
scope = OBJ_SCOPE(obj);
|
|
||||||
oldproto = STOBJ_GET_PROTO(obj);
|
|
||||||
if (oldproto && OBJ_SCOPE(oldproto) == scope) {
|
|
||||||
/* Either obj needs a new empty scope, or it should share pobj's. */
|
|
||||||
if (!pobj ||
|
|
||||||
!OBJ_IS_NATIVE(pobj) ||
|
|
||||||
OBJ_GET_CLASS(cx, pobj) != STOBJ_GET_CLASS(oldproto)) {
|
|
||||||
/*
|
|
||||||
* With no proto and no scope of its own, obj is truly empty.
|
|
||||||
*
|
|
||||||
* If pobj is not native, obj needs its own empty scope -- it
|
|
||||||
* should not continue to share oldproto's scope once oldproto
|
|
||||||
* is not on obj's prototype chain. That would put properties
|
|
||||||
* from oldproto's scope ahead of properties defined by pobj,
|
|
||||||
* in lookup order.
|
|
||||||
*
|
|
||||||
* If pobj's class differs from oldproto's, we may need a new
|
|
||||||
* scope to handle differences in private and reserved slots,
|
|
||||||
* so we suboptimally but safely make one.
|
|
||||||
*/
|
|
||||||
if (!js_GetMutableScope(cx, obj)) {
|
|
||||||
ssr->errnum = JSMSG_OUT_OF_MEMORY;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (OBJ_SCOPE(pobj) != scope) {
|
|
||||||
newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map);
|
|
||||||
obj->map = &newscope->map;
|
|
||||||
js_DropObjectMap(cx, &scope->map, obj);
|
|
||||||
JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Regenerate property cache shape ids for all of the scopes along the
|
|
||||||
* old prototype chain, in case any property cache entries were filled
|
|
||||||
* by looking up starting from obj.
|
|
||||||
*/
|
|
||||||
while (oldproto && OBJ_IS_NATIVE(oldproto)) {
|
|
||||||
scope = OBJ_SCOPE(oldproto);
|
|
||||||
js_MakeScopeShapeUnique(cx, scope);
|
|
||||||
oldproto = STOBJ_GET_PROTO(scope->object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally, do the deed. */
|
|
||||||
STOBJ_SET_SLOT(obj, slot, OBJECT_TO_JSVAL(pobj));
|
|
||||||
STOBJ_SET_DELEGATE(pobj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -240,7 +240,7 @@ obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return js_SetProtoOrParent(cx, obj, slot, pobj);
|
return js_SetProtoOrParent(cx, obj, slot, pobj, JS_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSBool
|
static JSBool
|
||||||
@ -279,45 +279,66 @@ out:
|
|||||||
#endif /* !JS_HAS_OBJ_PROTO_PROP */
|
#endif /* !JS_HAS_OBJ_PROTO_PROP */
|
||||||
|
|
||||||
JSBool
|
JSBool
|
||||||
js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj)
|
js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
|
||||||
|
JSBool checkForCycles)
|
||||||
{
|
{
|
||||||
JSSetSlotRequest ssr;
|
JS_ASSERT(slot == JSSLOT_PARENT || slot == JSSLOT_PROTO);
|
||||||
JSRuntime *rt;
|
JS_ASSERT_IF(!checkForCycles, obj != pobj);
|
||||||
|
|
||||||
/* Optimize the null case to avoid the unnecessary overhead of js_GC. */
|
if (slot == JSSLOT_PROTO) {
|
||||||
if (!pobj) {
|
|
||||||
JS_LOCK_OBJ(cx, obj);
|
|
||||||
if (slot == JSSLOT_PROTO && !js_GetMutableScope(cx, obj)) {
|
|
||||||
JS_UNLOCK_OBJ(cx, obj);
|
|
||||||
return JS_FALSE;
|
|
||||||
}
|
|
||||||
LOCKED_OBJ_SET_SLOT(obj, slot, JSVAL_NULL);
|
|
||||||
JS_UNLOCK_OBJ(cx, obj);
|
JS_UNLOCK_OBJ(cx, obj);
|
||||||
return JS_TRUE;
|
bool ok = !!js_GetMutableScope(cx, obj);
|
||||||
|
JS_UNLOCK_OBJ(cx, obj);
|
||||||
|
if (!ok)
|
||||||
|
return JS_FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Regenerate property cache shape ids for all of the scopes along the
|
||||||
|
* old prototype chain to invalidate their property cache entries, in
|
||||||
|
* case any entries were filled by looking up starting from obj.
|
||||||
|
*/
|
||||||
|
JSObject *oldproto = STOBJ_GET_PROTO(obj);
|
||||||
|
while (oldproto && OBJ_IS_NATIVE(oldproto)) {
|
||||||
|
JS_LOCK_OBJ(cx, oldproto);
|
||||||
|
JSScope *scope = OBJ_SCOPE(oldproto);
|
||||||
|
js_MakeScopeShapeUnique(cx, scope);
|
||||||
|
JSObject *tmp = STOBJ_GET_PROTO(scope->object);
|
||||||
|
JS_UNLOCK_OBJ(cx, oldproto);
|
||||||
|
oldproto = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssr.obj = obj;
|
if (!pobj || !checkForCycles) {
|
||||||
ssr.pobj = pobj;
|
if (slot == JSSLOT_PROTO)
|
||||||
ssr.slot = (uint16) slot;
|
STOBJ_SET_PROTO(obj, pobj);
|
||||||
ssr.errnum = (uint16) JSMSG_NOT_AN_ERROR;
|
else
|
||||||
|
STOBJ_SET_PARENT(obj, pobj);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Use the GC machinery to serialize access to all objects on the
|
||||||
|
* prototype or parent chain.
|
||||||
|
*/
|
||||||
|
JSSetSlotRequest ssr;
|
||||||
|
ssr.obj = obj;
|
||||||
|
ssr.pobj = pobj;
|
||||||
|
ssr.slot = (uint16) slot;
|
||||||
|
ssr.cycle = false;
|
||||||
|
|
||||||
rt = cx->runtime;
|
JSRuntime *rt = cx->runtime;
|
||||||
JS_LOCK_GC(rt);
|
|
||||||
ssr.next = rt->setSlotRequests;
|
|
||||||
rt->setSlotRequests = &ssr;
|
|
||||||
for (;;) {
|
|
||||||
js_GC(cx, GC_SET_SLOT_REQUEST);
|
|
||||||
JS_UNLOCK_GC(rt);
|
|
||||||
if (!rt->setSlotRequests)
|
|
||||||
break;
|
|
||||||
JS_LOCK_GC(rt);
|
JS_LOCK_GC(rt);
|
||||||
}
|
ssr.next = rt->setSlotRequests;
|
||||||
|
rt->setSlotRequests = &ssr;
|
||||||
|
for (;;) {
|
||||||
|
js_GC(cx, GC_SET_SLOT_REQUEST);
|
||||||
|
JS_UNLOCK_GC(rt);
|
||||||
|
if (!rt->setSlotRequests)
|
||||||
|
break;
|
||||||
|
JS_LOCK_GC(rt);
|
||||||
|
}
|
||||||
|
|
||||||
if (ssr.errnum != JSMSG_NOT_AN_ERROR) {
|
if (ssr.cycle) {
|
||||||
if (ssr.errnum == JSMSG_OUT_OF_MEMORY) {
|
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||||
JS_ReportOutOfMemory(cx);
|
JSMSG_CYCLIC_VALUE,
|
||||||
} else {
|
|
||||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, ssr.errnum,
|
|
||||||
#if JS_HAS_OBJ_PROTO_PROP
|
#if JS_HAS_OBJ_PROTO_PROP
|
||||||
object_props[slot].name
|
object_props[slot].name
|
||||||
#else
|
#else
|
||||||
@ -325,8 +346,8 @@ js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj)
|
|||||||
: js_parent_str
|
: js_parent_str
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
return JS_FALSE;
|
|
||||||
}
|
}
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -776,7 +776,8 @@ extern JSBool
|
|||||||
js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
|
js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj);
|
js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
|
||||||
|
JSBool checkForCycles);
|
||||||
|
|
||||||
extern JSBool
|
extern JSBool
|
||||||
js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
|
js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
|
||||||
|
@ -4587,7 +4587,9 @@ TraceRecorder::monitorRecording(JSContext* cx, TraceRecorder* tr, JSOp op)
|
|||||||
bool wasInImacro = (cx->fp->imacpc != NULL);
|
bool wasInImacro = (cx->fp->imacpc != NULL);
|
||||||
#endif
|
#endif
|
||||||
switch (op) {
|
switch (op) {
|
||||||
default: goto stop_recording;
|
default:
|
||||||
|
status = JSRS_ERROR;
|
||||||
|
goto stop_recording;
|
||||||
# define OPDEF(x,val,name,token,length,nuses,ndefs,prec,format) \
|
# define OPDEF(x,val,name,token,length,nuses,ndefs,prec,format) \
|
||||||
case x: \
|
case x: \
|
||||||
status = tr->record_##x(); \
|
status = tr->record_##x(); \
|
||||||
|
Loading…
Reference in New Issue
Block a user