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

[GR-41047] use C++ symbol mangling on Linux to make tools happy #4950

Merged
merged 7 commits into from
Oct 7, 2022

Conversation

adinn
Copy link
Collaborator

@adinn adinn commented Sep 13, 2022

This patch encodes local symbols on Linux using a C++-like bfd compatible encoding of the Java method name and signature. This allows both gdb and Linux tools to demangle method names in most circumstances, including in assembly code listings. If works best best used in combination with option -H:-DeleteLocalSymbols but still improved behaviour for tools without passing that option.

Note that for gdb to display demangled method names after this patch is enabled it is necessary to execute command (gdb) set print asm-demangle.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Sep 13, 2022
@adinn adinn force-pushed the mangling_support branch 6 times, most recently from adbc2ab to 47e81a3 Compare September 14, 2022 12:33
@fniephaus fniephaus added this to the 23.0 milestone Sep 15, 2022
@fniephaus fniephaus changed the title use C++ symbol mangling on Linux to make tools happy [GR-41047] use C++ symbol mangling on Linux to make tools happy Sep 15, 2022
@fniephaus
Copy link
Member

Unfortunately, AOT-compiling Graal.js fails with this:

[libjsvm:51131] Failed generating 'libjsvm' after 5m 33s.
Fatal error: com.oracle.svm.core.util.VMError$HostedError: java.lang.RuntimeException: Illegal replacement of symbol table entry
	at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:72)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:697)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:536)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:580)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:610)
Caused by: java.lang.RuntimeException: Illegal replacement of symbol table entry
	at com.oracle.objectfile.SymbolTable.tryReplace(SymbolTable.java:45)
	at com.oracle.objectfile.elf.ELFSymtab.lambda$addEntry$0(ELFSymtab.java:447)
	at java.base/java.util.HashMap.compute(HashMap.java:1229)
	at com.oracle.objectfile.elf.ELFSymtab.addEntry(ELFSymtab.java:447)
	at com.oracle.objectfile.elf.ELFSymtab.newDefinedEntry(ELFSymtab.java:435)
	at com.oracle.objectfile.elf.ELFObjectFile.createDefinedSymbol(ELFObjectFile.java:187)
	at com.oracle.svm.hosted.image.LIRNativeImageCodeCache$NativeTextSectionImpl.defineMethodSymbol(LIRNativeImageCodeCache.java:491)
	at com.oracle.svm.hosted.image.NativeImage$NativeTextSectionImpl.writeTextSection(NativeImage.java:951)
	at com.oracle.svm.hosted.image.NativeImage.build(NativeImage.java:457)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:685)
	... 5 more
Error: Image build request failed with exit status 1

Any idea what could be going on here, @adinn?

@adinn
Copy link
Collaborator Author

adinn commented Sep 16, 2022

@fniephaus Hi. I have an idea what might going on here but I may need to debug the problem to be sure.

The error means that the map from ResolvedJavaMethod to encoded name is not 1-1. Clearly this cannot the case for uniqueShortName. I can only think of two reasons why my code might be doign this:

  1. I am relying on ResolvedJavaMethod::getname and ResolvedJavaType::toJavaName to provide the base strings that I embed in my encoding whereas uniqueShortName relies on ResolvedJavaType::toClassName. I cannot see how that could make any difference but I may be missing something in how some of the overrides work.
  2. I might be munging these text components together incorrectly in some corner case. The most likely cause I envisage for that would be that I have wrongly applied the C++ mangler substitutions that replace repeated prefixes with terms like S_, S1_` etc. However, there might well be some other coding mistake in there.

Can you provide me with instructions on how to run the gate test in a debugger? If that is not possible can you provide a reproducer I can run that recreates the problem?

@adinn
Copy link
Collaborator Author

adinn commented Sep 16, 2022

@fniephaus @olpaw

Ok, scratch that last comment. I see now that the problem is upstream of method SubstrateUtils.uniqueShortName.

This relates to the patch Paul added to HostedMethod::create some while back to deal with multiple methods with the same print name. That current patched code for that method feeds uniqueShortName a classloader id string and, in the case of a print name clash in the same class loader, a numeric index on the method name. These both serve to disambiguate HostedMethod instances that would otherwise map to the same name.

I can easily inherit Paul's disambiguation fix by making HostedMethod.create invoke the BFD mangler when we are generating Linux debug info. I'll try that and get back to you with the results on the examples I have played with.

I fear this fix may not be the end of the story as the resulting changes to the demangled name may cause problems for the tools. For non-bootstrap classes or methods which require a disambiguation suffix the demangled name will fail to be an exact match for both the name encoded via DWARF and the Java source name. The disparity might not confuse users very much as far as the ability to identify which method is at play is concerned (although it would certainly not be completely transparent). However, I am not clear what problems these deviations might cause perf and/or valgrind to suffer: firstly, during reporting, when trying to connect profile data with the relevant sources and disassembliesl; and secondly, on the command line, when a user needs to specify the method(s) for which reports of profile data are desired.

I don't think the method name ambiguity will constitute a significant problem. This type of ambiguity only in rare cases. However, I think the loader issue is something we need to resolve.

One thing that strikes me is that we don't actually need classloader prefixes for the system or module loader. Names of classes in all 3 initial loaders should not duplicate each other (the delegation rules ought to ensure that is the case). If so then that would mean a lot less opportunity for tools to be stymied by the name change.

In the case where the class is in a user loader not on the system path a solution to the DWARF name mismatch might be to embed the class loader name into the DWARF info. We could just prepend it to the class info name attribute with an extra '.' or '::' separator? Alternatively, we might embed classes belonging to the loader into a namespace whose name is derived from the classloader name?

Any thoughts?

@olpaw
Copy link
Member

olpaw commented Sep 19, 2022

I don't think the method name ambiguity will constitute a significant problem. This type of ambiguity only in rare cases. However, I think the loader issue is something we need to resolve.

Correct. SubstrateUtil.toolFriendlyMangle must have the same semantics as

com.oracle.svm.core.SubstrateUtil#uniqueShortName(java.lang.String, jdk.vm.ci.meta.ResolvedJavaType, java.lang.String, jdk.vm.ci.meta.Signature, boolean)

The classloader must play it's role in uniqueness of the returned String.

Names of classes in all 3 initial loaders should not duplicate each other (the delegation rules ought to ensure that is the case).

This can be implemented as an optimization in SubstrateUtil.toolFriendlyMangle.

Copy link
Member

@olpaw olpaw left a comment

Choose a reason for hiding this comment

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

See comment #4950 (comment)

@olpaw
Copy link
Member

olpaw commented Sep 19, 2022

Also I see internal aarch64 gates failing with these changes with e.g.


[wasm:8777] [7/7] Creating image...                                                                      (0.0s @ 4.10GB)
[wasm:8777] ------------------------------------------------------------------------------------------------------------------------
[wasm:8777]                         7.7s (3.6% of total time) in 64 GCs | Peak RSS: 7.90GB | CPU load: 8.74
[wasm:8777] ========================================================================================================================
[wasm:8777] Failed generating 'wasm' after 3m 34s.
Fatal error: com.oracle.svm.core.util.VMError$HostedError: java.lang.RuntimeException: Illegal replacement of symbol table entry
	at com.oracle.svm.core.util.VMError.shouldNotReachHere(VMError.java:72)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:697)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:536)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:580)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:610)
Caused by: java.lang.RuntimeException: Illegal replacement of symbol table entry
	at com.oracle.objectfile.SymbolTable.tryReplace(SymbolTable.java:45)
	at com.oracle.objectfile.elf.ELFSymtab.lambda$addEntry$0(ELFSymtab.java:447)
	at java.base/java.util.HashMap.compute(HashMap.java:1229)
	at com.oracle.objectfile.elf.ELFSymtab.addEntry(ELFSymtab.java:447)
	at com.oracle.objectfile.elf.ELFSymtab.newDefinedEntry(ELFSymtab.java:435)
	at com.oracle.objectfile.elf.ELFObjectFile.createDefinedSymbol(ELFObjectFile.java:187)
	at com.oracle.svm.hosted.image.LIRNativeImageCodeCache$NativeTextSectionImpl.defineMethodSymbol(LIRNativeImageCodeCache.java:491)
	at com.oracle.svm.hosted.image.NativeImage$NativeTextSectionImpl.writeTextSection(NativeImage.java:951)
	at com.oracle.svm.hosted.image.NativeImage.build(NativeImage.java:457)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:685)
	... 5 more

@adinn
Copy link
Collaborator Author

adinn commented Sep 23, 2022

New version factors out unique short name generation into a provider and configures a BFD-compatible provider when generating debug info on Linux.
Still need to generate namespaces when class names may require a loader id qualifier.

@adinn adinn force-pushed the mangling_support branch 2 times, most recently from 819e1cb to ca079b5 Compare September 23, 2022 15:42
Copy link
Member

@olpaw olpaw left a comment

Choose a reason for hiding this comment

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

See comments on recent changes

public abstract class UniqueShortNameProvider {
private static UniqueShortNameProvider provider = null;

public static synchronized UniqueShortNameProvider provider() {
Copy link
Member

Choose a reason for hiding this comment

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

The convention we usually use here is to name such methods singleton().

It's not a good idea to make this method smart.

I.e. do not make the method synchronized to create a fallback here on first access but instead make sure that ImageSingletons.lookup(UniqueShortNameProvider.class) always returns a valid provider so that the implementation is just return ImageSingletons.lookup(UniqueShortNameProvider.class); and nothing else.

In simple cases you can use annotation @AutomaticallyRegisteredImageSingleton or if you need more flexibility use an internal feature (with @AutomaticallyRegisteredFeature) that uses afterRegistration to set up the UniqueShortNameProvider.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have changed this to use name singleton and simply do an unsynchronized lookup. The default provider is now factored out of the interface and installed as an AutomaticallyRegisteredImageSingleton. It uses an associated BooleanSupplier to enable registration when we have no debug info enabled or are not on Linux.
I have retained the DebugInfoFeature with an afterRegistration callback in order to ensure that the BFD provider gets registered when we do have debug info enabled and are on Linux.

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good.

Please make sure you use the same BooleanSupplier in both so that it's easy to find the belonging parts in an IDE.

Copy link
Member

Choose a reason for hiding this comment

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

@adinn
Copy link
Collaborator Author

adinn commented Sep 27, 2022

@olpaw I have just pushed commits for the rework and for the DWARF changes to embed child DIEs for class compile units with a named loader in a wrapper namespace DIE.

n.b. I had to update the API for UniqueShortNameProvider to expose the loader encoding method

String uniqueShortName(ClassLoader);

That's needed because NativeImageDwarfInfoProvider needs to pass on the loader encoding to the DWARF generator. The default provider just calls into SubstrateUtil to fetch field classNameAndId. However the BFD provider retruns "" for loaders that need to be ignored and for those it does not skip it edits the field value to make it more readable.

Assuming there are nor style or format errors this is ready for re-review.

@adinn adinn force-pushed the mangling_support branch 4 times, most recently from d2a7814 to 74de69e Compare September 27, 2022 17:26
@adinn
Copy link
Collaborator Author

adinn commented Sep 27, 2022

@olpaw The latest push is complete, has no style errors and passes the gate tests apart from two sulong errors unrelated to the patch. gdb, perf and valgrind all successfully recognize the DWARF info and demangle the ELF symbols correctly.

I also tested with your test program that has two versions of the same class. I had to tweak the pom to enable javac debug info and had build source jars for Main, Module1 and Module2. I also had to include the source jars for the Module classes in the source search path (the Main sources are found because they sit next to the Main jar).

gdb identifies both versions of the method located under a namespace derived from the relevant classloader id as shown in the session listing that follows:

(gdb) run
`/home/adinn/redhat/openjdk/graal/graal/substratevm/main' has changed; re-reading symbols.
Starting program: /home/adinn/redhat/openjdk/graal/graal/substratevm/main 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff79ff640 (LWP 1237342)]

Thread 1 "main" hit Breakpoint 1, Main::main(java.lang.String[]*) (args=0x7ffff7a010f0) at Main.java:38
Missing separate debuginfos, use: dnf debuginfo-install zlib-1.2.11-31.fc35.x86_64
(gdb) info fun ::main
All functions matching regular expression "::main":

File Main.java:
38:	void Main::main(java.lang.String[]*);
(gdb) info func ::SameClass
All functions matching regular expression "::SameClass":
(gdb) info func SameClass
All functions matching regular expression "SameClass":

File foo/bar/SameClass.java:
9:	int URLClassLoader_12bcd0c0::foo.bar.SameClass::method();
5:	int URLClassLoader_1fdfafd2::foo.bar.SameClass::method();

File jdk/internal/reflect/Reflection.java:
252:	boolean jdk.internal.reflect.Reflection::isSameClassPackage(java.lang.Class*, java.lang.Class*);
(gdb) c
Continuing.
Hello

Thread 1 "main" hit Breakpoint 2, URLClassLoader_12bcd0c0::foo.bar.SameClass::method() () at foo/bar/SameClass.java:9
(gdb) bt
#0  URLClassLoader_12bcd0c0::foo.bar.SameClass::method() () at foo/bar/SameClass.java:9
#1  0x00000000004a69e6 in com.oracle.svm.core.reflect.ReflectionAccessorHolder::invoke_325e96a0b624d069773b50920fd700a64518797b(java.lang.Object*, java.lang.Object[]*, org.graalvm.nativeimage.c.function.CFunctionPointer*) (__0=<optimized out>, __1=<optimized out>, __2=<optimized out>) at com/oracle/svm/core/reflect/ReflectionAccessorHolder.java:1
#2  0x00000000004a8d0f in com.oracle.svm.core.reflect.SubstrateMethodAccessor::invoke(java.lang.Object*, java.lang.Object[]*) (this=<optimized out>, obj=<optimized out>, args=<optimized out>) at com/oracle/svm/core/reflect/SubstrateMethodAccessor.java:105
#3  0x00000000004060d3 in java.lang.reflect.Method::invoke(java.lang.Object*, java.lang.Object[]*) (this=<optimized out>, obj=<optimized out>, args=<optimized out>) at java/lang/reflect/Method.java:568
#4  Main::main(java.lang.String[]*) (args=<optimized out>) at Main.java:42
#5  0x0000000000413828 in com.oracle.svm.core.JavaMainWrapper::runCore0() () at com/oracle/svm/core/JavaMainWrapper.java:175
#6  0x000000000041353c in com.oracle.svm.core.JavaMainWrapper::runCore() () at com/oracle/svm/core/JavaMainWrapper.java:135
#7  com.oracle.svm.core.JavaMainWrapper::doRun(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (argc=<optimized out>, argv=<optimized out>) at com/oracle/svm/core/JavaMainWrapper.java:232
#8  0x0000000000437feb in com.oracle.svm.core.JavaMainWrapper::run(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (argc=<optimized out>, argv=<optimized out>) at com/oracle/svm/core/JavaMainWrapper.java:218
#9  com.oracle.svm.core.code.IsolateEnterStub::JavaMainWrapper_run_e6899342f5939c89e6e2f78e2c71f5f4926b786d(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (__0=<optimized out>, __1=<optimized out>) at com/oracle/svm/core/code/IsolateEnterStub.java:1
(gdb) c
Continuing.
Calling from Module1
java.lang.Exception: Stack trace
	at java.base@17.0.1/java.lang.Thread.dumpStack(Thread.java:1380)
	at foo.bar.SameClass.method(SameClass.java:10)
	at java.base@17.0.1/java.lang.reflect.Method.invoke(Method.java:568)
	at Main.main(Main.java:42)
java.net.URLClassLoader@12bcd0c0, name: null

Thread 1 "main" hit Breakpoint 2, URLClassLoader_1fdfafd2::foo.bar.SameClass::method() () at foo/bar/SameClass.java:5
(gdb) bt
#0  URLClassLoader_1fdfafd2::foo.bar.SameClass::method() () at foo/bar/SameClass.java:5
#1  0x00000000004a69e6 in com.oracle.svm.core.reflect.ReflectionAccessorHolder::invoke_325e96a0b624d069773b50920fd700a64518797b(java.lang.Object*, java.lang.Object[]*, org.graalvm.nativeimage.c.function.CFunctionPointer*) (__0=<optimized out>, __1=<optimized out>, __2=<optimized out>) at com/oracle/svm/core/reflect/ReflectionAccessorHolder.java:1
#2  0x00000000004a8d0f in com.oracle.svm.core.reflect.SubstrateMethodAccessor::invoke(java.lang.Object*, java.lang.Object[]*) (this=<optimized out>, obj=<optimized out>, args=<optimized out>) at com/oracle/svm/core/reflect/SubstrateMethodAccessor.java:105
#3  0x0000000000406191 in java.lang.reflect.Method::invoke(java.lang.Object*, java.lang.Object[]*) (this=<optimized out>, obj=<optimized out>, args=<optimized out>) at java/lang/reflect/Method.java:568
#4  Main::main(java.lang.String[]*) (args=<optimized out>) at Main.java:43
#5  0x0000000000413828 in com.oracle.svm.core.JavaMainWrapper::runCore0() () at com/oracle/svm/core/JavaMainWrapper.java:175
#6  0x000000000041353c in com.oracle.svm.core.JavaMainWrapper::runCore() () at com/oracle/svm/core/JavaMainWrapper.java:135
#7  com.oracle.svm.core.JavaMainWrapper::doRun(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (argc=<optimized out>, argv=<optimized out>) at com/oracle/svm/core/JavaMainWrapper.java:232
#8  0x0000000000437feb in com.oracle.svm.core.JavaMainWrapper::run(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (argc=<optimized out>, argv=<optimized out>) at com/oracle/svm/core/JavaMainWrapper.java:218
#9  com.oracle.svm.core.code.IsolateEnterStub::JavaMainWrapper_run_e6899342f5939c89e6e2f78e2c71f5f4926b786d(int, org.graalvm.nativeimage.c.type.CCharPointerPointer*) (__0=<optimized out>, __1=<optimized out>) at com/oracle/svm/core/code/IsolateEnterStub.java:1
(gdb) c
Continuing.
Calling from Module2
java.lang.Exception: Stack trace
	at java.base@17.0.1/java.lang.Thread.dumpStack(Thread.java:1380)
	at foo.bar.SameClass.method(SameClass.java:6)
	at java.base@17.0.1/java.lang.reflect.Method.invoke(Method.java:568)
	at Main.main(Main.java:43)
java.net.URLClassLoader@1fdfafd2, name: null
true
java.net.URLClassLoader@12bcd0c0
java.net.URLClassLoader@1fdfafd2
true
true
jdk.internal.loader.ClassLoaders$AppClassLoader@7907ec20
true
TEST PASSED
[Thread 0x7ffff7f8a740 (LWP 1237341) exited]
[Thread 0x7ffff79ff640 (LWP 1237342) exited]
[New process 1237341]
[Inferior 1 (process 1237341) exited normally]

Notice that the two breakpoints are reported at different lines. Of course, the source cache only contains one version of the file -- the one found in the first source jar on the source path. So, the file view when at the second break displays the 'wrong' file, locating the current line in the comment. However, that is only to be expected.

@olpaw
Copy link
Member

olpaw commented Oct 5, 2022

Just to be 100% sure, I did the following experimental change:

diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageBFDNameProvider.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageBFDNameProvider.java
index 7c911ce..bcacbce 100644
--- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageBFDNameProvider.java
+++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageBFDNameProvider.java
@@ -363,7 +363,7 @@ class NativeImageBFDNameProvider implements UniqueShortNameProvider {
         public String mangle(String loaderName, ResolvedJavaType declaringClass, String memberName, Signature methodSignature, boolean isConstructor) {
             String fqn = declaringClass.toJavaName();
             String selector = memberName;
-            if (isConstructor) {
+            if (isConstructor && false) {
                 assert methodSignature != null;
                 assert selector.equals("<init>");
                 int index = fqn.lastIndexOf('.');

which fixes the issue. In other words for constructors mangle breaks it's promise to produce truly unique names for a given set of input parameters because it currently does not take the value of memberName into account.

@olpaw olpaw requested a review from matneu October 5, 2022 12:11
@olpaw
Copy link
Member

olpaw commented Oct 5, 2022

@matneu this PR needs a security review because it modified the symbol names we generate in native-images when the user builds with debug-info generation (-g) on Linux. In this case the symbol names contain the fully qualified type signatures of a method/constructor instead of generating hashes like we do per default. Thus more information is given to the user when this is used.

@adinn
Copy link
Collaborator Author

adinn commented Oct 5, 2022

@olpaw I just pushed a fix that includes the guarantee for uniqueness of the fixed name and modifies the generator to retain any suffix on the constructor name.

@olpaw
Copy link
Member

olpaw commented Oct 5, 2022

@adinn rerunning the CI gates right now ...

@olpaw
Copy link
Member

olpaw commented Oct 6, 2022

@adinn looks like all gates are passing now. There were two failing gates but I suspect them to be transients that I'm rerunning now.

@olpaw
Copy link
Member

olpaw commented Oct 6, 2022

@adinn as usual, please fold style-fix commits into their dominating commits and make all commit messages start with an upper-case letter. After that I'm going to merge this.

@adinn
Copy link
Collaborator Author

adinn commented Oct 6, 2022

Ok, all squashed and ready to ship :-)

@adinn
Copy link
Collaborator Author

adinn commented Oct 6, 2022

Ah, except we have a conflict to resolve.

@adinn
Copy link
Collaborator Author

adinn commented Oct 6, 2022

@olpaw Ok, that was easy to fix.

I had to ensure reflection stub names (based on a digest) start with alpha not alphanum since the C++ encoding uses a length count prefix and a leading digit blends into the count. My addition of an "invoke_" prefix to the name clashed with an independent change to the same line.

I don't think this is going to break anything. Do you need to run the gate test again?

@olpaw
Copy link
Member

olpaw commented Oct 6, 2022

Do you need to run the gate test again?

Yes. On it. If all goes well should be on master by the end of this week.

@olpaw olpaw self-requested a review October 6, 2022 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native-image-debuginfo OCA Verified All contributors have signed the Oracle Contributor Agreement. redhat-interest
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants