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:
parent
9e109519a4
commit
b3c2bc5d8c
@ -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;
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user