Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/native/clr/host/bridge-processing.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ void BridgeProcessing::initialize_on_runtime_init (JNIEnv *env, jclass runtimeCl
abort_unless (GCUserPeer_class != nullptr && GCUserPeer_ctor != nullptr, "Failed to load mono.android.GCUserPeer!");
}

BridgeProcessing::BridgeProcessing (MarkCrossReferencesArgs *args) noexcept
: env{ OSBridge::ensure_jnienv () },
BridgeProcessing::BridgeProcessing (JNIEnv *jniEnv, MarkCrossReferencesArgs *args) noexcept
: env{ jniEnv },
cross_refs{ args }
{
if (args == nullptr) [[unlikely]] {
Expand Down
10 changes: 5 additions & 5 deletions src/native/clr/host/gc-bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ void GCBridge::mark_cross_references (MarkCrossReferencesArgs *args) noexcept
abort_if_invalid_pointer_argument (args, "args");
abort_unless (args->Components != nullptr || args->ComponentCount == 0, "Components must not be null if ComponentCount is greater than 0");
abort_unless (args->CrossReferences != nullptr || args->CrossReferenceCount == 0, "CrossReferences must not be null if CrossReferenceCount is greater than 0");
log_mark_cross_references_args_if_enabled (args);

shared_args.store (args);
shared_args_semaphore.release ();
Expand All @@ -64,31 +63,32 @@ void GCBridge::bridge_processing () noexcept
abort_unless (bridge_processing_started_callback != nullptr, "GC bridge processing started callback is not set");
abort_unless (bridge_processing_finished_callback != nullptr, "GC bridge processing finished callback is not set");

JNIEnv *env = OSBridge::ensure_jnienv ();

while (true) {
// wait until mark cross references args are set by the GC callback
shared_args_semaphore.acquire ();
MarkCrossReferencesArgs *args = shared_args.load ();
log_mark_cross_references_args_if_enabled (env, args);

bridge_processing_started_callback (args);

BridgeProcessing bridge_processing {args};
BridgeProcessing bridge_processing {env, args};
bridge_processing.process ();

bridge_processing_finished_callback (args);
}
}

[[gnu::always_inline]]
void GCBridge::log_mark_cross_references_args_if_enabled (MarkCrossReferencesArgs *args) noexcept
void GCBridge::log_mark_cross_references_args_if_enabled (JNIEnv *env, MarkCrossReferencesArgs *args) noexcept
{
if (!Logger::gc_spew_enabled ()) [[likely]] {
return;
}

log_info (LOG_GC, "cross references callback invoked with {} sccs and {} xrefs.", args->ComponentCount, args->CrossReferenceCount);

JNIEnv *env = OSBridge::ensure_jnienv ();

for (size_t i = 0; i < args->ComponentCount; ++i) {
const StronglyConnectedComponent &scc = args->Components [i];
log_info (LOG_GC, "group {} with {} objects", i, scc.Count);
Expand Down
2 changes: 1 addition & 1 deletion src/native/clr/include/host/bridge-processing.hh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct CrossReferenceTarget
class BridgeProcessing
{
public:
BridgeProcessing (MarkCrossReferencesArgs *args) noexcept;
BridgeProcessing (JNIEnv *jniEnv, MarkCrossReferencesArgs *args) noexcept;
static void initialize_on_runtime_init (JNIEnv *jniEnv, jclass runtimeClass) noexcept;
void process () noexcept;
private:
Expand Down
2 changes: 1 addition & 1 deletion src/native/clr/include/host/gc-bridge.hh
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ namespace xamarin::android {
static void bridge_processing () noexcept;
static void mark_cross_references (MarkCrossReferencesArgs *args) noexcept;

static void log_mark_cross_references_args_if_enabled (MarkCrossReferencesArgs *args) noexcept;
static void log_mark_cross_references_args_if_enabled (JNIEnv *env, MarkCrossReferencesArgs *args) noexcept;
static void log_handle_context (JNIEnv *env, HandleContext *ctx) noexcept;
};
}
20 changes: 19 additions & 1 deletion src/native/clr/include/host/os-bridge.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <cstdio>
#include <pthread.h>

#include <jni.h>

Expand Down Expand Up @@ -43,13 +44,30 @@ namespace xamarin::android {
args.version = JNI_VERSION_1_6;
args.name = nullptr;
args.group = nullptr;
jvm->AttachCurrentThread (&env, &args);
jvm->AttachCurrentThreadAsDaemon (&env, &args);
abort_unless (env != nullptr, "Unable to get a valid pointer to JNIEnv");

(void) pthread_once (&thread_local_env_init_key, make_key);
pthread_setspecific (thread_local_env_key, env);
}

return env;
}

private:
static inline pthread_key_t thread_local_env_key = {};
static inline pthread_once_t thread_local_env_init_key = PTHREAD_ONCE_INIT;

static void make_key () noexcept
{
pthread_key_create (&thread_local_env_key, &detach_thread_from_jni);
}

static void detach_thread_from_jni ([[maybe_unused]] void* unused) noexcept
{
jvm->DetachCurrentThread ();
}

private:
static auto _monodroid_gref_inc () noexcept -> int;
static auto _monodroid_gref_dec () noexcept -> int;
Expand Down
Loading