Skip to content
This repository has been archived by the owner on Oct 25, 2021. It is now read-only.

Avoid copying const string constants to the stack. #674

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion objcgen/methodhelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void WriteMethodLookup ()
implementation.Indent++;
implementation.WriteLine ($"__method = mono_get_method (__{AssemblySafeName}_image, 0x{MetadataToken:X8}, {ObjCTypeName}_class);");
implementation.WriteLineUnindented ("#else");
implementation.WriteLine ($"const char __method_name [] = \"{ManagedTypeName}:{MonoSignature}\";");
implementation.WriteLine ($"static const char __method_name [] = \"{ManagedTypeName}:{MonoSignature}\";");
Copy link
Member

Choose a reason for hiding this comment

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

Will this generate the same native code as if the string constant had been passed directly to the method call?

i.e.:

implementation.WriteLine ($"__method = mono_embeddinator_lookup_method (\"{ManagedTypeName}:{MonoSignature}\", {ObjCTypeName}_class);");

Copy link
Author

Choose a reason for hiding this comment

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

Another way is to pass the literal directly.
There are tradeoffs either way.
With msvc:
Literals can be writable or not, depending on version/flags.
Literals can be single-instanced or not, depending on version/flags.
static const will be not writable and not single-instanced.
Ideal is readonly and single instanced.
Non-static const at least with msvc will copy to stack.
Though I have seen clang optimize similar, kinda surprising.
Perhaps literals w/o temporary are best.
Sometimes people will also assign the literal to a pointer.
That is a wasted assignment but only of a pointer, so minor.

implementation.WriteLine ($"__method = mono_embeddinator_lookup_method (__method_name, {ObjCTypeName}_class);");
implementation.Indent--;
implementation.WriteLineUnindented ("#endif");
Expand Down
4 changes: 2 additions & 2 deletions objcgen/objcgenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ protected void Generate (ProcessedFieldInfo field)
implementation.WriteLineUnindented ("#if TOKENLOOKUP");
implementation.WriteLine ($"__field = mono_class_get_field ({managed_type_name}_class, 0x{fi.MetadataToken:X8});");
implementation.WriteLineUnindented ("#else");
implementation.WriteLine ($"const char __field_name [] = \"{fi.Name}\";");
implementation.WriteLine ($"static const char __field_name [] = \"{fi.Name}\";");
implementation.WriteLine ($"__field = mono_class_get_field_from_name ({managed_type_name}_class, __field_name);");
implementation.WriteLineUnindented ("#endif");
implementation.Indent--;
Expand Down Expand Up @@ -898,7 +898,7 @@ protected void Generate (ProcessedFieldInfo field)
implementation.WriteLineUnindented ("#if TOKENLOOKUP");
implementation.WriteLine ($"__field = mono_class_get_field ({managed_type_name}_class, 0x{fi.MetadataToken:X8});");
implementation.WriteLineUnindented ("#else");
implementation.WriteLine ($"const char __field_name [] = \"{fi.Name}\";");
implementation.WriteLine ($"static const char __field_name [] = \"{fi.Name}\";");
implementation.WriteLine ($"__field = mono_class_get_field_from_name ({managed_type_name}_class, __field_name);");
implementation.WriteLineUnindented ("#endif");
implementation.Indent--;
Expand Down