Bug 820390 - Implement AutoHashMapRooter and AutoObjectObjectHashMap. r=terrence

--HG--
extra : rebase_source : 5b6950ddae603ccdfabb7a6de0cd46b5c3d6331f
This commit is contained in:
Till Schneidereit 2012-12-13 22:50:56 +01:00
parent a49d89e708
commit 12dcc64b1c
3 changed files with 160 additions and 11 deletions

View File

@ -531,6 +531,17 @@ AutoGCRooter::trace(JSTracer *trc)
return; return;
} }
case OBJOBJHASHMAP: {
AutoObjectObjectHashMap::HashMapImpl &map = static_cast<AutoObjectObjectHashMap *>(this)->map;
for (AutoObjectObjectHashMap::Enum e(map); !e.empty(); e.popFront()) {
RawObject key = e.front().key;
MarkObjectRoot(trc, (RawObject *) &e.front().key, "AutoObjectObjectHashMap key");
JS_ASSERT(key == e.front().key);
MarkObjectRoot(trc, &e.front().value, "AutoObjectObjectHashMap value");
}
return;
}
case PROPDESC: { case PROPDESC: {
PropDesc::AutoRooter *rooter = static_cast<PropDesc::AutoRooter *>(this); PropDesc::AutoRooter *rooter = static_cast<PropDesc::AutoRooter *>(this);
MarkValueRoot(trc, &rooter->pd->pd_, "PropDesc::AutoRooter pd"); MarkValueRoot(trc, &rooter->pd->pd_, "PropDesc::AutoRooter pd");

View File

@ -31,6 +31,7 @@
#include "jsalloc.h" #include "jsalloc.h"
#include "js/Vector.h" #include "js/Vector.h"
#include "js/HashTable.h"
/************************************************************************/ /************************************************************************/
@ -1041,7 +1042,7 @@ class JS_PUBLIC_API(AutoGCRooter) {
*stackTop = down; *stackTop = down;
} }
/* Implemented in jsgc.cpp. */ /* Implemented in gc/RootMarking.cpp. */
inline void trace(JSTracer *trc); inline void trace(JSTracer *trc);
static void traceAll(JSTracer *trc); static void traceAll(JSTracer *trc);
static void traceAllWrappers(JSTracer *trc); static void traceAllWrappers(JSTracer *trc);
@ -1087,7 +1088,8 @@ class JS_PUBLIC_API(AutoGCRooter) {
IONMASM = -28, /* js::ion::MacroAssembler */ IONMASM = -28, /* js::ion::MacroAssembler */
IONALLOC = -29, /* js::ion::AutoTempAllocatorRooter */ IONALLOC = -29, /* js::ion::AutoTempAllocatorRooter */
WRAPVECTOR = -30, /* js::AutoWrapperVector */ WRAPVECTOR = -30, /* js::AutoWrapperVector */
WRAPPER = -31 /* js::AutoWrapperRooter */ WRAPPER = -31, /* js::AutoWrapperRooter */
OBJOBJHASHMAP=-32 /* js::AutoObjectObjectHashMap */
}; };
private: private:
@ -1328,6 +1330,129 @@ class AutoVectorRooter : protected AutoGCRooter
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
template<class Key, class Value>
class AutoHashMapRooter : protected AutoGCRooter
{
private:
typedef js::HashMap<Key, Value> HashMapImpl;
public:
explicit AutoHashMapRooter(JSContext *cx, ptrdiff_t tag
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, tag), map(cx)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
typedef Key KeyType;
typedef Value ValueType;
typedef typename HashMapImpl::Lookup Lookup;
typedef typename HashMapImpl::Ptr Ptr;
typedef typename HashMapImpl::AddPtr AddPtr;
bool init(uint32_t len = 16) {
return map.init(len);
}
bool initialized() const {
return map.initialized();
}
Ptr lookup(const Lookup &l) const {
return map.lookup(l);
}
void remove(Ptr p) {
map.remove(p);
}
AddPtr lookupForAdd(const Lookup &l) const {
return map.lookupForAdd(l);
}
template<typename KeyInput, typename ValueInput>
bool add(AddPtr &p, const KeyInput &k, const ValueInput &v) {
return map.add(k, v);
}
bool add(AddPtr &p, const Key &k) {
return map.add(p, k);
}
template<typename KeyInput, typename ValueInput>
bool relookupOrAdd(AddPtr &p, const KeyInput &k, const ValueInput &v) {
return map.relookupOrAdd(p, k, v);
}
typedef typename HashMapImpl::Range Range;
Range all() const {
return map.all();
}
typedef typename HashMapImpl::Enum Enum;
void clear() {
map.clear();
}
void finish() {
map.finish();
}
bool empty() const {
return map.empty();
}
uint32_t count() const {
return map.count();
}
size_t capacity() const {
return map.capacity();
}
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
return map.sizeOfExcludingThis(mallocSizeOf);
}
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
return map.sizeOfIncludingThis(mallocSizeOf);
}
unsigned generation() const {
return map.generation();
}
/************************************************** Shorthand operations */
bool has(const Lookup &l) const {
return map.has(l);
}
template<typename KeyInput, typename ValueInput>
bool put(const KeyInput &k, const ValueInput &v) {
return map.put(k, v);
}
template<typename KeyInput, typename ValueInput>
bool putNew(const KeyInput &k, const ValueInput &v) {
return map.putNew(k, v);
}
Ptr lookupWithDefault(const Key &k, const Value &defaultValue) {
return map.lookupWithDefault(k, defaultValue);
}
void remove(const Lookup &l) {
map.remove(l);
}
friend void AutoGCRooter::trace(JSTracer *trc);
private:
AutoHashMapRooter(const AutoHashMapRooter &hmr) MOZ_DELETE;
AutoHashMapRooter &operator=(const AutoHashMapRooter &hmr) MOZ_DELETE;
HashMapImpl map;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoValueVector : public AutoVectorRooter<Value> class AutoValueVector : public AutoVectorRooter<Value>
{ {
public: public:

View File

@ -2097,12 +2097,12 @@ SetValueRangeToNull(Value *vec, size_t len)
SetValueRangeToNull(vec, vec + len); SetValueRangeToNull(vec, vec + len);
} }
class AutoObjectVector : public AutoVectorRooter<JSObject *> class AutoObjectVector : public AutoVectorRooter<RawObject>
{ {
public: public:
explicit AutoObjectVector(JSContext *cx explicit AutoObjectVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<JSObject *>(cx, OBJVECTOR) : AutoVectorRooter<RawObject>(cx, OBJVECTOR)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
@ -2110,12 +2110,12 @@ class AutoObjectVector : public AutoVectorRooter<JSObject *>
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
class AutoStringVector : public AutoVectorRooter<JSString *> class AutoStringVector : public AutoVectorRooter<RawString>
{ {
public: public:
explicit AutoStringVector(JSContext *cx explicit AutoStringVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<JSString *>(cx, STRINGVECTOR) : AutoVectorRooter<RawString>(cx, STRINGVECTOR)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
@ -2123,12 +2123,12 @@ class AutoStringVector : public AutoVectorRooter<JSString *>
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
class AutoShapeVector : public AutoVectorRooter<Shape *> class AutoShapeVector : public AutoVectorRooter<RawShape>
{ {
public: public:
explicit AutoShapeVector(JSContext *cx explicit AutoShapeVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<Shape *>(cx, SHAPEVECTOR) : AutoVectorRooter<RawShape>(cx, SHAPEVECTOR)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
@ -2138,24 +2138,37 @@ class AutoShapeVector : public AutoVectorRooter<Shape *>
class AutoValueArray : public AutoGCRooter class AutoValueArray : public AutoGCRooter
{ {
js::Value *start_; RawValue *start_;
unsigned length_; unsigned length_;
SkipRoot skip; SkipRoot skip;
public: public:
AutoValueArray(JSContext *cx, js::Value *start, unsigned length AutoValueArray(JSContext *cx, RawValue *start, unsigned length
JS_GUARD_OBJECT_NOTIFIER_PARAM) JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, VALARRAY), start_(start), length_(length), skip(cx, start, length) : AutoGCRooter(cx, VALARRAY), start_(start), length_(length), skip(cx, start, length)
{ {
JS_GUARD_OBJECT_NOTIFIER_INIT; JS_GUARD_OBJECT_NOTIFIER_INIT;
} }
Value *start() { return start_; } RawValue *start() { return start_; }
unsigned length() const { return length_; } unsigned length() const { return length_; }
JS_DECL_USE_GUARD_OBJECT_NOTIFIER JS_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
class AutoObjectObjectHashMap : public AutoHashMapRooter<RawObject, RawObject>
{
public:
explicit AutoObjectObjectHashMap(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoHashMapRooter<RawObject, RawObject>(cx, OBJOBJHASHMAP)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
/* /*
* Allocation policy that uses JSRuntime::malloc_ and friends, so that * Allocation policy that uses JSRuntime::malloc_ and friends, so that
* memory pressure is properly accounted for. This is suitable for * memory pressure is properly accounted for. This is suitable for