bug 452913 - fixing sprop management, r=brendan, a.9.1b2=sayer

This commit is contained in:
Igor Bukanov 2008-11-17 13:59:39 +01:00
parent a76c374322
commit b31f8300ea
5 changed files with 22 additions and 6 deletions

View File

@ -3675,7 +3675,7 @@ out:
goto restart;
}
if (rt->shapeGen & SHAPE_OVERFLOW_BIT) {
if (rt->shapeGen >= SHAPE_OVERFLOW_BIT - 1) {
/*
* FIXME bug 440834: The shape id space has overflowed. Currently we
* cope badly with this. Every call to js_GenerateShape does GC, and

View File

@ -85,17 +85,22 @@
#if !JS_LONE_INTERPRET ^ defined jsinvoke_cpp___
uint32
js_GenerateShape(JSContext *cx, JSBool gcLocked)
js_GenerateShape(JSContext *cx, JSBool gcLocked, JSScopeProperty *sprop)
{
JSRuntime *rt;
uint32 shape;
JSTempValueRooter tvr;
rt = cx->runtime;
shape = JS_ATOMIC_INCREMENT(&rt->shapeGen);
JS_ASSERT(shape != 0);
if (shape & SHAPE_OVERFLOW_BIT) {
rt->gcPoke = JS_TRUE;
if (sprop)
JS_PUSH_TEMP_ROOT_SPROP(cx, sprop, &tvr);
js_GC(cx, gcLocked ? GC_LOCK_HELD : GC_NORMAL);
if (sprop)
JS_POP_TEMP_ROOT(cx, &tvr);
shape = JS_ATOMIC_INCREMENT(&rt->shapeGen);
JS_ASSERT(shape != 0);
JS_ASSERT_IF(shape & SHAPE_OVERFLOW_BIT,

View File

@ -198,8 +198,12 @@ typedef struct JSInlineFrame {
#define SHAPE_OVERFLOW_BIT JS_BIT(32 - PCVCAP_TAGBITS)
/*
* When sprop is not null and the shape generation triggers the GC due to a
* shape overflow, the functions roots sprop.
*/
extern uint32
js_GenerateShape(JSContext *cx, JSBool gcLocked);
js_GenerateShape(JSContext *cx, JSBool gcLocked, JSScopeProperty *sprop);
struct JSPropCacheEntry {
jsbytecode *kpc; /* pc if vcap tag is <= 1, else atom */

View File

@ -809,6 +809,7 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
JSScopeProperty *sprop;
PropTreeKidsChunk *chunk;
uintN i, n;
uint32 shape;
rt = cx->runtime;
if (!parent) {
@ -895,6 +896,12 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
}
locked_not_found:
/*
* Call js_GenerateShape before the allocation to prevent collecting the
* new property when the shape generation triggers the GC.
*/
shape = js_GenerateShape(cx, JS_TRUE, NULL);
sprop = NewScopeProperty(rt);
if (!sprop)
goto out_of_memory;
@ -907,7 +914,7 @@ locked_not_found:
sprop->flags = child->flags;
sprop->shortid = child->shortid;
sprop->parent = sprop->kids = NULL;
sprop->shape = js_GenerateShape(cx, JS_TRUE);
sprop->shape = shape;
if (!parent) {
entry->child = sprop;

View File

@ -221,7 +221,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
#define OBJ_SHAPE(obj) (OBJ_SCOPE(obj)->shape)
#define SCOPE_MAKE_UNIQUE_SHAPE(cx,scope) \
((scope)->shape = js_GenerateShape((cx), JS_FALSE))
((scope)->shape = js_GenerateShape((cx), JS_FALSE, NULL))
#define SCOPE_EXTEND_SHAPE(cx,scope,sprop) \
JS_BEGIN_MACRO \
@ -229,7 +229,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
(scope)->shape == (scope)->lastProp->shape) { \
(scope)->shape = (sprop)->shape; \
} else { \
(scope)->shape = js_GenerateShape((cx), JS_FALSE); \
(scope)->shape = js_GenerateShape((cx), JS_FALSE, sprop); \
} \
JS_END_MACRO