Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++-ification] Introducing EmbeddedAssemblies class #2606

Merged
merged 1 commit into from
Jan 14, 2019

Conversation

grendello
Copy link
Contributor

@grendello grendello commented Jan 10, 2019

  • removed a number of MONO_API functions, they don't appear to be used anywhere (were supposed to be used by Mono Unreal Engine, but we're not sure if that's the case). We can restore them if needed
  • Simplified a lot of code
  • Removed printf family calls

@grendello grendello added the do-not-merge PR should not be merged. label Jan 10, 2019
@grendello grendello requested a review from jonpryor as a code owner January 10, 2019 21:27
@grendello grendello changed the title [WIP, C++-ification] Introducing EmbeddedAssemblies class [C++-ification] Introducing EmbeddedAssemblies class Jan 11, 2019
@grendello grendello added full-mono-integration-build For PRs; run a full build (~6-10h for mono bumps), not the faster PR subset (~2h for mono bumps) and removed do-not-merge PR should not be merged. labels Jan 11, 2019
int entry_length;
int value_offset;
const char *mapping;
struct TypeMappingInfo *next;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet another struct StructType which could instead be StructType ;-)

}

MONO_API int
monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is Another Repo that cares about our "public API" surface: https://github.com/mono/Embeddinator-4000

In particular, they call monodroid_embedded_assemblies_set_assemblies_prefix():

https://github.com/mono/Embeddinator-4000/blob/c237e21b63df40799ef251350ee961846c549553/support/mono_embeddinator.c#L62

As such:

  1. This export shouldn't be removed, and
  2. I don't think EmbeddedAssemblies::assemblies_prefix can actually be a constexpr.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. is it just this API or all of the ones which were here before?
  2. it can - it's the default, we can use it as long as the 3rd party sets a new one, in which case we'll use the new value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose I don't understand constexpr then; I thought constexpr was for compile-time constants.

@jonathanpeppers: Do you have a feel for which parts of our libmonodroid.so API Embeddinator-4000 uses?

@grendello: From what I can easily tell, monodroid_embedded_assemblies_set_assemblies_prefix is the only one:

$ git grep monodroid_
support/mono_embeddinator.c:MONO_API int monodroid_embedded_assemblies_set_assemblies_prefix (const char *prefix);
support/mono_embeddinator.c:    monodroid_embedded_assemblies_set_assemblies_prefix("assets/assemblies/");

Looking at git grep mono...they use mono.android.jar?!

/me backs away slowly and awaits @jonathanpeppers response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonpryor you understand constexpr correctly, but see the updated code here. We should optimize for the most common case - and that is our prefix in this instance.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

monodroid_embedded_assemblies_set_assemblies_prefix is the only one called by Embeddinator.

I was not able to put assembly files in /assemblies, because AAR files couldn't have arbitrary directories like that. I put them in assets/assemblies and called monodroid_embedded_assemblies_set_assemblies_prefix. I had to include instructions to leave .dll files uncompressed.

size_t si;

MonoAssembly *a = nullptr;
const char *culture = reinterpret_cast<const char*> (monoFunctions.assembly_name_get_culture (aname));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose I should have asked this ages ago, but why monoFunctions and not mono?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this reinterpret_cast<const char*> needed in the first place? DylibMono::assembly_name_get_culture() already returns const char*. This cast should not be needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it's not Mono, just its functions :)


MonoAssembly *a = nullptr;
const char *culture = reinterpret_cast<const char*> (monoFunctions.assembly_name_get_culture (aname));
const char *asmname = reinterpret_cast<const char*> (monoFunctions.assembly_name_get_name (aname));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto here:

const char*
DylibMono::assembly_name_get_name (MonoAssemblyName *aname)

DylibMono::assembly_name_get_name() already returns a const char*. Why is there a cast?

@@ -156,11 +135,10 @@ monodroid_typemap_java_to_managed (const char *java)
return nullptr;
}

MONO_API const char *
monodroid_typemap_managed_to_java (const char *managed)
inline const char*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're inlining a method with a for loop?!

Why?

Copy link
Contributor Author

@grendello grendello Jan 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it faster without incurring another call overhead? This way we end up with code identical, performance and size wise, as before.

const char *data = addr;

if (!p)
struct TypeMappingInfo *p = new TypeMappingInfo (); // calloc (1, sizeof (struct TypeMappingInfo));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet another struct that can be removed.


if (!p)
TypeMappingInfo *p = new TypeMappingInfo (); // calloc (1, sizeof (struct TypeMappingInfo));
if (p == nullptr)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant/unnecessary/contradictory/a source of confusion; as per this and related comments:
#2515 (comment)

We have explicitly stated that new T will either return memory, or abort the process. There is thus no need to continue checking for nullptr return values, unless new(nothrow) T is used.

Thus, a philosophical question: should we have "error handling code" for scenarios that we know and guarantee cannot possibly happen? p will NEVER be nullptr; as such, this and the following line are dead.

Worse than dead, though; misleading: their mere presence suggests that perhaps new T can return NULL, which will be confusing to any newcomers to the codebase: some places are checking the return value, some don't, so which is correct? ¯_(ツ)_/¯

...which is yet another thing I missed/overlooked in PR #2599: it also contains places which use new, then check the return value.

We should be consistent.

Furthermore, consistency should be this:

  • If new T is used, do not check the return value. It cannot be NULL.
  • If new(nothrow) T is used, check the return value; it may be NULL.

should_register = r;
should_register_data = d;
if (assemblies_prefix_override != nullptr)
delete[] assemblies_prefix_override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be free(assemblies_prefix_override), not delete[], as we use strdup().

Copy link
Contributor Author

@grendello grendello Jan 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in preparation for the changes in this PR , it was deliberate

  * removed a number of `MONO_API` functions, they don't appear to be used
    anywhere (were supposed to be used by Mono Unreal Engine, but we're not sure
    if that's the case). We can restore them if needed
  * Simplified a lot of code
  * Removed `printf` family calls
@jonpryor jonpryor merged commit 434d2d8 into dotnet:master Jan 14, 2019
@grendello grendello deleted the cppify+1 branch January 15, 2019 21:07
@github-actions github-actions bot locked and limited conversation to collaborators Feb 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
full-mono-integration-build For PRs; run a full build (~6-10h for mono bumps), not the faster PR subset (~2h for mono bumps)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants