Bug 844893 - Don't assert when two threads call getVMWrapper at the same time. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 26 Feb 2013 13:49:44 +0100
changeset 123012 9198ac37724ba1d0ce61190e8ee841fe56147138
parent 123011 b00914c9e7d4b0e224ef81c40ac336646b4b8a03
child 123013 e952b94e1f789257a936f027cde1be2b3013cbf8
push id24372
push useremorley@mozilla.com
push dateWed, 27 Feb 2013 13:22:59 +0000
treeherdermozilla-central@0a91da5f5eab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs844893
milestone22.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 844893 - Don't assert when two threads call getVMWrapper at the same time. r=luke
js/public/HashTable.h
js/src/ion/Ion.cpp
--- a/js/public/HashTable.h
+++ b/js/public/HashTable.h
@@ -80,16 +80,20 @@ class HashMap
     //     assert(p->key == 3);     // Entry contains the key
     //     char val = p->value;     // and value
     //   }
     //
     // Also see the definition of Ptr in HashTable above (with T = Entry).
     typedef typename Impl::Ptr Ptr;
     Ptr lookup(const Lookup &l) const                 { return impl.lookup(l); }
 
+    // Like lookup, but does not assert if two threads call lookup at the same
+    // time. Only use this method when none of the threads will modify the map.
+    Ptr readonlyThreadsafeLookup(const Lookup &l) const { return impl.readonlyThreadsafeLookup(l); }
+
     // Assuming |p.found()|, remove |*p|.
     void remove(Ptr p)                                { impl.remove(p); }
 
     // Like |lookup(l)|, but on miss, |p = lookupForAdd(l)| allows efficient
     // insertion of Key |k| (where |HashPolicy::match(k,l) == true|) using
     // |add(p,k,v)|. After |add(p,k,v)|, |p| points to the new Entry. E.g.:
     //
     //   typedef HashMap<int,char> HM;
@@ -1338,16 +1342,22 @@ class HashTable : private AllocPolicy
 
     Ptr lookup(const Lookup &l) const
     {
         ReentrancyGuard g(*this);
         HashNumber keyHash = prepareHash(l);
         return Ptr(lookup(l, keyHash, 0));
     }
 
+    Ptr readonlyThreadsafeLookup(const Lookup &l) const
+    {
+        HashNumber keyHash = prepareHash(l);
+        return Ptr(lookup(l, keyHash, 0));
+    }
+
     AddPtr lookupForAdd(const Lookup &l) const
     {
         ReentrancyGuard g(*this);
         HashNumber keyHash = prepareHash(l);
         Entry &entry = lookup(l, keyHash, sCollisionBit);
         AddPtr p(entry, keyHash);
         p.mutationCount = mutationCount;
         return p;
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -285,17 +285,17 @@ IonCompartment::getBailoutTable(const Fr
 
 IonCode *
 IonCompartment::getVMWrapper(const VMFunction &f)
 {
     typedef MoveResolver::MoveOperand MoveOperand;
 
     JS_ASSERT(rt->functionWrappers_);
     JS_ASSERT(rt->functionWrappers_->initialized());
-    IonRuntime::VMWrapperMap::Ptr p = rt->functionWrappers_->lookup(&f);
+    IonRuntime::VMWrapperMap::Ptr p = rt->functionWrappers_->readonlyThreadsafeLookup(&f);
     JS_ASSERT(p);
 
     return p->value;
 }
 
 IonActivation::IonActivation(JSContext *cx, StackFrame *fp)
   : cx_(cx),
     compartment_(cx->compartment),