Skip to content

Commit 7174669

Browse files
jonpryorgrendello
authored andcommitted
Implement MonoVM BC Bridge :: Java Marshaling API "thunk"
Commit 9e9daf4 suggested that we could probably "thunk" the MonoVM API to implement the proposed Java Bridge API.. Implement the thunk! Next up: implementing `markCrossReferences` in C#!
1 parent abb0e94 commit 7174669

File tree

4 files changed

+107
-1
lines changed

4 files changed

+107
-1
lines changed

src/Java.Runtime.Environment/Java.Interop/JavaBridgedValueManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public struct ComponentCrossReference {
2323
}
2424

2525
public unsafe struct StronglyConnectedComponent {
26+
public int IsAlive;
2627
public nint Count;
2728
public System.IntPtr* Context;
2829
}

src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,18 @@ partial class JreNativeMethods {
415415

416416
[DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
417417
internal static extern void java_interop_gc_bridge_wait_for_bridge_processing (IntPtr bridge);
418+
419+
[DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
420+
internal static extern unsafe int java_interop_gc_bridge_set_mark_cross_references (
421+
IntPtr bridge,
422+
delegate* unmanaged[Cdecl]<System.Runtime.InteropServices.Java.MarkCrossReferences*, void> markCrossReferences
423+
);
424+
425+
[DllImport (JavaInteropLib, CallingConvention=CallingConvention.Cdecl)]
426+
internal static extern unsafe int java_interop_gc_bridge_release_mark_cross_references_resources (
427+
IntPtr bridge,
428+
System.Runtime.InteropServices.Java.MarkCrossReferences* crossReferences
429+
);
418430
}
419431

420432
sealed class OverrideStackTrace : Exception {

src/java-interop/java-interop-gc-bridge-mono.cc

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct JavaInteropGCBridge {
7676
char *gref_path, *lref_path;
7777
int gref_log_level, lref_log_level;
7878
int gref_cleanup, lref_cleanup;
79+
80+
JavaInteropMarkCrossReferencesCallback mark_cross_references;
7981
};
8082

8183
static jobject
@@ -1283,6 +1285,46 @@ gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGC
12831285
free (thread_name);
12841286
}
12851287

1288+
static void
1289+
managed_gc_cross_references (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs)
1290+
{
1291+
if (mono_bridge->mark_cross_references == NULL) {
1292+
assert (!"mono_bridge->mark_cross_references is NULL; WE SHOULD NOT BE EXECUTING");
1293+
return;
1294+
}
1295+
int i;
1296+
1297+
Srij_MarkCrossReferences cross_references = {};
1298+
1299+
cross_references.ComponentsLen = (void*) (intptr_t) num_sccs;
1300+
cross_references.Components = (Srij_StronglyConnectedComponent*) calloc (num_sccs, sizeof (Srij_StronglyConnectedComponent));
1301+
for (i = 0; i < num_sccs; ++i) {
1302+
Srij_StronglyConnectedComponent *scc = &cross_references.Components [i];
1303+
1304+
scc->Count = (void*) (intptr_t) sccs [i]->num_objs;
1305+
scc->Context = (void**) calloc (sccs [i]->num_objs, sizeof (void*));
1306+
for (int j = 0; j < sccs [i]->num_objs; ++j) {
1307+
MonoObject *obj = sccs [i]->objs [j];
1308+
scc->Context [j] = get_gc_control_block_for_object (mono_bridge, obj);
1309+
}
1310+
}
1311+
1312+
cross_references.CrossReferencesLen = (void*) (intptr_t) num_xrefs;
1313+
cross_references.CrossReferences = (Srij_ComponentCrossReference*) calloc (num_xrefs, sizeof (Srij_ComponentCrossReference));
1314+
for (i = 0; i < num_xrefs; ++i) {
1315+
Srij_ComponentCrossReference *xref = &cross_references.CrossReferences [i];
1316+
xref->SourceGroupIndex = (void*) (intptr_t) xrefs [i].src_scc_index;
1317+
xref->DestinationGroupIndex = (void*) (intptr_t) xrefs [i].dst_scc_index;
1318+
}
1319+
1320+
mono_bridge->mark_cross_references (&cross_references);
1321+
1322+
for (i = 0; i < num_sccs; ++i) {
1323+
Srij_StronglyConnectedComponent *scc = &cross_references.Components [i];
1324+
sccs [i]->is_alive = scc->IsAlive;
1325+
}
1326+
}
1327+
12861328
int
12871329
java_interop_gc_bridge_register_hooks (JavaInteropGCBridge *bridge, int weak_ref_kind)
12881330
{
@@ -1316,7 +1358,9 @@ java_interop_gc_bridge_register_hooks (JavaInteropGCBridge *bridge, int weak_ref
13161358
bridge_cbs.bridge_version = SGEN_BRIDGE_VERSION;
13171359
bridge_cbs.bridge_class_kind = gc_bridge_class_kind;
13181360
bridge_cbs.is_bridge_object = gc_is_bridge_object;
1319-
bridge_cbs.cross_references = gc_cross_references;
1361+
bridge_cbs.cross_references = bridge->mark_cross_references
1362+
? managed_gc_cross_references
1363+
: gc_cross_references;
13201364

13211365
mono_gc_register_bridge_callbacks (&bridge_cbs);
13221366

@@ -1332,3 +1376,28 @@ java_interop_gc_bridge_wait_for_bridge_processing (JavaInteropGCBridge *bridge)
13321376
mono_gc_wait_for_bridge_processing ();
13331377
return 0;
13341378
}
1379+
1380+
int
1381+
java_interop_gc_bridge_set_mark_cross_references (JavaInteropGCBridge *bridge, JavaInteropMarkCrossReferencesCallback markCrossReferences)
1382+
{
1383+
if (bridge == NULL)
1384+
return -1;
1385+
1386+
bridge->mark_cross_references = markCrossReferences;
1387+
1388+
return 0;
1389+
}
1390+
1391+
int
1392+
java_interop_gc_bridge_release_mark_cross_references_resources (JavaInteropGCBridge *bridge, Srij_MarkCrossReferences *crossReferences)
1393+
{
1394+
if (bridge == NULL)
1395+
return -1;
1396+
1397+
if (crossReferences == NULL)
1398+
return -1;
1399+
1400+
// leak it…
1401+
1402+
return 0;
1403+
}

src/java-interop/java-interop-gc-bridge.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@ struct JavaInterop_System_RuntimeTypeHandle {
1919
void *value;
2020
};
2121

22+
typedef struct Srij_ComponentCrossReference {
23+
void *SourceGroupIndex;
24+
void *DestinationGroupIndex;
25+
} Srij_ComponentCrossReference;
26+
27+
typedef struct Srij_StronglyConnectedComponent {
28+
int IsAlive;
29+
void *Count;
30+
void **Context;
31+
} Srij_StronglyConnectedComponent;
32+
33+
typedef struct Srij_MarkCrossReferences {
34+
void *ComponentsLen;
35+
Srij_StronglyConnectedComponent *Components;
36+
void* CrossReferencesLen;
37+
Srij_ComponentCrossReference *CrossReferences;
38+
} Srij_MarkCrossReferences;
39+
40+
typedef void (*JavaInteropMarkCrossReferencesCallback) (Srij_MarkCrossReferences *crossReferences);
41+
2242
JAVA_INTEROP_API JavaInteropGCBridge *java_interop_gc_bridge_get_current (void);
2343
JAVA_INTEROP_API int java_interop_gc_bridge_set_current_once (JavaInteropGCBridge *bridge);
2444

@@ -32,6 +52,10 @@ JAVA_INTEROP_API int java_interop_gc_bridge_add_current_a
3252
JAVA_INTEROP_API int java_interop_gc_bridge_remove_current_app_domain (JavaInteropGCBridge *bridge);
3353

3454
JAVA_INTEROP_API int java_interop_gc_bridge_set_bridge_processing_field (JavaInteropGCBridge *bridge, struct JavaInterop_System_RuntimeTypeHandle type_handle, char *field_name);
55+
56+
JAVA_INTEROP_API int java_interop_gc_bridge_set_mark_cross_references (JavaInteropGCBridge *bridge, JavaInteropMarkCrossReferencesCallback markCrossReferences);
57+
JAVA_INTEROP_API int java_interop_gc_bridge_release_mark_cross_references_resources (JavaInteropGCBridge *bridge, Srij_MarkCrossReferences *crossReferences);
58+
3559
JAVA_INTEROP_API int java_interop_gc_bridge_register_bridgeable_type (JavaInteropGCBridge *bridge, struct JavaInterop_System_RuntimeTypeHandle type_handle);
3660
JAVA_INTEROP_API int java_interop_gc_bridge_enable (JavaInteropGCBridge *bridge, int enable);
3761

0 commit comments

Comments
 (0)