Bug 1290469 - Use fallible hashing for SavedFrame r=terrence a=sylvestre
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 01 Aug 2016 09:56:25 +0100
changeset 407640 a86f28044dd4e943bae3961442d7abdb7c3a3880
parent 407639 e33c4c0efaaf4df186fb5e11f24cc9d7f5df2ba8
child 407641 4217d21df7061f94061d059c56bcb96d290990f1
push id28002
push userfelipc@gmail.com
push dateTue, 30 Aug 2016 18:14:28 +0000
reviewersterrence, sylvestre
bugs1290469
milestone48.0.1
Bug 1290469 - Use fallible hashing for SavedFrame r=terrence a=sylvestre
js/src/jit-test/tests/saved-stacks/oom-in-save-stack.js
js/src/vm/SavedFrame.h
js/src/vm/SavedStacks.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/saved-stacks/oom-in-save-stack.js
@@ -0,0 +1,4 @@
+if (!('oomTest' in this))
+    quit();
+let s = saveStack();
+oomTest(() => { saveStack(); });
--- a/js/src/vm/SavedFrame.h
+++ b/js/src/vm/SavedFrame.h
@@ -186,23 +186,36 @@ class SavedFrame : public NativeObject {
 };
 
 struct SavedFrame::HashPolicy
 {
     typedef SavedFrame::Lookup              Lookup;
     typedef MovableCellHasher<SavedFrame*>  SavedFramePtrHasher;
     typedef PointerHasher<JSPrincipals*, 3> JSPrincipalsPtrHasher;
 
+    static bool       hasHash(const Lookup& l);
+    static bool       ensureHash(const Lookup& l);
     static HashNumber hash(const Lookup& lookup);
     static bool       match(SavedFrame* existing, const Lookup& lookup);
 
     typedef ReadBarriered<SavedFrame*> Key;
     static void rekey(Key& key, const Key& newKey);
 };
 
+template <>
+struct FallibleHashMethods<SavedFrame::HashPolicy>
+{
+    template <typename Lookup> static bool hasHash(Lookup&& l) {
+        return SavedFrame::HashPolicy::hasHash(mozilla::Forward<Lookup>(l));
+    }
+    template <typename Lookup> static bool ensureHash(Lookup&& l) {
+        return SavedFrame::HashPolicy::ensureHash(mozilla::Forward<Lookup>(l));
+    }
+};
+
 // Assert that if the given object is not null, that it must be either a
 // SavedFrame object or wrapper (Xray or CCW) around a SavedFrame object.
 inline void AssertObjectIsSavedFrameOrWrapper(JSContext* cx, HandleObject stack);
 
 // When we reconstruct a SavedFrame stack from a JS::ubi::StackFrame, we may not
 // have access to the principals that the original stack was captured
 // with. Instead, we use these two singleton principals based on whether
 // JS::ubi::StackFrame::isSystem or not. These singletons should never be passed
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -222,16 +222,28 @@ class MOZ_STACK_CLASS SavedFrame::AutoLo
     LookupVector lookups;
 
     virtual void trace(JSTracer* trc) {
         for (size_t i = 0; i < lookups.length(); i++)
             lookups[i].trace(trc);
     }
 };
 
+/* static */ bool
+SavedFrame::HashPolicy::hasHash(const Lookup& l)
+{
+    return SavedFramePtrHasher::hasHash(l.parent);
+}
+
+/* static */ bool
+SavedFrame::HashPolicy::ensureHash(const Lookup& l)
+{
+    return SavedFramePtrHasher::ensureHash(l.parent);
+}
+
 /* static */ HashNumber
 SavedFrame::HashPolicy::hash(const Lookup& lookup)
 {
     JS::AutoCheckCannotGC nogc;
     // Assume that we can take line mod 2^32 without losing anything of
     // interest.  If that assumption changes, we'll just need to start with 0
     // and add another overload of AddToHash with more arguments.
     return AddToHash(lookup.line,