Bug 340129: Bulletproof rooting of objects during sharp graph construction/usage. r=mrbkap

This commit is contained in:
igor.bukanov%gmail.com 2006-06-15 10:14:42 +00:00
Родитель 97c415e6cf
Коммит 640729a776
3 изменённых файлов: 46 добавлений и 0 удалений

Просмотреть файл

@ -2289,6 +2289,9 @@ restart:
}
}
if (acx->sharpObjectMap.depth > 0)
js_GCMarkSharpMap(cx, &acx->sharpObjectMap);
acx->cachedIterObj = NULL;
}

Просмотреть файл

@ -648,6 +648,42 @@ js_LeaveSharpObject(JSContext *cx, JSIdArray **idap)
}
}
JS_STATIC_DLL_CALLBACK(intN)
gc_sharp_table_entry_marker(JSHashEntry *he, intN i, void *arg)
{
GC_MARK((JSContext *)arg, (JSObject *)he->key, "sharp table entry");
return JS_DHASH_NEXT;
}
void
js_GCMarkSharpMap(JSContext *cx, JSSharpObjectMap *map)
{
JS_ASSERT(map->depth > 0);
JS_ASSERT(map->table);
/*
* During recursive calls to MarkSharpObjects a non-native object or
* object with a custom getProperty method can potentially return an
* unrooted value or even cut from the object graph an argument of one of
* MarkSharpObjects recursive invocations. So we must protect map->table
* entries against GC.
*
* We can not simply use JSTempValueRooter to mark the obj argument of
* MarkSharpObjects during recursion as we have to protect *all* entries
* in JSSharpObjectMap including those that contains otherwise unreachable
* objects just allocated through custom getProperty. Otherwise newer
* allocations can re-use the address of an object stored in the hashtable
* confusing js_EnterSharpObject. So to address the problem we simply
* mark all objects from map->table.
*
* An alternative "proper" solution is to use JSTempValueRooter in
* MarkSharpObjects with code to remove during finalization entries
* with otherwise unreachable objects. But this is way too complex
* to justify spending efforts.
*/
JS_HashTableEnumerateEntries(map->table, gc_sharp_table_entry_marker, cx);
}
#define OBJ_TOSTRING_EXTRA 4 /* for 4 local GC roots */
#if JS_HAS_TOSOURCE

Просмотреть файл

@ -304,6 +304,13 @@ js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
extern void
js_LeaveSharpObject(JSContext *cx, JSIdArray **idap);
/*
* Mark objects stored in map if GC happens between js_EnterSharpObject
* and js_LeaveSharpObject. GC calls this when map->depth > 0.
*/
extern void
js_GCMarkSharpMap(JSContext *cx, JSSharpObjectMap *map);
extern JSBool
js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval *rval);