Bug 1251529: Pass AutoEnterOOMUnsafeRegion to allocation metadata builder methods. r=fitzgen
authorJim Blandy <jimb@mozilla.com>
Mon, 29 Feb 2016 18:27:10 -0800
changeset 347723 12f6c52e4b4df6527c98593c31840a8c68e2bf5f
parent 347722 fc76f66bf11f5800a7692ccf71add7ef8b01640d
child 347724 0d06527892bcdb86beec7898b2402d7294354f55
push id14653
push userolivier@olivieryiptong.com
push dateTue, 05 Apr 2016 19:21:01 +0000
reviewersfitzgen
bugs1251529
milestone48.0a1
Bug 1251529: Pass AutoEnterOOMUnsafeRegion to allocation metadata builder methods. r=fitzgen
js/src/builtin/TestingFunctions.cpp
js/src/jscompartment.cpp
js/src/jsfriendapi.h
js/src/vm/SavedStacks.cpp
js/src/vm/SavedStacks.h
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1686,26 +1686,26 @@ DisplayName(JSContext* cx, unsigned argc
     JSFunction* fun = &args[0].toObject().as<JSFunction>();
     JSString* str = fun->displayAtom();
     args.rval().setString(str ? str : cx->runtime()->emptyString);
     return true;
 }
 
 class ShellAllocationMetadataBuilder : public AllocationMetadataBuilder {
   public:
-    virtual JSObject* build(JSContext *cx, HandleObject) const override;
+    virtual JSObject* build(JSContext *cx, HandleObject,
+                            AutoEnterOOMUnsafeRegion& oomUnsafe) const override;
 
     static const ShellAllocationMetadataBuilder metadataBuilder;
 };
 
 JSObject*
-ShellAllocationMetadataBuilder::build(JSContext* cx, HandleObject) const
+ShellAllocationMetadataBuilder::build(JSContext* cx, HandleObject,
+                                      AutoEnterOOMUnsafeRegion& oomUnsafe) const
 {
-    AutoEnterOOMUnsafeRegion oomUnsafe;
-
     RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
     if (!obj)
         oomUnsafe.crash("ShellAllocationMetadataBuilder::build");
 
     RootedObject stack(cx, NewDenseEmptyArray(cx));
     if (!stack)
         oomUnsafe.crash("ShellAllocationMetadataBuilder::build");
 
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -889,18 +889,18 @@ JSCompartment::clearObjectMetadata()
     objectMetadataTable = nullptr;
 }
 
 void
 JSCompartment::setNewObjectMetadata(JSContext* cx, HandleObject obj)
 {
     assertSameCompartment(cx, this, obj);
 
-    if (JSObject* metadata = allocationMetadataBuilder->build(cx, obj)) {
-        AutoEnterOOMUnsafeRegion oomUnsafe;
+    AutoEnterOOMUnsafeRegion oomUnsafe;
+    if (JSObject* metadata = allocationMetadataBuilder->build(cx, obj, oomUnsafe)) {
         assertSameCompartment(cx, metadata);
         if (!objectMetadataTable) {
             objectMetadataTable = cx->new_<ObjectWeakMap>(cx);
             if (!objectMetadataTable || !objectMetadataTable->init())
                 oomUnsafe.crash("setNewObjectMetadata");
         }
         if (!objectMetadataTable->add(cx, obj, metadata))
             oomUnsafe.crash("setNewObjectMetadata");
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -14,16 +14,17 @@
 
 #include "jsapi.h" // For JSAutoByteString.  See bug 1033916.
 #include "jsbytecode.h"
 #include "jspubtd.h"
 
 #include "js/CallArgs.h"
 #include "js/CallNonGenericMethod.h"
 #include "js/Class.h"
+#include "js/Utility.h"
 
 #if JS_STACK_GROWTH_DIRECTION > 0
 # define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) < (limit)))
 #else
 # define JS_CHECK_STACK_SIZE(limit, sp) (MOZ_LIKELY((uintptr_t)(sp) > (limit)))
 #endif
 
 class JSAtom;
@@ -2667,18 +2668,23 @@ class MOZ_RAII JS_FRIEND_API(AutoCTypesA
 
 // Abstract base class for objects that build allocation metadata for JavaScript
 // values.
 struct AllocationMetadataBuilder {
     // Return a metadata object for the newly constructed object |obj|, or
     // nullptr if there's no metadata to attach.
     //
     // Implementations should treat all errors as fatal; there is no way to
-    // report errors from this callback.
-    virtual JSObject* build(JSContext *cx, JS::HandleObject obj) const { return nullptr; }
+    // report errors from this callback. In particular, the caller provides an
+    // oomUnsafe for overriding implementations to use.
+    virtual JSObject* build(JSContext* cx, JS::HandleObject obj,
+                            AutoEnterOOMUnsafeRegion& oomUnsafe) const
+    {
+        return nullptr;
+    }
 };
 
 /**
  * Specify a callback to invoke when creating each JS object in the current
  * compartment, which may return a metadata object to associate with the
  * object.
  */
 JS_FRIEND_API(void)
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1470,25 +1470,25 @@ SavedStacks::chooseSamplingProbability(J
         bernoulli.setRandomState(seed[0], seed[1]);
         bernoulliSeeded = true;
     }
 
     bernoulli.setProbability(probability);
 }
 
 JSObject*
-SavedStacks::MetadataBuilder::build(JSContext* cx, HandleObject target) const
+SavedStacks::MetadataBuilder::build(JSContext* cx, HandleObject target,
+                                    AutoEnterOOMUnsafeRegion& oomUnsafe) const
 {
     RootedObject obj(cx, target);
 
     SavedStacks& stacks = cx->compartment()->savedStacks();
     if (!stacks.bernoulli.trial())
         return nullptr;
 
-    AutoEnterOOMUnsafeRegion oomUnsafe;
     RootedSavedFrame frame(cx);
     if (!stacks.saveCurrentStack(cx, &frame))
         oomUnsafe.crash("SavedStacksMetadataBuilder");
 
     if (!Debugger::onLogAllocationSite(cx, obj, frame, JS_GetCurrentEmbedderTime()))
         oomUnsafe.crash("SavedStacksMetadataBuilder");
 
     MOZ_ASSERT_IF(frame, !frame->is<WrapperObject>());
--- a/js/src/vm/SavedStacks.h
+++ b/js/src/vm/SavedStacks.h
@@ -177,17 +177,18 @@ class SavedStacks {
     // mozilla::non_crypto::XorShift128PlusRNG::setState for details.
     void     setRNGState(uint64_t state0, uint64_t state1) { bernoulli.setRandomState(state0, state1); }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
 
     // An alloction metadata builder that marks cells with the JavaScript stack
     // at which they were allocated.
     class MetadataBuilder : public AllocationMetadataBuilder {
-        virtual JSObject* build(JSContext *cx, HandleObject obj) const override;
+        virtual JSObject* build(JSContext *cx, HandleObject obj,
+                                AutoEnterOOMUnsafeRegion& oomUnsafe) const override;
     };
 
     static const MetadataBuilder metadataBuilder;
 
   private:
     SavedFrame::Set frames;
     bool bernoulliSeeded;
     mozilla::FastBernoulliTrial bernoulli;