Backout 00f2e1e9adc2 after mq malfunction.

This commit is contained in:
Terrence Cole 2012-03-29 17:52:45 -07:00
parent 2f9cd7725c
commit 2c0bc63017
10 changed files with 71 additions and 49 deletions

View File

@ -245,11 +245,9 @@ struct JSCountHeapNode {
JSCountHeapNode *next; JSCountHeapNode *next;
}; };
typedef HashSet<void *, PointerHasher<void *, 3>, SystemAllocPolicy> VisitedSet;
typedef struct JSCountHeapTracer { typedef struct JSCountHeapTracer {
JSTracer base; JSTracer base;
VisitedSet visited; JSDHashTable visited;
bool ok; bool ok;
JSCountHeapNode *traceList; JSCountHeapNode *traceList;
JSCountHeapNode *recycleList; JSCountHeapNode *recycleList;
@ -258,24 +256,27 @@ typedef struct JSCountHeapTracer {
static void static void
CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) CountHeapNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{ {
JS_ASSERT(trc->callback == CountHeapNotify); JSCountHeapTracer *countTracer;
JSDHashEntryStub *entry;
JSCountHeapTracer *countTracer = (JSCountHeapTracer *)trc; JSCountHeapNode *node;
void *thing = *thingp; void *thing = *thingp;
JS_ASSERT(trc->callback == CountHeapNotify);
countTracer = (JSCountHeapTracer *)trc;
if (!countTracer->ok) if (!countTracer->ok)
return; return;
VisitedSet::AddPtr p = countTracer->visited.lookupForAdd(thing); entry = (JSDHashEntryStub *)
if (p) JS_DHashTableOperate(&countTracer->visited, thing, JS_DHASH_ADD);
return; if (!entry) {
if (!countTracer->visited.add(p, thing)) {
countTracer->ok = false; countTracer->ok = false;
return; return;
} }
if (entry->key)
return;
entry->key = thing;
JSCountHeapNode *node = countTracer->recycleList; node = countTracer->recycleList;
if (node) { if (node) {
countTracer->recycleList = node->next; countTracer->recycleList = node->next;
} else { } else {
@ -353,7 +354,9 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
} }
JS_TracerInit(&countTracer.base, JS_GetRuntime(cx), CountHeapNotify); JS_TracerInit(&countTracer.base, JS_GetRuntime(cx), CountHeapNotify);
if (!countTracer.visited.init()) { if (!JS_DHashTableInit(&countTracer.visited, JS_DHashGetStubOps(),
NULL, sizeof(JSDHashEntryStub),
JS_DHASH_DEFAULT_CAPACITY(100))) {
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return JS_FALSE; return JS_FALSE;
} }
@ -381,6 +384,7 @@ CountHeap(JSContext *cx, unsigned argc, jsval *vp)
countTracer.recycleList = node->next; countTracer.recycleList = node->next;
js_free(node); js_free(node);
} }
JS_DHashTableFinish(&countTracer.visited);
if (!countTracer.ok) { if (!countTracer.ok) {
JS_ReportOutOfMemory(cx); JS_ReportOutOfMemory(cx);
return false; return false;

View File

@ -86,6 +86,10 @@
#include "jsxml.h" #include "jsxml.h"
#endif #endif
#if JS_HAS_DESTRUCTURING
#include "jsdhash.h"
#endif
#include "jsatominlines.h" #include "jsatominlines.h"
#include "jsscriptinlines.h" #include "jsscriptinlines.h"

View File

@ -49,6 +49,7 @@
#include "jstypes.h" #include "jstypes.h"
#include "jsutil.h" #include "jsutil.h"
#include "jsclist.h" #include "jsclist.h"
#include "jsdhash.h"
#include "jsprf.h" #include "jsprf.h"
#include "jsapi.h" #include "jsapi.h"
#include "jsarray.h" #include "jsarray.h"
@ -2607,11 +2608,9 @@ struct JSHeapDumpNode {
into thing */ into thing */
}; };
typedef HashSet<void *, PointerHasher<void *, 3>, SystemAllocPolicy> VisitedSet;
typedef struct JSDumpingTracer { typedef struct JSDumpingTracer {
JSTracer base; JSTracer base;
VisitedSet visited; JSDHashTable visited;
bool ok; bool ok;
void *startThing; void *startThing;
void *thingToFind; void *thingToFind;
@ -2624,10 +2623,12 @@ typedef struct JSDumpingTracer {
static void static void
DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind) DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{ {
JS_ASSERT(trc->callback == DumpNotify);
JSDumpingTracer *dtrc = (JSDumpingTracer *)trc;
void *thing = *thingp; void *thing = *thingp;
JSDumpingTracer *dtrc;
JSDHashEntryStub *entry;
JS_ASSERT(trc->callback == DumpNotify);
dtrc = (JSDumpingTracer *)trc;
if (!dtrc->ok || thing == dtrc->thingToIgnore) if (!dtrc->ok || thing == dtrc->thingToIgnore)
return; return;
@ -2649,13 +2650,15 @@ DumpNotify(JSTracer *trc, void **thingp, JSGCTraceKind kind)
*/ */
if (thing == dtrc->startThing) if (thing == dtrc->startThing)
return; return;
VisitedSet::AddPtr p = dtrc->visited.lookupForAdd(thing); entry = (JSDHashEntryStub *)
if (p) JS_DHashTableOperate(&dtrc->visited, thing, JS_DHASH_ADD);
return; if (!entry) {
if (!dtrc->visited.add(p, thing)) {
dtrc->ok = false; dtrc->ok = false;
return; return;
} }
if (entry->key)
return;
entry->key = thing;
} }
const char *edgeName = JS_GetTraceEdgeName(&dtrc->base, dtrc->buffer, sizeof(dtrc->buffer)); const char *edgeName = JS_GetTraceEdgeName(&dtrc->base, dtrc->buffer, sizeof(dtrc->buffer));
@ -2747,20 +2750,26 @@ JS_PUBLIC_API(JSBool)
JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind startKind, JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind startKind,
void *thingToFind, size_t maxDepth, void *thingToIgnore) void *thingToFind, size_t maxDepth, void *thingToIgnore)
{ {
if (maxDepth == 0)
return true;
JSDumpingTracer dtrc; JSDumpingTracer dtrc;
if (!dtrc.visited.init()) { JSHeapDumpNode *node, *children, *next, *parent;
size_t depth;
JSBool thingToFindWasTraced;
if (maxDepth == 0)
return JS_TRUE;
JS_TracerInit(&dtrc.base, rt, DumpNotify);
if (!JS_DHashTableInit(&dtrc.visited, JS_DHashGetStubOps(),
NULL, sizeof(JSDHashEntryStub),
JS_DHASH_DEFAULT_CAPACITY(100))) {
return false; return false;
} }
JS_TracerInit(&dtrc.base, rt, DumpNotify);
dtrc.ok = JS_TRUE; dtrc.ok = JS_TRUE;
dtrc.startThing = startThing; dtrc.startThing = startThing;
dtrc.thingToFind = thingToFind; dtrc.thingToFind = thingToFind;
dtrc.thingToIgnore = thingToIgnore; dtrc.thingToIgnore = thingToIgnore;
dtrc.parentNode = NULL; dtrc.parentNode = NULL;
JSHeapDumpNode *node = NULL; node = NULL;
dtrc.lastNodep = &node; dtrc.lastNodep = &node;
if (!startThing) { if (!startThing) {
JS_ASSERT(startKind == JSTRACE_OBJECT); JS_ASSERT(startKind == JSTRACE_OBJECT);
@ -2769,12 +2778,11 @@ JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind startKind,
JS_TraceChildren(&dtrc.base, startThing, startKind); JS_TraceChildren(&dtrc.base, startThing, startKind);
} }
size_t depth = 1; depth = 1;
if (!node) if (!node)
return dtrc.ok; goto dump_out;
JSHeapDumpNode *children, *next, *parent; thingToFindWasTraced = thingToFind && thingToFind == startThing;
bool thingToFindWasTraced = thingToFind && thingToFind == startThing;
for (;;) { for (;;) {
/* /*
* Loop must continue even when !dtrc.ok to free all nodes allocated * Loop must continue even when !dtrc.ok to free all nodes allocated
@ -2811,14 +2819,16 @@ JS_DumpHeap(JSRuntime *rt, FILE *fp, void* startThing, JSGCTraceKind startKind,
if (node) if (node)
break; break;
if (!parent) if (!parent)
return dtrc.ok; goto dump_out;
JS_ASSERT(depth > 1); JS_ASSERT(depth > 1);
--depth; --depth;
node = parent; node = parent;
} }
} }
dump_out:
JS_ASSERT(depth == 1); JS_ASSERT(depth == 1);
JS_DHashTableFinish(&dtrc.visited);
return dtrc.ok; return dtrc.ok;
} }

View File

@ -52,6 +52,7 @@
#include "jsprvtd.h" #include "jsprvtd.h"
#include "jsatom.h" #include "jsatom.h"
#include "jsclist.h" #include "jsclist.h"
#include "jsdhash.h"
#include "jsgc.h" #include "jsgc.h"
#include "jspropertycache.h" #include "jspropertycache.h"
#include "jspropertytree.h" #include "jspropertytree.h"

View File

@ -968,7 +968,7 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
{ {
size_t nbytes; size_t nbytes;
nbytes = sizeof(AtomStateEntry) + sizeof(HashNumber); nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
nbytes += sizeof(JSString); nbytes += sizeof(JSString);
nbytes += (atom->length() + 1) * sizeof(jschar); nbytes += (atom->length() + 1) * sizeof(jschar);
return nbytes; return nbytes;

View File

@ -51,6 +51,7 @@
#include "jstypes.h" #include "jstypes.h"
#include "jsprvtd.h" #include "jsprvtd.h"
#include "jspubtd.h" #include "jspubtd.h"
#include "jsdhash.h"
#include "jslock.h" #include "jslock.h"
#include "jsutil.h" #include "jsutil.h"
#include "jsversion.h" #include "jsversion.h"

View File

@ -49,6 +49,7 @@
#include "jstypes.h" #include "jstypes.h"
#include "jsutil.h" #include "jsutil.h"
#include "jshash.h" #include "jshash.h"
#include "jsdhash.h"
#include "jsprf.h" #include "jsprf.h"
#include "jsapi.h" #include "jsapi.h"
#include "jsarray.h" #include "jsarray.h"

View File

@ -46,6 +46,7 @@
#include <string.h> #include <string.h>
#include "jstypes.h" #include "jstypes.h"
#include "jsclist.h" #include "jsclist.h"
#include "jsdhash.h"
#include "jsutil.h" #include "jsutil.h"
#include "jsapi.h" #include "jsapi.h"
#include "jsatom.h" #include "jsatom.h"
@ -88,7 +89,7 @@ PropertyTable::init(JSRuntime *rt, Shape *lastProp)
if (!entries) if (!entries)
return false; return false;
hashShift = HASH_BITS - sizeLog2; hashShift = JS_DHASH_BITS - sizeLog2;
for (Shape::Range r = lastProp->all(); !r.empty(); r.popFront()) { for (Shape::Range r = lastProp->all(); !r.empty(); r.popFront()) {
const Shape &shape = r.front(); const Shape &shape = r.front();
Shape **spp = search(shape.propid(), true); Shape **spp = search(shape.propid(), true);
@ -201,7 +202,7 @@ PropertyTable::search(jsid id, bool adding)
return spp; return spp;
/* Collision: double hash. */ /* Collision: double hash. */
sizeLog2 = HASH_BITS - hashShift; sizeLog2 = JS_DHASH_BITS - hashShift;
hash2 = HASH2(hash0, sizeLog2, hashShift); hash2 = HASH2(hash0, sizeLog2, hashShift);
sizeMask = JS_BITMASK(sizeLog2); sizeMask = JS_BITMASK(sizeLog2);
@ -260,7 +261,7 @@ PropertyTable::change(int log2Delta, JSContext *cx)
/* /*
* Grow, shrink, or compress by changing this->entries. * Grow, shrink, or compress by changing this->entries.
*/ */
int oldlog2 = HASH_BITS - hashShift; int oldlog2 = JS_DHASH_BITS - hashShift;
int newlog2 = oldlog2 + log2Delta; int newlog2 = oldlog2 + log2Delta;
uint32_t oldsize = JS_BIT(oldlog2); uint32_t oldsize = JS_BIT(oldlog2);
uint32_t newsize = JS_BIT(newlog2); uint32_t newsize = JS_BIT(newlog2);
@ -269,7 +270,7 @@ PropertyTable::change(int log2Delta, JSContext *cx)
return false; return false;
/* Now that we have newTable allocated, update members. */ /* Now that we have newTable allocated, update members. */
hashShift = HASH_BITS - newlog2; hashShift = JS_DHASH_BITS - newlog2;
removedCount = 0; removedCount = 0;
Shape **oldTable = entries; Shape **oldTable = entries;
entries = newTable; entries = newTable;
@ -1150,7 +1151,7 @@ Shape::setObjectFlag(JSContext *cx, BaseShape::Flag flag, JSObject *proto, Shape
/* static */ inline HashNumber /* static */ inline HashNumber
StackBaseShape::hash(const StackBaseShape *base) StackBaseShape::hash(const StackBaseShape *base)
{ {
HashNumber hash = base->flags; JSDHashNumber hash = base->flags;
hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->clasp) >> 3); hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->clasp) >> 3);
hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->parent) >> 3); hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(base->parent) >> 3);
hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawGetter); hash = JS_ROTATE_LEFT32(hash, 4) ^ uintptr_t(base->rawGetter);
@ -1287,7 +1288,7 @@ Bindings::setParent(JSContext *cx, JSObject *obj)
/* static */ inline HashNumber /* static */ inline HashNumber
InitialShapeEntry::hash(const Lookup &lookup) InitialShapeEntry::hash(const Lookup &lookup)
{ {
HashNumber hash = uintptr_t(lookup.clasp) >> 3; JSDHashNumber hash = uintptr_t(lookup.clasp) >> 3;
hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.proto) >> 3); hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.proto) >> 3);
hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.parent) >> 3); hash = JS_ROTATE_LEFT32(hash, 4) ^ (uintptr_t(lookup.parent) >> 3);
return hash + lookup.nfixed; return hash + lookup.nfixed;

View File

@ -48,6 +48,7 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
#include "jsdhash.h"
#include "jsobj.h" #include "jsobj.h"
#include "jspropertytree.h" #include "jspropertytree.h"
#include "jstypes.h" #include "jstypes.h"
@ -135,11 +136,10 @@ static const uint32_t SHAPE_INVALID_SLOT = JS_BIT(24) - 1;
static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2; static const uint32_t SHAPE_MAXIMUM_SLOT = JS_BIT(24) - 2;
/* /*
* Shapes use multiplicative hashing, but specialized to * Shapes use multiplicative hashing, _a la_ jsdhash.[ch], but specialized to
* minimize footprint. * minimize footprint.
*/ */
struct PropertyTable { struct PropertyTable {
static const uint32_t HASH_BITS = tl::BitSize<HashNumber>::result;
static const uint32_t MIN_ENTRIES = 7; static const uint32_t MIN_ENTRIES = 7;
static const uint32_t MIN_SIZE_LOG2 = 4; static const uint32_t MIN_SIZE_LOG2 = 4;
static const uint32_t MIN_SIZE = JS_BIT(MIN_SIZE_LOG2); static const uint32_t MIN_SIZE = JS_BIT(MIN_SIZE_LOG2);
@ -154,7 +154,7 @@ struct PropertyTable {
js::Shape **entries; /* table of ptrs to shared tree nodes */ js::Shape **entries; /* table of ptrs to shared tree nodes */
PropertyTable(uint32_t nentries) PropertyTable(uint32_t nentries)
: hashShift(HASH_BITS - MIN_SIZE_LOG2), : hashShift(JS_DHASH_BITS - MIN_SIZE_LOG2),
entryCount(nentries), entryCount(nentries),
removedCount(0), removedCount(0),
freelist(SHAPE_INVALID_SLOT) freelist(SHAPE_INVALID_SLOT)
@ -166,8 +166,8 @@ struct PropertyTable {
js::UnwantedForeground::free_(entries); js::UnwantedForeground::free_(entries);
} }
/* By definition, hashShift = HASH_BITS - log2(capacity). */ /* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */
uint32_t capacity() const { return JS_BIT(HASH_BITS - hashShift); } uint32_t capacity() const { return JS_BIT(JS_DHASH_BITS - hashShift); }
/* Computes the size of the entries array for a given capacity. */ /* Computes the size of the entries array for a given capacity. */
static size_t sizeOfEntries(size_t cap) { return cap * sizeof(Shape *); } static size_t sizeOfEntries(size_t cap) { return cap * sizeof(Shape *); }
@ -999,7 +999,7 @@ struct StackShape
slot_ = slot; slot_ = slot;
} }
inline HashNumber hash() const; inline JSDHashNumber hash() const;
}; };
/* Rooter for stack allocated shapes. */ /* Rooter for stack allocated shapes. */

View File

@ -236,10 +236,10 @@ Shape::Shape(UnownedBaseShape *base, uint32_t nfixed)
kids.setNull(); kids.setNull();
} }
inline HashNumber inline JSDHashNumber
StackShape::hash() const StackShape::hash() const
{ {
HashNumber hash = uintptr_t(base); JSDHashNumber hash = uintptr_t(base);
/* Accumulate from least to most random so the low bits are most random. */ /* Accumulate from least to most random so the low bits are most random. */
hash = JS_ROTATE_LEFT32(hash, 4) ^ (flags & Shape::PUBLIC_FLAGS); hash = JS_ROTATE_LEFT32(hash, 4) ^ (flags & Shape::PUBLIC_FLAGS);