Bug 810192 - don't require a default constructor for Hash{Map,Set}; only construct objects for live elements (r=terrence)

This commit is contained in:
Luke Wagner 2012-11-12 15:30:39 -08:00
parent e72652f68f
commit da2499ccc0
10 changed files with 769 additions and 811 deletions

File diff suppressed because it is too large Load Diff

View File

@ -512,6 +512,9 @@ template <class T, size_t N, class AllocPolicy>
JS_ALWAYS_INLINE JS_ALWAYS_INLINE
Vector<T, N, AllocPolicy>::Vector(MoveRef<Vector> rhs) Vector<T, N, AllocPolicy>::Vector(MoveRef<Vector> rhs)
: AllocPolicy(rhs) : AllocPolicy(rhs)
#ifdef DEBUG
, entered(false)
#endif
{ {
mLength = rhs->mLength; mLength = rhs->mLength;
mCapacity = rhs->mCapacity; mCapacity = rhs->mCapacity;

View File

@ -94,6 +94,11 @@ class IonAllocPolicy
void *malloc_(size_t bytes) { void *malloc_(size_t bytes) {
return GetIonContext()->temp->allocate(bytes); return GetIonContext()->temp->allocate(bytes);
} }
void *calloc_(size_t bytes) {
void *p = GetIonContext()->temp->allocate(bytes);
memset(p, 0, bytes);
return p;
}
void *realloc_(void *p, size_t oldBytes, size_t bytes) { void *realloc_(void *p, size_t oldBytes, size_t bytes) {
void *n = malloc_(bytes); void *n = malloc_(bytes);
if (!n) if (!n)

View File

@ -18,6 +18,8 @@ namespace js {
* - public copy constructor, assignment, destructor * - public copy constructor, assignment, destructor
* - void *malloc_(size_t) * - void *malloc_(size_t)
* Responsible for OOM reporting on NULL return value. * Responsible for OOM reporting on NULL return value.
* - void *calloc_(size_t)
* Responsible for OOM reporting on NULL return value.
* - void *realloc_(size_t) * - void *realloc_(size_t)
* Responsible for OOM reporting on NULL return value. * Responsible for OOM reporting on NULL return value.
* The *used* bytes of the previous buffer is passed in * The *used* bytes of the previous buffer is passed in
@ -33,6 +35,7 @@ class SystemAllocPolicy
{ {
public: public:
void *malloc_(size_t bytes) { return js_malloc(bytes); } void *malloc_(size_t bytes) { return js_malloc(bytes); }
void *calloc_(size_t bytes) { return js_calloc(bytes); }
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return js_realloc(p, bytes); } void *realloc_(void *p, size_t oldBytes, size_t bytes) { return js_realloc(p, bytes); }
void free_(void *p) { js_free(p); } void free_(void *p) { js_free(p); }
void reportAllocOverflow() const {} void reportAllocOverflow() const {}
@ -71,6 +74,13 @@ class TempAllocPolicy
return p; return p;
} }
void *calloc_(size_t bytes) {
void *p = js_calloc(bytes);
if (JS_UNLIKELY(!p))
p = onOutOfMemory(NULL, bytes);
return p;
}
void *realloc_(void *p, size_t oldBytes, size_t bytes) { void *realloc_(void *p, size_t oldBytes, size_t bytes) {
void *p2 = js_realloc(p, bytes); void *p2 = js_realloc(p, bytes);
if (JS_UNLIKELY(!p2)) if (JS_UNLIKELY(!p2))

View File

@ -38,8 +38,7 @@ HashId(jsid id)
return mozilla::HashGeneric(JSID_BITS(id)); return mozilla::HashGeneric(JSID_BITS(id));
} }
template<> struct JsidHasher
struct DefaultHasher<jsid>
{ {
typedef jsid Lookup; typedef jsid Lookup;
static HashNumber hash(const Lookup &l) { static HashNumber hash(const Lookup &l) {

View File

@ -2194,6 +2194,7 @@ class RuntimeAllocPolicy
RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {} RuntimeAllocPolicy(JSRuntime *rt) : runtime(rt) {}
RuntimeAllocPolicy(JSContext *cx) : runtime(cx->runtime) {} RuntimeAllocPolicy(JSContext *cx) : runtime(cx->runtime) {}
void *malloc_(size_t bytes) { return runtime->malloc_(bytes); } void *malloc_(size_t bytes) { return runtime->malloc_(bytes); }
void *calloc_(size_t bytes) { return runtime->calloc_(bytes); }
void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); } void *realloc_(void *p, size_t bytes) { return runtime->realloc_(p, bytes); }
void free_(void *p) { js_free(p); } void free_(void *p) { js_free(p); }
void reportAllocOverflow() const {} void reportAllocOverflow() const {}
@ -2210,6 +2211,7 @@ class ContextAllocPolicy
ContextAllocPolicy(JSContext *cx) : cx(cx) {} ContextAllocPolicy(JSContext *cx) : cx(cx) {}
JSContext *context() const { return cx; } JSContext *context() const { return cx; }
void *malloc_(size_t bytes) { return cx->malloc_(bytes); } void *malloc_(size_t bytes) { return cx->malloc_(bytes); }
void *calloc_(size_t bytes) { return cx->calloc_(bytes); }
void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx->realloc_(p, oldBytes, bytes); } void *realloc_(void *p, size_t oldBytes, size_t bytes) { return cx->realloc_(p, oldBytes, bytes); }
void free_(void *p) { js_free(p); } void free_(void *p) { js_free(p); }
void reportAllocOverflow() const { js_ReportAllocationOverflow(cx); } void reportAllocOverflow() const { js_ReportAllocationOverflow(cx); }

View File

@ -3249,10 +3249,11 @@ InCrossCompartmentMap(JSObject *src, Cell *dst, JSGCTraceKind dstKind)
if (dstKind == JSTRACE_OBJECT) { if (dstKind == JSTRACE_OBJECT) {
Value key = ObjectValue(*static_cast<JSObject *>(dst)); Value key = ObjectValue(*static_cast<JSObject *>(dst));
WrapperMap::Ptr p = srccomp->crossCompartmentWrappers.lookup(key); if (WrapperMap::Ptr p = srccomp->crossCompartmentWrappers.lookup(key)) {
if (*p->value.unsafeGet() == ObjectValue(*src)) if (*p->value.unsafeGet() == ObjectValue(*src))
return true; return true;
} }
}
/* /*
* If the cross-compartment edge is caused by the debugger, then we don't * If the cross-compartment edge is caused by the debugger, then we don't

View File

@ -630,7 +630,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
if (replacer->isDenseArray()) if (replacer->isDenseArray())
len = Min(len, replacer->getDenseArrayCapacity()); len = Min(len, replacer->getDenseArrayCapacity());
HashSet<jsid> idSet(cx); HashSet<jsid, JsidHasher> idSet(cx);
if (!idSet.init(len)) if (!idSet.init(len))
return false; return false;
@ -667,7 +667,7 @@ js_Stringify(JSContext *cx, MutableHandleValue vp, JSObject *replacer_, Value sp
} }
/* Step 4b(iv)(6). */ /* Step 4b(iv)(6). */
HashSet<jsid>::AddPtr p = idSet.lookupForAdd(id); HashSet<jsid, JsidHasher>::AddPtr p = idSet.lookupForAdd(id);
if (!p) { if (!p) {
/* Step 4b(iv)(6)(a). */ /* Step 4b(iv)(6)(a). */
if (!idSet.add(p, id) || !propertyList.append(id)) if (!idSet.add(p, id) || !propertyList.append(id))

View File

@ -148,7 +148,8 @@ PropertyTree::getChild(JSContext *cx, Shape *parent_, uint32_t nfixed, const Sta
if (kid->matches(child)) if (kid->matches(child))
shape = kid; shape = kid;
} else if (kidp->isHash()) { } else if (kidp->isHash()) {
shape = *kidp->toHash()->lookup(child); if (KidsHash::Ptr p = kidp->toHash()->lookup(child))
shape = *p;
} else { } else {
/* If kidp->isNull(), we always insert. */ /* If kidp->isNull(), we always insert. */
} }

View File

@ -55,6 +55,7 @@ private:
class SystemAllocPolicy { class SystemAllocPolicy {
public: public:
void *malloc_(size_t bytes) { return ::malloc(bytes); } void *malloc_(size_t bytes) { return ::malloc(bytes); }
void *calloc_(size_t bytes) { return ::calloc(bytes, 1); }
void *realloc_(void *p, size_t bytes) { return ::realloc(p, bytes); } void *realloc_(void *p, size_t bytes) { return ::realloc(p, bytes); }
void free_(void *p) { ::free(p); } void free_(void *p) { ::free(p); }
void reportAllocOverflow() const {} void reportAllocOverflow() const {}