Skip to content

Commit

Permalink
Beginnings of initialization code
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Dec 4, 2024
1 parent 555cd9c commit 77aa40a
Show file tree
Hide file tree
Showing 12 changed files with 481 additions and 11 deletions.
13 changes: 13 additions & 0 deletions src/native-clr/host/host-jni.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, jstring lang,
jobjectArray assembliesJava, jboolean isEmulator,
jboolean haveSplitApks)
{
Host::Java_mono_android_Runtime_initInternal (
env,
klass,
lang,
runtimeApksJava,
runtimeNativeLibDir,
appDirs,
localDateTimeOffset,
loader,
assembliesJava,
isEmulator,
haveSplitApks
);
}

JNIEXPORT void
Expand Down
25 changes: 21 additions & 4 deletions src/native-clr/host/host.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <host/host.hh>
#include <host/host-jni.hh>
#include <runtime-base/android-system.hh>
#include <runtime-base/jni-wrappers.hh>
#include <runtime-base/logger.hh>
#include <runtime-base/timing-internal.hh>
#include <shared/log_types.hh>
Expand All @@ -17,10 +18,26 @@ void Host::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass klass, js
FastTiming::initialize ((Logger::log_timing_categories() & LogTimingCategories::FastBare) != LogTimingCategories::FastBare);

size_t total_time_index;
if (FastTiming::enabled ()) [[unlikely]] {
_timing = std::make_unique<Timing> ();
total_time_index = internal_timing->start_event (TimingEventKind::TotalRuntimeInit);
}
if (FastTiming::enabled ()) [[unlikely]] {
_timing = std::make_unique<Timing> ();
total_time_index = internal_timing->start_event (TimingEventKind::TotalRuntimeInit);
}

jstring_array_wrapper applicationDirs (env, appDirs);

jstring_wrapper jstr (env, lang);
Util::set_environment_variable ("LANG", jstr);

jstring_wrapper &home = applicationDirs[Constants::APP_DIRS_FILES_DIR_INDEX];
Util::set_environment_variable_for_directory ("TMPDIR", applicationDirs[Constants::APP_DIRS_CACHE_DIR_INDEX]);
Util::set_environment_variable_for_directory ("HOME", home);

AndroidSystem::detect_embedded_dso_mode (applicationDirs);
AndroidSystem::set_running_in_emulator (isEmulator);

if (FastTiming::enabled ()) [[unlikely]] {
internal_timing->end_event (total_time_index);
}
}

auto Host::Java_JNI_OnLoad (JavaVM *vm, [[maybe_unused]] void *reserved) noexcept -> jint
Expand Down
8 changes: 8 additions & 0 deletions src/native-clr/include/constants.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <fcntl.h>
#include <sys/system_properties.h>

#include <string_view>
Expand Down Expand Up @@ -95,5 +96,12 @@ namespace xamarin::android {

// Documented in NDK's <android/log.h> comments
static constexpr size_t MAX_LOGCAT_MESSAGE_LENGTH = 1023uz;

// PATH_MAX is always 4096 on Linux, but for our purposes it's most likely too much and since
// we use this value to allocate stack variables mostly, let's downsize it a bit to what the
// _XOPEN_PATH_MAX is set to
static constexpr size_t SENSIBLE_PATH_MAX = 1024uz;

static constexpr int DEFAULT_DIRECTORY_MODE = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
};
}
2 changes: 1 addition & 1 deletion src/native-clr/include/host/host.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include <memory>
#include <string_view>

#include <jni.h>

Expand Down
8 changes: 8 additions & 0 deletions src/native-clr/include/runtime-base/android-system.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "../constants.hh"
#include "../shared/log_types.hh"
#include "jni-wrappers.hh"
#include "strings.hh"

namespace xamarin::android {
Expand All @@ -26,14 +27,21 @@ namespace xamarin::android {
}

static auto monodroid_get_system_property (std::string_view const& name, dynamic_local_string<Constants::PROPERTY_VALUE_BUFFER_LEN> &value) noexcept -> int;
static void detect_embedded_dso_mode (jstring_array_wrapper& appDirs) noexcept;

private:
static auto lookup_system_property (std::string_view const &name, size_t &value_len) noexcept -> const char*;
static auto monodroid__system_property_get (std::string_view const&, char *sp_value, size_t sp_value_len) noexcept -> int;
static auto get_max_gref_count_from_system () noexcept -> long;

static void set_embedded_dso_mode_enabled (bool yesno) noexcept
{
embedded_dso_mode_enabled = yesno;
}

private:
static inline long max_gref_count = 0;
static inline bool running_in_emulator = false;
static inline bool embedded_dso_mode_enabled = false;
};
}
209 changes: 209 additions & 0 deletions src/native-clr/include/runtime-base/jni-wrappers.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#pragma once

#include <cstdlib>

#include <jni.h>

#include <shared/cpp-util.hh>

namespace xamarin::android
{
class jstring_array_wrapper;

class jstring_wrapper
{
public:
explicit jstring_wrapper (JNIEnv *_env) noexcept
: env (_env),
jstr (nullptr)
{
abort_if_invalid_pointer_argument (_env, "_env");
}

explicit jstring_wrapper (JNIEnv *_env, const jobject jo) noexcept
: env (_env),
jstr (reinterpret_cast<jstring> (jo))
{
abort_if_invalid_pointer_argument (_env, "_env");
}

explicit jstring_wrapper (JNIEnv *_env, const jstring js) noexcept
: env (_env),
jstr (js)
{
abort_if_invalid_pointer_argument (_env, "_env");
}

jstring_wrapper (const jstring_wrapper&) = delete;

~jstring_wrapper () noexcept
{
release ();
}

jstring_wrapper& operator=(const jstring_wrapper&) = delete;

bool hasValue () noexcept
{
return jstr != nullptr;
}

private:
[[gnu::always_inline]]
void ensure_cstr () noexcept
{
if (cstr != nullptr || env == nullptr) {
return;
}

cstr = env->GetStringUTFChars (jstr, nullptr);
}

public:
const char* get_cstr () noexcept
{
if (jstr == nullptr) {
return nullptr;
}

ensure_cstr ();
return cstr;
}

[[gnu::always_inline]]
const std::string_view get_string_view () noexcept
{
if (jstr == nullptr) {
return {};
}

ensure_cstr ();
return {cstr};
}

jstring_wrapper& operator= (const jobject new_jo) noexcept
{
assign (reinterpret_cast<jstring> (new_jo));
return *this;
}

jstring_wrapper& operator= (const jstring new_js) noexcept
{
assign (new_js);
return *this;
}

protected:
void release () noexcept
{
if (jstr == nullptr || cstr == nullptr || env == nullptr) {
return;
}
env->ReleaseStringUTFChars (jstr, cstr);
jobjectRefType type = env->GetObjectRefType (jstr);
switch (type) {
case JNILocalRefType:
env->DeleteLocalRef (jstr);
break;

case JNIGlobalRefType:
env->DeleteGlobalRef (jstr);
break;

case JNIWeakGlobalRefType:
env->DeleteWeakGlobalRef (jstr);
break;

case JNIInvalidRefType: // To hush compiler warning
break;
}

jstr = nullptr;
cstr = nullptr;
}

void assign (const jstring new_js) noexcept
{
release ();
if (new_js == nullptr) {
return;
}

jstr = new_js;
cstr = nullptr;
}

friend class jstring_array_wrapper;

private:
jstring_wrapper ()
: env (nullptr),
jstr (nullptr)
{}

private:
JNIEnv *env;
jstring jstr;
const char *cstr = nullptr;
};

class jstring_array_wrapper
{
public:
explicit jstring_array_wrapper (JNIEnv *_env) noexcept
: jstring_array_wrapper(_env, nullptr)
{}

explicit jstring_array_wrapper (JNIEnv *_env, jobjectArray _arr)
: env (_env),
arr (_arr)
{
abort_if_invalid_pointer_argument (_env, "_env");
if (_arr != nullptr) {
len = static_cast<size_t>(_env->GetArrayLength (_arr));
if (len > sizeof (static_wrappers) / sizeof (jstring_wrapper)) {
wrappers = new jstring_wrapper [len];
} else {
wrappers = static_wrappers;
}
} else {
len = 0;
wrappers = nullptr;
}
}

~jstring_array_wrapper () noexcept
{
if (wrappers != nullptr && wrappers != static_wrappers) {
delete[] wrappers;
}
}

size_t get_length () const noexcept
{
return len;
}

jstring_wrapper& operator[] (size_t index) noexcept
{
if (index >= len) {
return invalid_wrapper;
}

if (wrappers [index].env == nullptr) {
wrappers [index].env = env;
wrappers [index].jstr = reinterpret_cast <jstring> (env->GetObjectArrayElement (arr, static_cast<jsize>(index)));
}

return wrappers [index];
}

private:
JNIEnv *env;
jobjectArray arr;
size_t len;
jstring_wrapper *wrappers;
jstring_wrapper static_wrappers[5];
jstring_wrapper invalid_wrapper;
};
}
3 changes: 2 additions & 1 deletion src/native-clr/include/runtime-base/strings.hh
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,9 @@ namespace xamarin::android {
[[gnu::always_inline]]
auto append_c (const char *s) noexcept -> string_base&
{
if (s == nullptr)
if (s == nullptr) {
return *this;
}

return append (s, strlen (s));
}
Expand Down
Loading

0 comments on commit 77aa40a

Please sign in to comment.