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 349691 33ac1652a6f6dc6d524d2396219e59a1e7239df2
parent 349690 f5a9d33557dd860e74994a3a650e743569883cbb
child 349692 1ea78395c2d3df440caf7b947903695db66558eb
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence, sylvestre
bugs1290469
milestone50.0a2
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
@@ -188,23 +188,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,