Bug 1155618 - Fix places where OOM errors are not reported to the context in js::DependentAddPtr r=terrence
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 01 May 2015 16:26:10 +0100
changeset 273441 454541170ba25e3e1580ed6b07d1bb6fd7e5a674
parent 273440 fae47e06131277b96ec7ddac2a898a072c3bd253
child 273442 c870026255513f1aa5cd5b73b93747fd7921460a
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1155618
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1155618 - Fix places where OOM errors are not reported to the context in js::DependentAddPtr r=terrence
js/src/jshashutil.h
js/src/vm/Debugger.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/SavedStacks.cpp
--- a/js/src/jshashutil.h
+++ b/js/src/jshashutil.h
@@ -26,21 +26,25 @@ struct DependentAddPtr
 
     template <class Lookup>
     DependentAddPtr(const ExclusiveContext* cx, const T& table, const Lookup& lookup)
       : addPtr(table.lookupForAdd(lookup))
       , originalGcNumber(cx->zone()->gcNumber())
     {}
 
     template <class KeyInput, class ValueInput>
-    bool add(const ExclusiveContext* cx, T& table, const KeyInput& key, const ValueInput& value) {
+    bool add(ExclusiveContext* cx, T& table, const KeyInput& key, const ValueInput& value) {
         bool gcHappened = originalGcNumber != cx->zone()->gcNumber();
         if (gcHappened)
             addPtr = table.lookupForAdd(key);
-        return table.relookupOrAdd(addPtr, key, value);
+        if (!table.relookupOrAdd(addPtr, key, value)) {
+            ReportOutOfMemory(cx);
+            return false;
+        }
+        return true;
     }
 
 
     bool found() const                 { return addPtr.found(); }
     explicit operator bool() const     { return found(); }
     const Entry& operator*() const     { return *addPtr; }
     const Entry* operator->() const    { return &*addPtr; }
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -783,20 +783,18 @@ Debugger::wrapEnvironment(JSContext* cx,
         /* Create a new Debugger.Environment for env. */
         RootedObject proto(cx, &object->getReservedSlot(JSSLOT_DEBUG_ENV_PROTO).toObject());
         envobj = NewNativeObjectWithGivenProto(cx, &DebuggerEnv_class, proto,
                                                TenuredObject);
         if (!envobj)
             return false;
         envobj->setPrivateGCThing(env);
         envobj->setReservedSlot(JSSLOT_DEBUGENV_OWNER, ObjectValue(*object));
-        if (!p.add(cx, environments, env, envobj)) {
-            ReportOutOfMemory(cx);
+        if (!p.add(cx, environments, env, envobj))
             return false;
-        }
 
         CrossCompartmentKey key(CrossCompartmentKey::DebuggerEnvironment, object, env);
         if (!object->compartment()->putWrapper(cx, key, ObjectValue(*envobj))) {
             environments.remove(env);
             ReportOutOfMemory(cx);
             return false;
         }
     }
@@ -827,20 +825,18 @@ Debugger::wrapDebuggeeValue(JSContext* c
             NativeObject* dobj =
                 NewNativeObjectWithGivenProto(cx, &DebuggerObject_class, proto,
                                               TenuredObject);
             if (!dobj)
                 return false;
             dobj->setPrivateGCThing(obj);
             dobj->setReservedSlot(JSSLOT_DEBUGOBJECT_OWNER, ObjectValue(*object));
 
-            if (!p.add(cx, objects, obj, dobj)) {
-                ReportOutOfMemory(cx);
+            if (!p.add(cx, objects, obj, dobj))
                 return false;
-            }
 
             if (obj->compartment() != object->compartment()) {
                 CrossCompartmentKey key(CrossCompartmentKey::DebuggerObject, object, obj);
                 if (!object->compartment()->putWrapper(cx, key, ObjectValue(*dobj))) {
                     objects.remove(obj);
                     ReportOutOfMemory(cx);
                     return false;
                 }
@@ -4344,20 +4340,18 @@ Debugger::wrapScript(JSContext* cx, Hand
     assertSameCompartment(cx, object.get());
     MOZ_ASSERT(cx->compartment() != script->compartment());
     DependentAddPtr<ScriptWeakMap> p(cx, scripts, script);
     if (!p) {
         JSObject* scriptobj = newDebuggerScript(cx, script);
         if (!scriptobj)
             return nullptr;
 
-        if (!p.add(cx, scripts, script, scriptobj)) {
-            ReportOutOfMemory(cx);
+        if (!p.add(cx, scripts, script, scriptobj))
             return nullptr;
-        }
 
         CrossCompartmentKey key(CrossCompartmentKey::DebuggerScript, object, script);
         if (!object->compartment()->putWrapper(cx, key, ObjectValue(*scriptobj))) {
             scripts.remove(script);
             ReportOutOfMemory(cx);
             return nullptr;
         }
     }
@@ -5365,20 +5359,18 @@ Debugger::wrapSource(JSContext* cx, Hand
     assertSameCompartment(cx, object.get());
     MOZ_ASSERT(cx->compartment() != source->compartment());
     DependentAddPtr<SourceWeakMap> p(cx, sources, source);
     if (!p) {
         JSObject* sourceobj = newDebuggerSource(cx, source);
         if (!sourceobj)
             return nullptr;
 
-        if (!p.add(cx, sources, source, sourceobj)) {
-            ReportOutOfMemory(cx);
+        if (!p.add(cx, sources, source, sourceobj))
             return nullptr;
-        }
 
         CrossCompartmentKey key(CrossCompartmentKey::DebuggerSource, object, source);
         if (!object->compartment()->putWrapper(cx, key, ObjectValue(*sourceobj))) {
             sources.remove(source);
             ReportOutOfMemory(cx);
             return nullptr;
         }
     }
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -838,17 +838,18 @@ ObjectGroup::setGroupToHomogenousArray(E
         ObjectGroup* group = ObjectGroupCompartment::makeGroup(cx, &ArrayObject::class_, taggedProto);
         if (!group)
             return;
         obj->setGroup(group);
 
         AddTypePropertyId(cx, group, nullptr, JSID_VOID, elementType);
 
         key.proto = objProto;
-        (void) p.add(cx, *table, key, group);
+        if (!p.add(cx, *table, key, group))
+            cx->recoverFromOutOfMemory();
     }
 }
 
 /////////////////////////////////////////////////////////////////////
 // ObjectGroupCompartment PlainObjectTable
 /////////////////////////////////////////////////////////////////////
 
 struct ObjectGroupCompartment::PlainObjectKey
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1032,20 +1032,18 @@ SavedStacks::getOrCreateSavedFrame(JSCon
     DependentAddPtr<SavedFrame::Set> p(cx, frames, lookupInstance);
     if (p)
         return *p;
 
     RootedSavedFrame frame(cx, createFrameFromLookup(cx, lookup));
     if (!frame)
         return nullptr;
 
-    if (!p.add(cx, frames, lookupInstance, frame)) {
-        ReportOutOfMemory(cx);
+    if (!p.add(cx, frames, lookupInstance, frame))
         return nullptr;
-    }
 
     return frame;
 }
 
 SavedFrame*
 SavedStacks::createFrameFromLookup(JSContext* cx, SavedFrame::HandleLookup lookup)
 {
     RootedGlobalObject global(cx, cx->global());