Skip to content

Commit

Permalink
Changes
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Feb 21, 2025
1 parent d725990 commit 8a27480
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ namespace Xamarin.Android.Tasks;

class ApplicationConfigNativeAssemblyGeneratorCLR : LlvmIrComposer
{
// From host_runtime_contract.h in dotnet/runtime
const string HOST_PROPERTY_RUNTIME_CONTRACT = "HOST_RUNTIME_CONTRACT";
const string HOST_PROPERTY_BUNDLE_PROBE = "BUNDLE_PROBE";
const string HOST_PROPERTY_PINVOKE_OVERRIDE = "PINVOKE_OVERRIDE";

sealed class DSOCacheEntryContextDataProvider : NativeAssemblerStructContextDataProvider
{
public override string GetComment (object data, string fieldName)
Expand Down Expand Up @@ -127,26 +132,6 @@ sealed class RuntimePropertyIndexEntry
public uint index;
}

// Order of fields and their types must correspond **exactly** to those in CoreCLR's host_runtime_contract.h
sealed class host_configuration_property
{
[NativeAssembler (IsUTF16 = true)]
public string name;

[NativeAssembler (IsUTF16 = true)]
public string value;
}

// Order of fields and their types must correspond **exactly** to those in CoreCLR's host_runtime_contract.h
const string HostConfigurationPropertiesDataSymbol = "_host_configuration_properties_data";
sealed class host_configuration_properties
{
public ulong nitems;

[NativePointer (PointsToSymbol = HostConfigurationPropertiesDataSymbol)]
public host_configuration_property data;
}

sealed class XamarinAndroidBundledAssemblyContextDataProvider : NativeAssemblerStructContextDataProvider
{
public override ulong GetBufferSize (object data, string fieldName)
Expand Down Expand Up @@ -197,8 +182,6 @@ sealed class XamarinAndroidBundledAssembly
List<StructureInstance<XamarinAndroidBundledAssembly>>? xamarinAndroidBundledAssemblies;
List<StructureInstance<RuntimeProperty>>? runtimePropertiesData;
List<StructureInstance<RuntimePropertyIndexEntry>>? runtimePropertyIndex;
List<StructureInstance<host_configuration_property>> hostConfigurationPropertiesData;
StructureInstance<host_configuration_properties> hostConfigurationProperties;

StructureInfo? applicationConfigStructureInfo;
StructureInfo? dsoCacheEntryStructureInfo;
Expand Down Expand Up @@ -240,7 +223,16 @@ public ApplicationConfigNativeAssemblyGeneratorCLR (IDictionary<string, string>

if (runtimeProperties != null) {
this.runtimeProperties = new SortedDictionary<string, string> (runtimeProperties, StringComparer.Ordinal);
} else {
this.runtimeProperties = new SortedDictionary<string, string> (StringComparer.Ordinal);
}

// This will be filled in by the native host.
this.runtimeProperties[HOST_PROPERTY_RUNTIME_CONTRACT] = String.Empty;

// these mustn't be there, they would break our host contract
this.runtimeProperties.Remove (HOST_PROPERTY_PINVOKE_OVERRIDE);
this.runtimeProperties.Remove (HOST_PROPERTY_BUNDLE_PROBE);
}

protected override void Construct (LlvmIrModule module)
Expand Down Expand Up @@ -310,7 +302,7 @@ protected override void Construct (LlvmIrModule module)
};
module.Add (bundled_assemblies);

(runtimePropertiesData, runtimePropertyIndex, hostConfigurationPropertiesData) = InitRuntimeProperties ();
(runtimePropertiesData, runtimePropertyIndex) = InitRuntimeProperties ();
var runtime_properties = new LlvmIrGlobalVariable (runtimePropertiesData, "runtime_properties", LlvmIrVariableOptions.GlobalConstant) {
Comment = "Runtime config properties",
};
Expand All @@ -322,22 +314,33 @@ protected override void Construct (LlvmIrModule module)
};
module.Add (runtime_property_index);

var _host_configuration_properties_data = new LlvmIrGlobalVariable (hostConfigurationPropertiesData, HostConfigurationPropertiesDataSymbol, LlvmIrVariableOptions.LocalConstant) {
Comment = "Runtime host configuration properties data, encoded using 16-bit Unicode, as expected by CoreCLR",
// HOST_PROPERTY_RUNTIME_CONTRACT will come first, our native runtime requires that since it needs
// to set its value in the values array and we don't want to spend time searching for the index, nor
// we want to add yet another variable storing the index to the entry. KISS.
var runtime_property_names = new List<string> {
HOST_PROPERTY_RUNTIME_CONTRACT,
};
var runtime_property_values = new List<string?> {
null,
};
module.Add (_host_configuration_properties_data);

var hostConfigProps = new host_configuration_properties {
nitems = (ulong)hostConfigurationPropertiesData.Count,
foreach (var kvp in runtimeProperties) {
if (String.Compare (kvp.Key, HOST_PROPERTY_RUNTIME_CONTRACT, StringComparison.Ordinal) == 0) {
continue;
}
runtime_property_names.Add (kvp.Key);
runtime_property_values.Add (kvp.Value);
}

var init_runtime_property_names = new LlvmIrGlobalVariable (runtime_property_names, "init_runtime_property_names", LlvmIrVariableOptions.GlobalConstant) {
Comment = "Names of properties passed to coreclr_initialize",
};
var host_config_props = new LlvmIrGlobalVariable (
new StructureInstance<host_configuration_properties> (hostConfigurationPropertiesStructureInfo, hostConfigProps),
"host_config_properties",
LlvmIrVariableOptions.GlobalConstant)
{
Comment = "Runtime host config properties, for CoreCLR initialization phase"
module.Add (init_runtime_property_names);

var init_runtime_property_values = new LlvmIrGlobalVariable (runtime_property_values, "init_runtime_property_values", LlvmIrVariableOptions.GlobalWritable) {
Comment = "Values of properties passed to coreclr_initialize",
};
module.Add (host_config_props);
module.Add (init_runtime_property_values);

AddAssemblyStores (module);
}
Expand Down Expand Up @@ -368,16 +371,14 @@ void HashAndSortRuntimePropertiesIndex (LlvmIrVariable variable, LlvmIrModuleTar

(
List<StructureInstance<RuntimeProperty>> runtimeProps,
List<StructureInstance<RuntimePropertyIndexEntry>> runtimePropsIndex,
List<StructureInstance<host_configuration_property>> configProps
List<StructureInstance<RuntimePropertyIndexEntry>> runtimePropsIndex
) InitRuntimeProperties ()
{
var runtimeProps = new List<StructureInstance<RuntimeProperty>> ();
var runtimePropsIndex = new List<StructureInstance<RuntimePropertyIndexEntry>> ();
var configProps = new List<StructureInstance<host_configuration_property>> ();

if (runtimeProperties == null || runtimeProperties.Count == 0) {
return (runtimeProps, runtimePropsIndex, configProps);
return (runtimeProps, runtimePropsIndex);
}

foreach (var kvp in runtimeProperties) {
Expand All @@ -398,15 +399,9 @@ List<StructureInstance<host_configuration_property>> configProps
index = (uint)(runtimeProps.Count - 1),
};
runtimePropsIndex.Add (new StructureInstance<RuntimePropertyIndexEntry> (runtimePropertyIndexEntryStructureInfo, indexEntry));

var hostConfigProperty = new host_configuration_property {
name = name,
value = value,
};
configProps.Add (new StructureInstance<host_configuration_property> (hostConfigurationPropertyStructureInfo, hostConfigProperty));
}

return (runtimeProps, runtimePropsIndex, configProps);
return (runtimeProps, runtimePropsIndex);
}

void AddAssemblyStores (LlvmIrModule module)
Expand Down Expand Up @@ -542,7 +537,5 @@ void MapStructures (LlvmIrModule module)
dsoApkEntryStructureInfo = module.MapStructure<DSOApkEntry> ();
runtimePropertyStructureInfo = module.MapStructure<RuntimeProperty> ();
runtimePropertyIndexEntryStructureInfo = module.MapStructure<RuntimePropertyIndexEntry> ();
hostConfigurationPropertyStructureInfo = module.MapStructure<host_configuration_property> ();
hostConfigurationPropertiesStructureInfo = module.MapStructure<host_configuration_properties> ();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2052,7 +2052,7 @@ because xbuild doesn't support framework reference assemblies.
</ItemGroup>
</Target>

<Target Name="_PrepareApplicationSharedLibraryItems">
<Target Name="_PrepareApplicationSharedLibraryItems" Condition=" '$(_AndroidRuntime)' != 'NativeAOT' ">
<ItemGroup>
<_ApplicationSharedLibrary Include="$(_AndroidApplicationSharedLibraryPath)%(_BuildTargetAbis.Identity)\libxamarin-app.so">
<abi>%(_BuildTargetAbis.Identity)</abi>
Expand Down
44 changes: 30 additions & 14 deletions src/native/clr/host/host.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <cstdio>

#include <clr/hosts/coreclrhost.h>

#include <xamarin-app.hh>
Expand Down Expand Up @@ -26,7 +28,7 @@ size_t Host::clr_get_runtime_property (const char *key, char *value_buffer, size
return 0;
}

bool Host::clr_bundle_probe (const char *path, void **data_start, int64_t *size) noexcept
bool Host::clr_external_assembly_probe (const char *path, void **data_start, int64_t *size) noexcept
{
log_debug (LOG_DEFAULT, "clr_bundle_probe (\"{}\"...)", path);
if (data_start == nullptr || size == nullptr) {
Expand Down Expand Up @@ -133,8 +135,10 @@ auto Host::create_delegate (
&delegate
);
log_debug (LOG_ASSEMBLY,
"{} delegate creation result == {:x}; delegate == {:p}",
Constants::JNIENVINIT_FULL_TYPE_NAME,
"{}@{}.{} delegate creation result == {:x}; delegate == {:p}",
assembly_name,
type_name,
method_name,
static_cast<unsigned int>(hr),
delegate
);
Expand Down Expand Up @@ -191,17 +195,32 @@ void Host::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass runtimeCl

gather_assemblies_and_libraries (runtimeApks, haveSplitApks);

log_write (LOG_DEFAULT, LogLevel::Info, "Calling CoreCLR initialization routine");
size_t clr_init_time_index;
if (FastTiming::enabled ()) [[unlikely]] {
clr_init_time_index = internal_timing.start_event (TimingEventKind::MonoRuntimeInit);
}

coreclr_set_error_writer (clr_error_writer);
int hr = android_coreclr_initialize (
// We REALLY shouldn't be doing this
snprintf (host_contract_ptr_buffer.data (), host_contract_ptr_buffer.size (), "%p", &runtime_contract);

// The first entry in the property arrays is for the host contract pointer. Application build makes sure
// of that.
init_runtime_property_values[0] = host_contract_ptr_buffer.data ();
int hr = coreclr_initialize (
application_config.android_package_name,
u"Xamarin.Android",
&runtime_contract,
&host_config_properties,
"Xamarin.Android",
(int)application_config.number_of_runtime_properties,
init_runtime_property_names,
const_cast<const char**>(init_runtime_property_values),
&clr_host,
&domain_id
);
log_debug (LOG_ASSEMBLY, "CoreCLR init result == {:x}; clr_host == {:p}; domain ID == {}", static_cast<unsigned int>(hr), clr_host, domain_id);

if (FastTiming::enabled ()) [[unlikely]] {
internal_timing.end_event (clr_init_time_index);
}

// TODO: make S_OK & friends known to us
if (hr != 0 /* S_OK */) {
Helpers::abort_application (
Expand Down Expand Up @@ -253,8 +272,6 @@ void Host::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass runtimeCl

OSBridge::initialize_on_runtime_init (env, runtimeClass);

log_debug (LOG_DEFAULT, "Calling into managed runtime init"sv);

size_t native_to_managed_index;
if (FastTiming::enabled ()) [[unlikely]] {
native_to_managed_index = internal_timing.start_event (TimingEventKind::NativeToManagedTransition);
Expand Down Expand Up @@ -288,13 +305,12 @@ void Host::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass runtimeCl
);
}
);

log_debug (LOG_DEFAULT, "Calling into managed runtime init"sv);
initialize (&init);

if (FastTiming::enabled ()) [[unlikely]] {
internal_timing.end_event (native_to_managed_index);
}

if (FastTiming::enabled ()) [[unlikely]] {
internal_timing.end_event (total_time_index);
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/native/clr/host/typemap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,6 @@ auto TypeMapper::find_java_to_managed_entry (hash_t name_hash) noexcept -> const
[[gnu::flatten]]
auto TypeMapper::typemap_java_to_managed (const char *typeName) noexcept -> const char*
{
log_warn (LOG_ASSEMBLY, "{} WIP"sv, __PRETTY_FUNCTION__);
log_warn (LOG_ASSEMBLY, " asking for '{}'"sv, optional_string (typeName));

if (typeName == nullptr) [[unlikely]] {
return nullptr;
}
Expand Down
8 changes: 6 additions & 2 deletions src/native/clr/include/host/host.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <array>
#include <string_view>

#include <jni.h>
Expand Down Expand Up @@ -34,7 +35,7 @@ namespace xamarin::android {
static void gather_assemblies_and_libraries (jstring_array_wrapper& runtimeApks, bool have_split_apks);

static size_t clr_get_runtime_property (const char *key, char *value_buffer, size_t value_buffer_size, void *contract_context) noexcept;
static bool clr_bundle_probe (const char *path, void **data_start, int64_t *size) noexcept;
static bool clr_external_assembly_probe (const char *path, void **data_start, int64_t *size) noexcept;
static const void* clr_pinvoke_override (const char *library_name, const char *entry_point_name) noexcept;
static void clr_error_writer (const char *message) noexcept;

Expand All @@ -56,9 +57,12 @@ namespace xamarin::android {
.size = sizeof(host_runtime_contract),
.context = nullptr,
.get_runtime_property = clr_get_runtime_property,
.android_bundle_probe = clr_bundle_probe,
.external_assembly_probe = clr_external_assembly_probe,
.bundle_probe = nullptr,
.pinvoke_override = clr_pinvoke_override,
};

// Enough to fit 0xffffffffffffffff + terminating NUL
static inline std::array<char, 19> host_contract_ptr_buffer{};
};
}
3 changes: 2 additions & 1 deletion src/native/clr/include/xamarin-app.hh
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ extern "C" {
[[gnu::visibility("default")]] extern const RuntimeProperty runtime_properties[];
[[gnu::visibility("default")]] extern const RuntimePropertyIndexEntry runtime_property_index[];

[[gnu::visibility("default")]] extern const host_configuration_properties host_config_properties;
[[gnu::visibility("default")]] extern const char *init_runtime_property_names[];
[[gnu::visibility("default")]] extern char *init_runtime_property_values[];
}

//
Expand Down
4 changes: 2 additions & 2 deletions src/native/clr/runtime-base/android-system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,9 @@ AndroidSystem::setup_environment () noexcept
var_value = "";
}

if constexpr (Constants::is_debug_build) {
// if constexpr (Constants::is_debug_build) {
log_info (LOG_DEFAULT, "Setting environment variable '{}' to '{}'", var_name, var_value);
}
// }

if (setenv (var_name, var_value, 1) < 0) {
log_warn (LOG_DEFAULT, "Failed to set environment variable: {}", strerror (errno));
Expand Down
26 changes: 5 additions & 21 deletions src/native/clr/xamarin-app-stub/application_dso_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -340,26 +340,10 @@ const RuntimePropertyIndexEntry runtime_property_index[] = {
},
};

namespace {
const host_configuration_property _host_configuration_properties_data[] = {
{
.name = u"test_string",
.value = u"string value",
},

{
.name = u"test_integer",
.value = u"23",
},

{
.name = u"test_boolean",
.value = u"true",
},
};
}
const char *init_runtime_property_names[] = {
"HOST_RUNTIME_CONTRACT",
};

const host_configuration_properties host_config_properties = {
.nitems = 3,
.data = _host_configuration_properties_data,
char *init_runtime_property_values[] {
nullptr,
};

0 comments on commit 8a27480

Please sign in to comment.