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

8247536: Support for pre-generated java.lang.invoke classes in CDS static archive #193

Closed
wants to merge 29 commits into from
Closed

Conversation

yminqi
Copy link
Contributor

@yminqi yminqi commented Sep 15, 2020

This patch is reorganized after 8252725, which is separated from this patch to refactor jlink glugin code. The previous webrev with hg can be found at: http://cr.openjdk.java.net/~minqi/2020/8247536/webrev-05. With 8252725 integrated, the regeneration of holder classes is simply to call the new added GenerateJLIClassesHelper.cdsGenerateHolderClasses function.

Tests: tier1-4


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Testing

Linux x64 Windows x64 macOS x64
Build / test ✔️ (0/0 passed) ✔️ (0/0 passed) ✔️ (0/0 passed)

Issue

  • JDK-8247536: Support for pre-generated java.lang.invoke classes in CDS static archive

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jdk pull/193/head:pull/193
$ git checkout pull/193

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 15, 2020

👋 Welcome back minqi! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Sep 15, 2020

⚠️ @yminqi This pull request contains merges that bring in commits not present in the target repository. Since this is not a "merge style" pull request, these changes will be squashed when this pull request in integrated. If this is your intention, then please ignore this message. If you want to preserve the commit structure, you must change the title of this pull request to Merge <project>:<branch> where <project> is the name of another project in the OpenJDK organization (for example Merge jdk:master).

@openjdk
Copy link

openjdk bot commented Sep 15, 2020

@yminqi The following labels will be automatically applied to this pull request: build core-libs hotspot.

When this pull request is ready to be reviewed, an RFR email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label (add|remove) "label" command.

@openjdk openjdk bot added build build-dev@openjdk.org hotspot hotspot-dev@openjdk.org core-libs core-libs-dev@openjdk.org labels Sep 15, 2020
@yminqi yminqi changed the title Jdk 8247536 8247536: Support for pre-generated java.lang.invoke classes in CDS static archive Sep 15, 2020
@openjdk openjdk bot added the rfr Pull request is ready for review label Sep 15, 2020
@mlbridge
Copy link

mlbridge bot commented Sep 15, 2020

@mlbridge
Copy link

mlbridge bot commented Sep 15, 2020

Mailing list message from Mandy Chung on build-dev:

src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java
367 /** 368 * called from vm to generate MethodHandle holder classes 369
* @return @code { Object[] } if holder classes can be generated. 370 *
@param lines the output lines from @code { VM.cdsTraceResolve } 371 */
@code {....} is wrong syntax. It should be {@code ....} 372 static
Object[] cdsGenerateHolderClasses(String[] lines) { this can be made
private as it's invoked by VM only. Can you move it to the end of the
file. 373 try { 374 Map<String, byte[]> result =
generateHolderClasses(Arrays.stream(lines)); 375 if (result == null) {
376 return null; 377 }

generateHolderClasses should never return null and so line 371-377 can
be dropped. ? I also suggest to add in the generateHolderClasses method
to add Objects.requireNonNull(traces).

379???????????? Object[] ret_array = new Object[size * 2];

Rename `ret_array` to retArray to follow the naming convention using camel case.

src/java.base/share/classes/jdk/internal/misc/VM.java
457 isDumpLoadedClassListSetAndOpen = isDumpLoadedClassListSetAndOpen0();

This should be cached in the caller who checks if -XX:+DumpLoadedClassList
instead of every VM initialization.

Since there are many CDS-related methods, I think it's time to introduce
a new CDS class for these methods to reside (maybe jdk.internal.vm.CDS?).

I suggest to add CDS:logTraceResolve(String line) method that
will check if isDumpLoadedClassListSetAndOpen is true, then call the
native cdsTraceResolve (or whatever name). This way,
GenerateJLIClassesHelper can simply call CDS::logTraceResolve.

493 * Output to DumpLoadedClassList, format is simimar to LF_RESOLVE

s/simimar/similar

494 * @see InvokerBytecodeGenerator
495 * @param line the line to output.

@see is typically placed after @param.

Should it say @see java.lang.invoke.GenerateJLIClassesHelper::traceLambdaForm
instead of InvokerBytecodeGenerator?

Mandy

On 9/15/20 12:15 PM, Yumin Qi wrote:

// exclude the existing class from dump
// find_class assert on SystemDictionary_lock or safepoint
MutexLocker lock(SystemDictionary_lock);
InstanceKlass* old = SystemDictionary::find_class(class_name, cld);
Copy link
Member

Choose a reason for hiding this comment

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

There's no need to call find_class here, since it will return the same class as klass on line 117.

src/hotspot/share/classfile/lambdaFormInvokers.hpp Outdated Show resolved Hide resolved
@@ -1870,7 +1871,8 @@ InstanceKlass* SystemDictionary::find_class(Symbol* class_name, ClassLoaderData*
VerifyDuringGC ||
VerifyBeforeExit ||
VerifyDuringStartup ||
VerifyAfterGC, "too expensive");
VerifyAfterGC ||
DumpSharedSpaces, "too expensive");
Copy link
Member

Choose a reason for hiding this comment

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

This may not be needed if you remove the find_class() call from LambdaFormInvokers::regenerate_holder_classes?

}
if (VM.isDumpLoadedClassListSetAndOpen) {
VM.cdsTraceResolve(traceLF);
}
Copy link
Member

Choose a reason for hiding this comment

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

GenerateJLIClassesHelper shouldn't need to know why the trace is needed. Also, "cdsTraceResolve" is too generic.

I think it's better to have

if (TRACE_RESOLVE || VM.CDS_TRACE_JLINV_RESOLVE) {
    ...
    VM.cdsTraceJLINVResolve(traceLF);

The acronym JLINV is used in methodHandles.cpp

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With CDS related code moved to CDS.java, I think we should keep TRACE_RESOLVE here. A new name like suggested by Mandy, logTraceResolve in CDS.java

* Check if DumpLoadedClassList is set and the file is open.
*/
public static boolean isDumpLoadedClassListSetAndOpen;
private static native boolean isDumpLoadedClassListSetAndOpen0();
Copy link
Member

Choose a reason for hiding this comment

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

I would suggest to rename to isDumpingLoadedClassList

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will change.

@yminqi
Copy link
Contributor Author

yminqi commented Sep 17, 2020

Mailing list message from Mandy Chung on build-dev:

src/java.base/share/classes/java/lang/invoke/GenerateJLIClassesHelper.java
367 /** 368 * called from vm to generate MethodHandle holder classes 369

  • @return @code { Object[] } if holder classes can be generated. 370 *
    @param lines the output lines from @code { VM.cdsTraceResolve } 371 */
    @code {....} is wrong syntax. It should be {@code ....} 372 static
    Object[] cdsGenerateHolderClasses(String[] lines) { this can be made
    private as it's invoked by VM only. Can you move it to the end of the

Will change access to 'private'

file. 373 try { 374 Map<String, byte[]> result =
generateHolderClasses(Arrays.stream(lines)); 375 if (result == null) {
376 return null; 377 }

generateHolderClasses should never return null and so line 371-377 can
be dropped. ? I also suggest to add in the generateHolderClasses method
to add Objects.requireNonNull(traces).

Will drop the check and add Objects.requireNonNull(traces).

379???????????? Object[] ret_array = new Object[size * 2];

Rename ret_array to retArray to follow the naming convention using camel case.

src/java.base/share/classes/jdk/internal/misc/VM.java
457 isDumpLoadedClassListSetAndOpen = isDumpLoadedClassListSetAndOpen0();

This should be cached in the caller who checks if -XX:+DumpLoadedClassList
instead of every VM initialization.

Since there are many CDS-related methods, I think it's time to introduce
a new CDS class for these methods to reside (maybe jdk.internal.vm.CDS?).

I suggest to add CDS:logTraceResolve(String line) method that
will check if isDumpLoadedClassListSetAndOpen is true, then call the
native cdsTraceResolve (or whatever name). This way,
GenerateJLIClassesHelper can simply call CDS::logTraceResolve.

Created a separate issue https://bugs.openjdk.java.net/browse/JDK-8253208 to move CDS method to CDS.java
All CDS related code will be added to CDS.java

493 * Output to DumpLoadedClassList, format is simimar to LF_RESOLVE

s/simimar/similar

494 * @see InvokerBytecodeGenerator
495 * @param line the line to output.

@see is typically placed after @param.

Should it say @see java.lang.invoke.GenerateJLIClassesHelper::traceLambdaForm
instead of InvokerBytecodeGenerator?

Right, will change that to the suggestion.

Mandy

On 9/15/20 12:15 PM, Yumin Qi wrote:

@openjdk
Copy link

openjdk bot commented Sep 25, 2020

@yminqi this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout jdk-8247536
git fetch https://git.openjdk.java.net/jdk master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk openjdk bot added the merge-conflict Pull request has merge conflict with target branch label Sep 25, 2020
@openjdk openjdk bot removed merge-conflict Pull request has merge conflict with target branch rfr Pull request is ready for review labels Sep 25, 2020
@openjdk openjdk bot added the rfr Pull request is ready for review label Sep 25, 2020
"@lambda-form-invoker [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeNothing L7_L (success)",
"@lambda-form-invoker [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeNothing LL_I (success)"),
"@lambda-form-invoker [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeNothing L7_L (anyword)",
"@lambda-form-invoker [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeNothing LL_I anyword"),
Copy link
Member

Choose a reason for hiding this comment

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

We shouldn't allow the classlist to contain arbitrary data. These two cases should generate an error.

@@ -48,6 +48,16 @@

GrowableArray<char*>* LambdaFormInvokers::_lambdaform_lines = NULL;

// trim white spaces from front and end of string.
char* trim(char* s) {
Copy link
Member

Choose a reason for hiding this comment

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

I think this creates unnecessary dependency between the C code and the Java code. The C code assumes that the Java code has appended something like "(salvaged)" into the output, and tries to get rid of that in a non-obvious way. It's better to modify the Java code from

static void traceSpeciesType(String cn, Class<?> salvage) {
    if (TRACE_RESOLVE || CDS.isDumpLoadedClassList()) {
        String traceSP = SPECIES_RESOLVE + " " + cn + (salvage != null ? " (salvaged)" : " (generated)");
        if (TRACE_RESOLVE) {
            System.out.println(traceSP);
        }
        CDS.logTraceResolve(traceSP);
    }
}

to

    if (TRACE_RESOLVE || CDS.isDumpLoadedClassList()) {
        String traceSP = SPECIES_RESOLVE + " " + cn;
        if (TRACE_RESOLVE) {
            System.out.println(traceSP + (salvage != null ? " (salvaged)" : " (generated)"));
        }
        CDS.logTraceResolve(traceSP);
    }

MESSAGE_OK);
// 5. The two lines with worng LF format
dumpShouldPass(
"TESTCASE 5: With incorrect LF format, the line will be ignored",
appJar, classlist(
"Hello",
"@lambda-form-invoker [LF_XYRESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic L7_L (success)",
"@lambda-form-invoker [LF_XYRESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic LL_I (success)"),
"@lambda-form-invoker [LF_XYRESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic L7_L (any)",
Copy link
Member

Choose a reason for hiding this comment

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

We should not allow incorrect input. This should generate an error.

"@lambda-form-invoker [LF_RESOLVE] my.nonexist.package.MyNonExistClassName$holder invokeStatic L7_L (success)",
"@lambda-form-invoker [LF_RESOLVE] my.nonexist.package.MyNonExistClassName$holder invokeStatic LL_I (success)"),
"@lambda-form-invoker [LF_RESOLVE] my.nonexist.package.MyNonExistClassName$holder invokeStatic L7_L",
"@lambda-form-invoker [LF_RESOLVE] my.nonexist.package.MyNonExistClassName$holder invokeStatic LL_I"),
Copy link
Member

Choose a reason for hiding this comment

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

I think it's dangerous to allow arbitrary class names here. InvokerBytecodeGenerator doesn't check the classname. This will make it possible to overwrite the contents of arbitrary classes. We should have a check here and allow only the specific holder classes that are supported.

@@ -26,6 +26,15 @@
package jdk.internal.misc;

public class CDS {
// cache the result
static private boolean isDumpLoadedClassList;
Copy link
Member

Choose a reason for hiding this comment

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

isDumpLoadedClassList is not gramatically correct. Also the field should be final. How about:

static final private boolean isDumpingClassList = isDumpingClassList0();
public static boolean isDumpingClassList() {
    return isDumpingClassList;
}
private static boolean isDumpingClassList0();

/**
* log output to DumpLoadedClassList
*/
public static void logTraceResolve(String line) {
Copy link
Member

Choose a reason for hiding this comment

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

logTraceResolve is too generic. How about CDS.logLambdaFormInvoker() to match the @lambda-form-invoker in the classlist file?

Yumin Qi added 4 commits October 5, 2020 09:16
…ccording to the changes. The invoke name verififcation is not implemented since not all the holder class are processed, not all the functions of processed holder classes are added. For holder class with DirectMethodHandle in its name, only the name in the DMH_METHOD_TYPE_MAP keyset is added, ithe line with other names just gets skipped silently. This makes the verification on invoke names difficul, a name not in the keyset should not fail the test. Also add a boolean to cdsGenerateHolderClasses to indicate call path.
…p to CDS as generateLambdaFormHolderClasses. Added input verification function in CDS before class generation. Added more test scenarios. Removed trailing unused ending words for output of lambda form trace line in case of DumpLoadedClassList.
shortenSignature(basicTypeSignature(type));
if (TRACE_RESOLVE) {
System.out.println(traceLF + (resolvedMember != null ? " (success)" : " (fail)"));
}
Copy link
Member

Choose a reason for hiding this comment

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

I suggest not to change the existing code. Instead, have CDS::traceLambdaFormInvoker
to take individual parameters Class<?> holder, String name, String shortenSignature
(rather than the formatted string). Something like:

    if (CDS.isDumpLoadedClassList()) {
          CDS.traceLambdaFormInvoker(holder, name, shortenSignature(basicTypeSignature(type));
    }

This also gives flexibility to CDS to decide on what format to write to the class list (like this case, you drop the text "success/fail")

In addition, the conditional check on CDS.isDumpLoadedClassList() is hard to relate to why CDS traces these events. I see Ioi's comment on this method name too. I agree with Ioi that isDumpingClassList makes more sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

if (TRACE_RESOLVE) {
System.out.println(traceSP + (salvage != null ? " (salvaged)" : " (generated)"));
}
CDS.traceLambdaFormInvoker(traceSP);
Copy link
Member

Choose a reason for hiding this comment

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

I suggest leaving the existing code unchanged. Instead, add the following:

    if (CDS.isDumpingClassList()) {
         CDS.traceSpeciesType(cn);
    }

The above uses Ioi's suggested method name which reads better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

/**
* check if -XX:+DumpLoadedClassList and given file is open
*/
public static boolean isDumpLoadedClassList() {
Copy link
Member

Choose a reason for hiding this comment

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

I agree with Ioi's suggestion to rename this to isDumpingClassList which describes what the VM is doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

Yumin Qi added 2 commits October 6, 2020 13:12
…he existing function to log lambda form invokers. Changed isDumpLoadedClassList to a reasonable name isDumpingClassList as read only in CDS.
src/hotspot/share/prims/jvm.cpp Outdated Show resolved Hide resolved
@openjdk
Copy link

openjdk bot commented Oct 7, 2020

@yminqi This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8247536: Support for pre-generated java.lang.invoke classes in CDS static archive

Reviewed-by: iklam, mchung

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 61 new commits pushed to the master branch:

  • 7ec9c8e: 8233214: Remove runtime code not needed with CMS removed
  • 536b35b: 8254319: Shenandoah: Interpreter native-LRB needs to activate during HAS_FORWARDED
  • be26972: 8253379: [windows] Several jpackage tests failed with error code 1638
  • 52e45a3: 8229186: Improve error messages for TestStringIntrinsics failures
  • 6d2c1a6: 8254292: Update JMH devkit to 1.26
  • 2bbf8a2: 8245543: Cgroups: Incorrect detection logic on some systems (still reproducible)
  • aaa0a2a: 8254297: Zero and Minimal VMs are broken with undeclared identifier 'DerivedPointerTable' after JDK-8253180
  • 7e80c98: 8254261: fix javadocs in jdk.test.lib.Utils
  • d4b5dfd: 8253857: Shenandoah: Bugs in ShenandoahEvacOOMHandler related code
  • e9c1905: 8253740: [PPC64] Minor interpreter cleanup
  • ... and 51 more: https://git.openjdk.java.net/jdk/compare/82fe023b063ccb989467f8ec69f6d0a50cb97055...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Oct 7, 2020
…ity check on class_list_file is not NULL before check on it is open.
src/java.base/share/classes/jdk/internal/misc/CDS.java Outdated Show resolved Hide resolved
src/java.base/share/classes/jdk/internal/misc/CDS.java Outdated Show resolved Hide resolved
src/java.base/share/classes/jdk/internal/misc/CDS.java Outdated Show resolved Hide resolved

// return null for invalid input
private static Stream<String> validateInputLines(String[] lines) {
ArrayList<String> list = new ArrayList<String>(lines.length);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: this can use diamond operatior like this: new ArrayList<>(lines.length).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will update.

private static Object[] generateLambdaFormHolderClasses(String[] lines) {
Objects.requireNonNull(lines);
try {
Stream<String> lineStream = validateInputLines(lines);
Copy link
Member

Choose a reason for hiding this comment

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

It seems clearer to have validateInputLines do validation only and convert this line into:

  validateInputLines(lines);
  Stream<String> lineStream = Arrays.stream(lines);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Somewhere in the testing framework, the line in ExtraClassList was added '\f' which needs trim, I did not dig into deep the root cause so here just return a new List with ending white spaces trimmed instead. I will file a bug for it and when it fixed, we can do this way.

src/java.base/share/classes/jdk/internal/misc/CDS.java Outdated Show resolved Hide resolved
};
return retArray;
} catch (Exception e) {
e.printStackTrace();
Copy link
Member

Choose a reason for hiding this comment

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

Is this a debugging statement? If CDS swallows the exception thrown, I think VM should emit the warning message and print the stack trace if appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I want to print this in java since in VM it is a little complex than java. It just used to give the stack trace where the exception happened for debug purpose. Maybe I should put comment for it.

Yumin Qi added 2 commits October 7, 2020 19:59
…access it. Changed function validateInputLines to isValidInputLines and return a boolean to indicate its valid. Added more comments for review concern.
…ong inputs. Fixed missed archive_mirror issue which could lead crash for archived heap iteration. After call generateLambdaFormHolderClasses, should check exception first. Added more comments why print out exception message and stacktrace in CDS.
@yminqi
Copy link
Contributor Author

yminqi commented Oct 9, 2020

passed mach5 tier1-4

Copy link
Member

@mlchung mlchung left a comment

Choose a reason for hiding this comment

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

I reviewed the files under src/java.base.

Copy link
Member

@iklam iklam left a comment

Choose a reason for hiding this comment

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

Latest version LGTM.

@yminqi
Copy link
Contributor Author

yminqi commented Oct 10, 2020

/integrate

@openjdk openjdk bot closed this Oct 10, 2020
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Oct 10, 2020
@openjdk
Copy link

openjdk bot commented Oct 10, 2020

@yminqi Since your change was applied there have been 61 commits pushed to the master branch:

  • 7ec9c8e: 8233214: Remove runtime code not needed with CMS removed
  • 536b35b: 8254319: Shenandoah: Interpreter native-LRB needs to activate during HAS_FORWARDED
  • be26972: 8253379: [windows] Several jpackage tests failed with error code 1638
  • 52e45a3: 8229186: Improve error messages for TestStringIntrinsics failures
  • 6d2c1a6: 8254292: Update JMH devkit to 1.26
  • 2bbf8a2: 8245543: Cgroups: Incorrect detection logic on some systems (still reproducible)
  • aaa0a2a: 8254297: Zero and Minimal VMs are broken with undeclared identifier 'DerivedPointerTable' after JDK-8253180
  • 7e80c98: 8254261: fix javadocs in jdk.test.lib.Utils
  • d4b5dfd: 8253857: Shenandoah: Bugs in ShenandoahEvacOOMHandler related code
  • e9c1905: 8253740: [PPC64] Minor interpreter cleanup
  • ... and 51 more: https://git.openjdk.java.net/jdk/compare/82fe023b063ccb989467f8ec69f6d0a50cb97055...master

Your commit was automatically rebased without conflicts.

Pushed as commit e4469d2.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build build-dev@openjdk.org core-libs core-libs-dev@openjdk.org hotspot hotspot-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

3 participants