[gjs: 24/25] gtype: Don't use lookupForAdd() when adding GType to table



commit 9445fae6bd50999ab69575bfeb40791b29aea828
Author: Philip Chimento <philip chimento gmail com>
Date:   Sat Jan 25 20:14:54 2020 -0800

    gtype: Don't use lookupForAdd() when adding GType to table
    
    This was a bug exposed by more efficient garbage collection and better
    debug assertions in SpiderMonkey 68. We cannot use lookupForAdd() when
    checking if a GType is already present in the GType table (which we did
    to anticipate adding it if it wasn't present) because creating the GType
    wrapper object might trigger a GC, which could cause another GType to be
    garbage collected, which would remove it from the GType table. Mutating
    the table invalidates the AddPtr returned by lookupForAdd(), which is a
    bug.

 gi/gtype.cpp | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
---
diff --git a/gi/gtype.cpp b/gi/gtype.cpp
index e9649559..dd68d924 100644
--- a/gi/gtype.cpp
+++ b/gi/gtype.cpp
@@ -122,8 +122,12 @@ gjs_gtype_create_gtype_wrapper (JSContext *context,
               gtype != 0));
 
     GjsContextPrivate* gjs = GjsContextPrivate::from_cx(context);
-    auto p = gjs->gtype_table().lookupForAdd(gtype);
-    if (p)
+    // We cannot use gtype_table().lookupForAdd() here, because in between the
+    // lookup and the add, GCs may take place and mutate the hash table. A GC
+    // may only remove an element, not add one, so it's still safe to do this
+    // without locking.
+    auto p = gjs->gtype_table().lookup(gtype);
+    if (p.found())
         return p->value();
 
     JS::RootedObject proto(context);
@@ -137,7 +141,7 @@ gjs_gtype_create_gtype_wrapper (JSContext *context,
 
     JS_SetPrivate(gtype_wrapper, GSIZE_TO_POINTER(gtype));
 
-    gjs->gtype_table().add(p, gtype, gtype_wrapper);
+    gjs->gtype_table().put(gtype, gtype_wrapper);
 
     return gtype_wrapper;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]