[sgen] Make getting object size safe with parallel collector
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 20 Oct 2016 23:30:32 +0000 (02:30 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 19 Jan 2017 22:45:12 +0000 (00:45 +0200)
mono/sgen/sgen-gc.h

index ab552c7c7df79b76d2f5914bb333cb076dece4de..ba7aee729406a55f2ae6bde264d7219e9e349620 100644 (file)
@@ -753,12 +753,18 @@ static mword sgen_client_slow_object_get_size (GCVTable vtable, GCObject* o);
 static inline mword
 sgen_safe_object_get_size (GCObject *obj)
 {
-       GCObject *forwarded;
-
-       if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj)))
-               obj = forwarded;
+       GCObject *forwarded;
+       GCVTable vtable = SGEN_LOAD_VTABLE_UNCHECKED (obj);
 
-       return sgen_client_par_object_get_size (SGEN_LOAD_VTABLE (obj), obj);
+       /*
+        * Once we load the vtable, we must always use it, in case we are in parallel case.
+        * Otherwise the object might get forwarded in the meantime and we would read an
+        * invalid vtable. An object cannot be forwarded for a second time during same GC.
+        */
+       if ((forwarded = SGEN_VTABLE_IS_FORWARDED (vtable)))
+               return sgen_client_par_object_get_size (SGEN_LOAD_VTABLE (forwarded), obj);
+       else
+               return sgen_client_par_object_get_size ((GCVTable)SGEN_POINTER_UNTAG_ALL (vtable), obj);
 }
 
 static inline gboolean