Backout 784ceadd60e5 until PGO stops crashing
This commit is contained in:
@@ -1467,26 +1467,46 @@ array_toSource(JSContext *cx, uintN argc, jsval *vp)
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSHashNumber
|
||||
js_hash_array(const void *key)
|
||||
{
|
||||
return (JSHashNumber)JS_PTR_TO_UINT32(key) >> JSVAL_TAGBITS;
|
||||
}
|
||||
|
||||
bool
|
||||
js_InitContextBusyArrayTable(JSContext *cx)
|
||||
{
|
||||
cx->busyArrayTable = JS_NewHashTable(4, js_hash_array, JS_CompareValues,
|
||||
JS_CompareValues, NULL, NULL);
|
||||
return cx->busyArrayTable != NULL;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
|
||||
JSString *sepstr, jsval *rval)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
/*
|
||||
* This hash table is shared between toString invocations and must be empty
|
||||
* after the root invocation completes.
|
||||
*/
|
||||
JSHashTable *table = cx->busyArrayTable;
|
||||
|
||||
/*
|
||||
* Use HashTable entry as the cycle indicator. On first visit, create the
|
||||
* entry, and, when leaving, remove the entry.
|
||||
*/
|
||||
typedef js::HashSet<JSObject *> ObjSet;
|
||||
ObjSet::AddPtr hashp = cx->busyArrays.lookupForAdd(obj);
|
||||
uint32 genBefore;
|
||||
if (!hashp) {
|
||||
JSHashNumber hash = js_hash_array(obj);
|
||||
JSHashEntry **hep = JS_HashTableRawLookup(table, hash, obj);
|
||||
JSHashEntry *he = *hep;
|
||||
if (!he) {
|
||||
/* Not in hash table, so not a cycle. */
|
||||
if (!cx->busyArrays.add(hashp, obj)) {
|
||||
he = JS_HashTableRawAdd(table, hep, hash, obj, NULL);
|
||||
if (!he) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
genBefore = cx->busyArrays.generation();
|
||||
} else {
|
||||
/* Cycle, so return empty string. */
|
||||
*rval = ATOM_KEY(cx->runtime->atomState.emptyAtom);
|
||||
@@ -1560,10 +1580,11 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
|
||||
ok = true;
|
||||
|
||||
out:
|
||||
if (genBefore == cx->busyArrays.generation())
|
||||
cx->busyArrays.remove(hashp);
|
||||
else
|
||||
cx->busyArrays.remove(obj);
|
||||
/*
|
||||
* It is possible that 'hep' may have been invalidated by subsequent
|
||||
* RawAdd/Remove. Hence, 'RawRemove' must not be used.
|
||||
*/
|
||||
JS_HashTableRemove(table, obj);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user