Bug 452913. Patch by Igor Bukanov <igor@mir2.org>

git-svn-id: svn://10.0.0.236/trunk@255739 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
sayrer%gmail.com 2009-01-07 04:31:52 +00:00
parent 9e109519a4
commit b3c2bc5d8c
5 changed files with 22 additions and 6 deletions

View File

@ -3479,7 +3479,7 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind)
goto restart;
}
if (!(rt->shapeGen & SHAPE_OVERFLOW_BIT)) {
if (rt->shapeGen < SHAPE_OVERFLOW_BIT - 1) {
js_EnablePropertyCache(cx);
#ifdef JS_THREADSAFE
iter = NULL;

View File

@ -80,17 +80,22 @@
#ifdef js_invoke_c__
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

@ -162,8 +162,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

@ -220,7 +220,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map)
#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 \
@ -228,7 +228,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