mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-05 08:35:26 +00:00
Root all strings and objects first when unboxing. Then box values that might trigger the GC (doubles/ints). This probably needs some performance tuning over time.
This commit is contained in:
parent
e42a82831b
commit
6f69a35718
@ -668,9 +668,8 @@ box_jsval(JSContext* cx, jsval& v, uint8 t, double* slot)
|
||||
if (JSDOUBLE_IS_INT(d, i))
|
||||
goto store_int;
|
||||
store_double:
|
||||
/* GC is not allowed to hit as we come out of the native frame. We have to teach
|
||||
the GC how to scan native frames to avoid this race condition. */
|
||||
JS_ASSERT(cx->doubleFreeList != NULL);
|
||||
/* Its safe to trigger the GC here since we rooted all strings/objects and all the
|
||||
doubles we already processed. */
|
||||
return js_NewDoubleInRootedValue(cx, d, &v);
|
||||
case JSVAL_STRING:
|
||||
v = STRING_TO_JSVAL(*(JSString**)slot);
|
||||
@ -688,13 +687,15 @@ box_jsval(JSContext* cx, jsval& v, uint8 t, double* slot)
|
||||
/* Attempt to unbox the given JS frame into a native frame, checking along the way that the
|
||||
supplied typemap holds. */
|
||||
static bool
|
||||
unbox(JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* m, double* native)
|
||||
unbox(JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* map, double* native)
|
||||
{
|
||||
verbose_only(printf("unbox native@%p ", native);)
|
||||
double* np = native;
|
||||
uint8* mp = map;
|
||||
FORALL_SLOTS_IN_PENDING_FRAMES(entryFrame, currentFrame,
|
||||
if (vp && !unbox_jsval(*vp, *m, native))
|
||||
if (vp && !unbox_jsval(*vp, *mp, np))
|
||||
return false;
|
||||
++m; ++native
|
||||
++mp; ++np;
|
||||
);
|
||||
verbose_only(printf("\n");)
|
||||
return true;
|
||||
@ -703,13 +704,26 @@ unbox(JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* m, double* na
|
||||
/* Box the given native frame into a JS frame. This only fails due to a hard error
|
||||
(out of memory for example). */
|
||||
static bool
|
||||
box(JSContext* cx, JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* m, double* native)
|
||||
box(JSContext* cx, JSStackFrame* entryFrame, JSStackFrame* currentFrame, uint8* map, double* native)
|
||||
{
|
||||
verbose_only(printf("box native@%p ", native);)
|
||||
double* np = native;
|
||||
uint8* mp = map;
|
||||
/* Root all string and object references first (we don't need to call the GC for this). */
|
||||
FORALL_SLOTS_IN_PENDING_FRAMES(entryFrame, currentFrame,
|
||||
if (vp && !box_jsval(cx, *vp, *m, native))
|
||||
if (vp && (*mp == JSVAL_STRING || *mp == JSVAL_OBJECT) && !box_jsval(cx, *vp, *mp, np))
|
||||
return false;
|
||||
++m; ++native
|
||||
++mp; ++np
|
||||
);
|
||||
/* Now do this again but this time for all values (properly quicker than actually checking
|
||||
the type and excluding strings and objects). The GC might kick in when we store doubles,
|
||||
but everything is rooted now (all strings/objects and all doubles we already boxed). */
|
||||
np = native;
|
||||
mp = map;
|
||||
FORALL_SLOTS_IN_PENDING_FRAMES(entryFrame, currentFrame,
|
||||
if (vp && !box_jsval(cx, *vp, *mp, np))
|
||||
return false;
|
||||
++mp; ++np
|
||||
);
|
||||
verbose_only(printf("\n");)
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user