From b3c2bc5d8c7ca7c58afa2f63ee9230eb4b3e485c Mon Sep 17 00:00:00 2001 From: "sayrer%gmail.com" Date: Wed, 7 Jan 2009 04:31:52 +0000 Subject: [PATCH] Bug 452913. Patch by Igor Bukanov git-svn-id: svn://10.0.0.236/trunk@255739 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsgc.c | 2 +- mozilla/js/src/jsinterp.c | 7 ++++++- mozilla/js/src/jsinterp.h | 6 +++++- mozilla/js/src/jsscope.c | 9 ++++++++- mozilla/js/src/jsscope.h | 4 ++-- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/mozilla/js/src/jsgc.c b/mozilla/js/src/jsgc.c index 5d51bd7d3bd..a8ad2830b23 100644 --- a/mozilla/js/src/jsgc.c +++ b/mozilla/js/src/jsgc.c @@ -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; diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index b46783c5173..bf13e4f6c3f 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -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, diff --git a/mozilla/js/src/jsinterp.h b/mozilla/js/src/jsinterp.h index 7fb54660a74..2bd746ee683 100644 --- a/mozilla/js/src/jsinterp.h +++ b/mozilla/js/src/jsinterp.h @@ -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 */ diff --git a/mozilla/js/src/jsscope.c b/mozilla/js/src/jsscope.c index db5bab41ab0..2e609dbdc86 100644 --- a/mozilla/js/src/jsscope.c +++ b/mozilla/js/src/jsscope.c @@ -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; diff --git a/mozilla/js/src/jsscope.h b/mozilla/js/src/jsscope.h index 7f181dd2f22..fc5c5da24b1 100644 --- a/mozilla/js/src/jsscope.h +++ b/mozilla/js/src/jsscope.h @@ -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