The bridge code was triggering handles to be considered deallocated thus leading
them to be overwritten.
sccs [i]->is_alive = TRUE;
}
+/* This bridge keeps all peers with __test > 0 */
+static void
+bridge_test_positive_status (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs)
+{
+ int i;
+
+ if (!mono_bridge_test_field) {
+ mono_bridge_test_field = mono_class_get_field_from_name (mono_object_get_class (sccs[0]->objs [0]), "__test");
+ g_assert (mono_bridge_test_field);
+ }
+
+ /*We mark all objects in a scc with live objects as reachable by scc*/
+ for (i = 0; i < num_sccs; ++i) {
+ int j;
+ for (j = 0; j < sccs [i]->num_objs; ++j) {
+ if (test_scc (sccs [i], j)) {
+ sccs [i]->is_alive = TRUE;
+ break;
+ }
+ }
+ }
+}
+
+
static void
register_test_bridge_callbacks (const char *bridge_class_name)
{
callbacks.bridge_version = SGEN_BRIDGE_VERSION;
callbacks.bridge_class_kind = bridge_test_bridge_class_kind;
callbacks.is_bridge_object = bridge_test_is_bridge_object;
- callbacks.cross_references = bridge_class_name[0] == '2' ? bridge_test_cross_reference2 : bridge_test_cross_reference;
+
+ switch (bridge_class_name [0]) {
+ case '2':
+ bridge_class = bridge_class_name + 1;
+ callbacks.cross_references = bridge_test_cross_reference2;
+ break;
+ case '3':
+ bridge_class = bridge_class_name + 1;
+ callbacks.cross_references = bridge_test_positive_status;
+ break;
+ default:
+ bridge_class = bridge_class_name;
+ callbacks.cross_references = bridge_test_cross_reference;
+ }
mono_gc_register_bridge_callbacks (&callbacks);
- bridge_class = bridge_class_name + (bridge_class_name[0] == '2' ? 1 : 0);
}
gboolean
@$(MCS) -r:TestDriver.dll $(srcdir)/debug-casts.cs
@$(RUNTIME) --debug=casts debug-casts.exe
-EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs
+EXTRA_DIST += sgen-bridge.cs sgen-descriptors.cs sgen-gshared-vtype.cs sgen-bridge-major-fragmentation.cs sgen-domain-unload.cs sgen-weakref-stress.cs sgen-cementing-stress.cs sgen-case-23400.cs finalizer-wait.cs critical-finalizers.cs sgen-domain-unload-2.cs sgen-suspend.cs sgen-new-threads-dont-join-stw.cs sgen-bridge-xref.cs bug-17590.cs sgen-toggleref.cs sgen-bridge-gchandle.cs
sgen-tests:
sgen-bridge2-tests-ms-split-tarjan-bridge: $(SGEN_BRIDGE2_TESTS) test-runner.exe
MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=2Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE2_TESTS)
+
+SGEN_BRIDGE3_TESTS= \
+ sgen-bridge-gchandle.exe
+
+sgen-bridge3-tests: $(SGEN_BRIDGE3_TESTS)
+ $(MAKE) sgen-bridge3-tests-plain
+ $(MAKE) sgen-bridge3-tests-ms-conc
+ $(MAKE) sgen-bridge3-tests-ms-split
+ $(MAKE) sgen-bridge3-tests-plain-new-bridge
+ $(MAKE) sgen-bridge3-tests-ms-conc-new-bridge
+ $(MAKE) sgen-bridge3-tests-ms-split-new-bridge
+ $(MAKE) sgen-bridge3-tests-plain-tarjan-bridge
+ $(MAKE) sgen-bridge3-tests-ms-split-tarjan-bridge
+
+sgen-bridge3-tests-plain: $(SGEN_bridge3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-ms-conc: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="major=marksweep-conc" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-ms-split: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-plain-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-ms-conc-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,major=marksweep-conc" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-ms-split-new-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=new,minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-plain-tarjan-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+sgen-bridge3-tests-ms-split-tarjan-bridge: $(SGEN_BRIDGE3_TESTS) test-runner.exe
+ MONO_ENV_OPTIONS="--gc=sgen" MONO_GC_DEBUG="bridge=3Bridge" MONO_GC_PARAMS="bridge-implementation=tarjan,minor=split" $(RUNTIME) ./test-runner.exe --testsuite-name $@ --timeout 900 $(SGEN_BRIDGE3_TESTS)
+
+
AOT_CONFIGURATIONS= \
"|regular" \
"--gc=boehm|boehm"
--- /dev/null
+using System;
+using System.Collections;
+using System.Threading;
+using System.Runtime.InteropServices;
+
+
+public class Bridge {
+ public int __test;
+ public string id;
+
+ ~Bridge () {
+ try {Console.WriteLine ("bridge {0} gone", id);} catch (Exception) {}
+ }
+}
+
+
+/*
+Test scenario:
+ Alloc a bridge and create a gc handle to it
+ Get it collected.
+ Create another one and see it steal the handle of the previous one.
+
+
+*/
+class Driver {
+ public static GCHandle weak_track_handle;
+ public static GCHandle weak_track_handle2;
+
+ static void CreateFirstBridge () {
+ Bridge b = new Bridge() {
+ __test = 0,
+ id = "first",
+ };
+ weak_track_handle = GCHandle.Alloc (b, GCHandleType.WeakTrackResurrection);
+ }
+
+ static void CreateSecondBridge () {
+ Bridge b = new Bridge() {
+ __test = 1,
+ id = "second",
+ };
+ weak_track_handle2 = GCHandle.Alloc (b, GCHandleType.WeakTrackResurrection);
+ }
+
+ static void DumpHandle (GCHandle h, string name) {
+ Console.WriteLine ("{0}:{1:X} alloc:{2} hasValue:{2}", name, (IntPtr)h, h.IsAllocated, h.Target == null);
+ }
+
+ static int Main () {
+ var t = new Thread (CreateFirstBridge);
+ t.Start ();
+ t.Join ();
+
+ GC.Collect ();
+ GC.WaitForPendingFinalizers ();
+ Console.WriteLine ("GC DONE");
+
+ DumpHandle (weak_track_handle, "weak-track1");
+
+ t = new Thread (CreateSecondBridge);
+ t.Start ();
+ t.Join ();
+
+ GC.Collect ();
+ GC.WaitForPendingFinalizers ();
+ Console.WriteLine ("GC DONE");
+ DumpHandle (weak_track_handle, "weak-track1");
+ DumpHandle (weak_track_handle2, "weak-track2");
+ Console.WriteLine ("DONE");
+
+ if ((IntPtr)weak_track_handle == (IntPtr)weak_track_handle2) {
+ Console.WriteLine ("FIRST HANDLE GOT DEALLOCATED!");
+ return 1;
+ }
+
+ return 0;
+ }
+}