diff --git a/.gitignore b/.gitignore index 3f711a8..36c00d3 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ /openjdk-jdk21u-jdk-21+35.tar.xz /openjdk-21+35.tar.xz /openjdk-21.0.1+12.tar.xz +/openjdk-21.0.2+11.tar.xz +/openjdk-21.0.2+12.tar.xz +/openjdk-21.0.2+13.tar.xz diff --git a/NEWS b/NEWS index 09d1dfe..24382b1 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,416 @@ Key: JDK-X - https://bugs.openjdk.java.net/browse/JDK-X CVE-XXXX-YYYY: https://cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY +New in release OpenJDK 21.0.2 (2024-01-16): +=========================================== + +* CVEs + - CVE-2024-20918 + - CVE-2024-20919 + - CVE-2024-20921 + - CVE-2024-20945 + - CVE-2024-20952 +* Security fixes + - JDK-8308204: Enhanced certificate processing + - JDK-8314295: Enhance verification of verifier + - JDK-8314307: Improve loop handling + - JDK-8314468: Improve Compiler loops + - JDK-8316976: Improve signature handling + - JDK-8317547: Enhance TLS connection support +* Other changes + - JDK-8038244: (fs) Check return value of malloc in Java_sun_nio_fs_AixNativeDispatcher_getmntctl() + - JDK-8161536: sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java fails with ProviderException + - JDK-8219652: [aix] Tests failing with JNI attach problems. + - JDK-8225377: type annotations are not visible to javac plugins across compilation boundaries + - JDK-8232839: JDI AfterThreadDeathTest.java failed due to "FAILED: Did not get expected IllegalThreadStateException on a StepRequest.enable()" + - JDK-8267502: JDK-8246677 caused 16x performance regression in SynchronousQueue + - JDK-8267509: Improve IllegalAccessException message to include the cause of the exception + - JDK-8268916: Tests for AffirmTrust roots + - JDK-8286757: adlc tries to build with /pathmap but without /experimental:deterministic + - JDK-8294156: Allow PassFailJFrame.Builder to create test UI + - JDK-8294158: HTML formatting for PassFailJFrame instructions + - JDK-8294427: Check boxes and radio buttons have rendering issues on Windows in High DPI env + - JDK-8294535: Add screen capture functionality to PassFailJFrame + - JDK-8295068: SSLEngine throws NPE parsing CertificateRequests + - JDK-8295555: Primitive wrapper caches could be `@Stable` + - JDK-8299614: Shenandoah: STW mark should keep nmethod/oops referenced from stack chunk alive + - JDK-8300663: java/util/concurrent/SynchronousQueue/Fairness.java failed with "Error: fair=true i=0 j=1" + - JDK-8301247: JPackage app-image exe launches multiple exe's in JDK 17+ + - JDK-8301341: LinkedTransferQueue does not respect timeout for poll() + - JDK-8301457: Code in SendPortZero.java is uncommented even after JDK-8236852 was fixed + - JDK-8301489: C1: ShortLoopOptimizer might lift instructions before their inputs + - JDK-8301846: Invalid TargetDataLine after screen lock when using JFileChooser or COM library + - JDK-8303737: C2: Load can bypass subtype check that enforces it's from the right object type + - JDK-8306561: Possible out of bounds access in print_pointer_information + - JDK-8308103: Massive (up to ~30x) increase in C2 compilation time since JDK 17 + - JDK-8308452: Extend internal Architecture enum with byte order and address size + - JDK-8308479: [s390x] Implement alternative fast-locking scheme + - JDK-8308592: Framework for CA interoperability testing + - JDK-8308593: Add KEEPALIVE Extended Socket Options Support for Windows + - JDK-8309209: C2 failed "assert(_stack_guard_state == stack_guard_reserved_disabled) failed: inconsistent state" + - JDK-8309305: sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java fails with jtreg test timeout + - JDK-8309545: Thread.interrupted from virtual thread needlessly resets interrupt status + - JDK-8309663: test fails "assert(check_alignment(result)) failed: address not aligned: 0x00000008baadbabe" + - JDK-8309778: java/nio/file/Files/CopyAndMove.java fails when using second test directory + - JDK-8309974: some JVMCI tests fail when VM options include -XX:+EnableJVMCI + - JDK-8310239: Add missing cross modifying fence in nmethod entry barriers + - JDK-8310512: Cleanup indentation in jfc files + - JDK-8310596: Utilize existing method frame::interpreter_frame_monitor_size_in_bytes() + - JDK-8310982: jdk/internal/util/ArchTest.java fails after JDK-8308452 failed with Method isARM() + - JDK-8311261: [AIX] TestAlwaysPreTouchStacks.java fails due to java.lang.RuntimeException: Did not find expected NMT output + - JDK-8311514: Incorrect regex in TestMetaSpaceLog.java + - JDK-8311585: Add JRadioButtonMenuItem to bug8031573.java + - JDK-8311591: Add SystemModulesPlugin test case that splits module descriptors with new local variables defined by DedupSetBuilder + - JDK-8311630: [s390] Implementation of Foreign Function & Memory API (Preview) + - JDK-8311631: When multiple users run tools/jpackage/share/LicenseTest.java, Permission denied for writing /var/tmp/*.files + - JDK-8311680: Update the release version after forking Oct CPU23_10 + - JDK-8311681: Update the Jan CPU24_01 release date in master branch after forking Oct CPU23_10 + - JDK-8311813: C1: Uninitialized PhiResolver::_loop field + - JDK-8311938: Add default cups include location for configure on AIX + - JDK-8312078: [PPC] JcmdScale.java Failing on AIX + - JDK-8312126: NullPointerException in CertStore.getCRLs after 8297955 + - JDK-8312166: (dc) DatagramChannel's socket adaptor does not release carrier thread when blocking in receive + - JDK-8312174: missing JVMTI events from vthreads parked during JVMTI attach + - JDK-8312191: ColorConvertOp.filter for the default destination is too slow + - JDK-8312433: HttpClient request fails due to connection being considered idle and closed + - JDK-8312434: SPECjvm2008/xml.transform with CDS fails with "can't seal package nu.xom" + - JDK-8312440: assert(cast != nullptr) failed: must have added a cast to pin the node + - JDK-8312466: /bin/nm usage in AIX makes needs -X64 flag + - JDK-8312467: relax the builddir check in make/autoconf/basic.m4 + - JDK-8312592: New parentheses warnings after HarfBuzz 7.2.0 update + - JDK-8312612: handle WideCharToMultiByte return values + - JDK-8313164: src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp GetRGBPixels adjust releasing of resources + - JDK-8313167: Update to use jtreg 7.3 + - JDK-8313206: PKCS11 tests silently skip execution + - JDK-8313244: NM flags handling in configure process + - JDK-8313252: Java_sun_awt_windows_ThemeReader_paintBackground release resources in early returns + - JDK-8313322: RISC-V: implement MD5 intrinsic + - JDK-8313368: (fc) FileChannel.size returns 0 on block special files + - JDK-8313575: Refactor PKCS11Test tests + - JDK-8313616: support loading library members on AIX in os::dll_load + - JDK-8313643: Update HarfBuzz to 8.2.2 + - JDK-8313656: assert(!JvmtiExport::can_support_virtual_threads()) with -XX:-DoJVMTIVirtualThreadTransitions + - JDK-8313756: [BACKOUT] 8308682: Enhance AES performance + - JDK-8313760: [REDO] Enhance AES performance + - JDK-8313779: RISC-V: use andn / orn in the MD5 instrinsic + - JDK-8313781: Add regression tests for large page logging and user-facing error messages + - JDK-8313782: Add user-facing warning if THPs are enabled but cannot be used + - JDK-8313792: Verify 4th party information in src/jdk.internal.le/share/legal/jline.md + - JDK-8313873: java/nio/channels/DatagramChannel/SendReceiveMaxSize.java fails on AIX due to small default RCVBUF size and different IPv6 Header interpretation + - JDK-8314045: ArithmeticException in GaloisCounterMode + - JDK-8314094: java/lang/ProcessHandle/InfoTest.java fails on Windows when run as user with Administrator privileges + - JDK-8314120: Add tests for FileDescriptor.sync + - JDK-8314121: test tools/jpackage/share/RuntimePackageTest.java#id0 fails on RHEL8 + - JDK-8314191: C2 compilation fails with "bad AD file" + - JDK-8314226: Series of colon-style fallthrough switch cases with guards compiled incorrectly + - JDK-8314242: Update applications/scimark/Scimark.java to accept VM flags + - JDK-8314246: javax/swing/JToolBar/4529206/bug4529206.java fails intermittently on Linux + - JDK-8314263: Signed jars triggering Logger finder recursion and StackOverflowError + - JDK-8314330: java/foreign tests should respect vm flags when start new processes + - JDK-8314476: TestJstatdPortAndServer.java failed with "java.rmi.NoSuchObjectException: no such object in table" + - JDK-8314495: Update to use jtreg 7.3.1 + - JDK-8314551: More generic way to handshake GC threads with monitor deflation + - JDK-8314580: PhaseIdealLoop::transform_long_range_checks fails with assert "was tested before" + - JDK-8314632: Intra-case dominance check fails in the presence of a guard + - JDK-8314759: VirtualThread.parkNanos timeout adjustment when pinned should be replaced + - JDK-8314883: Java_java_util_prefs_FileSystemPreferences_lockFile0 write result errno in missing case + - JDK-8314935: Shenandoah: Unable to throw OOME on back-to-back Full GCs + - JDK-8315026: ProcessHandle implementation listing processes on AIX should use getprocs64 + - JDK-8315062: [GHA] get-bootjdk action should return the abolute path + - JDK-8315082: [REDO] Generational ZGC: Tests crash with assert(index == 0 || is_power_of_2(index)) + - JDK-8315088: C2: assert(wq.size() - before == EMPTY_LOOP_SIZE) failed: expect the EMPTY_LOOP_SIZE nodes of this body if empty + - JDK-8315195: RISC-V: Update hwprobe query for new extensions + - JDK-8315206: RISC-V: hwprobe query is_set return wrong value + - JDK-8315213: java/lang/ProcessHandle/TreeTest.java test enhance output of children + - JDK-8315214: Do not run sun/tools/jhsdb tests concurrently + - JDK-8315362: NMT: summary diff reports threads count incorrectly + - JDK-8315377: C2: assert(u->find_out_with(Op_AddP) == nullptr) failed: more than 2 chained AddP nodes? + - JDK-8315383: jlink SystemModulesPlugin incorrectly parses the options + - JDK-8315415: OutputAnalyzer.shouldMatchByLine() fails in some cases + - JDK-8315437: Enable parallelism in vmTestbase/nsk/monitoring/stress/classload tests + - JDK-8315442: Enable parallelism in vmTestbase/nsk/monitoring/stress/thread tests + - JDK-8315452: Erroneous AST missing modifiers for partial input + - JDK-8315499: build using devkit on Linux ppc64le RHEL puts path to devkit into libsplashscreen + - JDK-8315545: C1: x86 cmove can use short branches + - JDK-8315549: CITime misreports code/total nmethod sizes + - JDK-8315554: C1: Replace "cmp reg, 0" with "test reg, reg" on x86 + - JDK-8315578: PPC builds are broken after JDK-8304913 + - JDK-8315579: SPARC64 builds are broken after JDK-8304913 + - JDK-8315606: Open source few swing text/html tests + - JDK-8315612: RISC-V: intrinsic for unsignedMultiplyHigh + - JDK-8315644: increase timeout of sun/security/tools/jarsigner/Warning.java + - JDK-8315651: Stop hiding AIX specific multicast socket errors via NetworkConfiguration (aix) + - JDK-8315683: Parallelize java/util/concurrent/tck/JSR166TestCase.java + - JDK-8315684: Parallelize sun/security/util/math/TestIntegerModuloP.java + - JDK-8315688: Update jdk21u fix version to 21.0.2 + - JDK-8315692: Parallelize gc/stress/TestStressRSetCoarsening.java test + - JDK-8315696: SignedLoggerFinderTest.java test failed + - JDK-8315702: jcmd Thread.dump_to_file slow with millions of virtual threads + - JDK-8315706: com/sun/tools/attach/warnings/DynamicLoadWarningTest.java real fix for failure on AIX + - JDK-8315735: VerifyError when switch statement used with synchronized block + - JDK-8315751: RandomTestBsi1999 fails often with timeouts on Linux ppc64le + - JDK-8315766: Parallelize gc/stress/TestStressIHOPMultiThread.java test + - JDK-8315770: serviceability/sa/TestJmapCoreMetaspace.java should run with -XX:-VerifyDependencies + - JDK-8315774: Enable parallelism in vmTestbase/gc/g1/unloading tests + - JDK-8315863: [GHA] Update checkout action to use v4 + - JDK-8315869: UseHeavyMonitors not used + - JDK-8315920: C2: "control input must dominate current control" assert failure + - JDK-8315931: RISC-V: xxxMaxVectorTestsSmokeTest fails when using RVV + - JDK-8315936: Parallelize gc/stress/TestStressG1Humongous.java test + - JDK-8315937: Enable parallelism in vmTestbase/nsk/stress/numeric tests + - JDK-8315942: Sort platform enums and definitions after JDK-8304913 follow-ups + - JDK-8315960: test/jdk/java/io/File/TempDirDoesNotExist.java leaves test files behind + - JDK-8315971: ProblemList containers/docker/TestMemoryAwareness.java on linux-all + - JDK-8316003: Update FileChooserSymLinkTest.java to HTML instructions + - JDK-8316017: Refactor timeout handler in PassFailJFrame + - JDK-8316025: Use testUI() method of PassFailJFrame.Builder in FileChooserSymLinkTest.java + - JDK-8316030: Update Libpng to 1.6.40 + - JDK-8316031: SSLFlowDelegate should not log from synchronized block + - JDK-8316060: test/hotspot/jtreg/runtime/reflect/ReflectOutOfMemoryError.java may fail if heap is huge + - JDK-8316087: Test SignedLoggerFinderTest.java is still failing + - JDK-8316113: Infinite permission checking loop in java/net/spi/InetAddressResolverProvider/RuntimePermissionTest + - JDK-8316123: ProblemList serviceability/dcmd/gc/RunFinalizationTest.java on AIX + - JDK-8316130: Incorrect control in LibraryCallKit::inline_native_notify_jvmti_funcs + - JDK-8316142: Enable parallelism in vmTestbase/nsk/monitoring/stress/lowmem tests + - JDK-8316156: ByteArrayInputStream.transferTo causes MaxDirectMemorySize overflow + - JDK-8316178: Better diagnostic header for CodeBlobs + - JDK-8316179: Use consistent naming for lightweight locking in MacroAssembler + - JDK-8316181: Move the fast locking implementation out of the .ad files + - JDK-8316199: Remove sun/tools/jstatd/TestJstatd* tests from problemlist for Windows. + - JDK-8316206: Test StretchedFontTest.java fails for Baekmuk font + - JDK-8316304: (fs) Add support for BasicFileAttributes.creationTime() for Linux + - JDK-8316337: (bf) Concurrency issue in DirectByteBuffer.Deallocator + - JDK-8316341: sun/security/pkcs11/PKCS11Test.java needs adjustment on Linux ppc64le Ubuntu 22 + - JDK-8316387: Exclude more failing multicast tests on AIX after JDK-8315651 + - JDK-8316396: Endless loop in C2 compilation triggered by AddNode::IdealIL + - JDK-8316399: Exclude java/net/MulticastSocket/Promiscuous.java on AIX + - JDK-8316400: Exclude jdk/jfr/event/runtime/TestResidentSetSizeEvent.java on AIX + - JDK-8316401: sun/tools/jhsdb/JStackStressTest.java failed with "InternalError: We should have found a thread that owns the anonymous lock" + - JDK-8316411: compiler/compilercontrol/TestConflictInlineCommands.java fails intermittent with force inline by CompileCommand missing + - JDK-8316414: C2: large byte array clone triggers "failed: malformed control flow" assertion failure on linux-x86 + - JDK-8316415: Parallelize sun/security/rsa/SignedObjectChain.java subtests + - JDK-8316418: containers/docker/TestMemoryWithCgroupV1.java get OOM killed with Parallel GC + - JDK-8316436: ContinuationWrapper uses unhandled nullptr oop + - JDK-8316461: Fix: make test outputs TEST SUCCESS after unsuccessful exit + - JDK-8316468: os::write incorrectly handles partial write + - JDK-8316514: Better diagnostic header for VtableStub + - JDK-8316540: StoreReproducibilityTest fails on some locales + - JDK-8316566: RISC-V: Zero extended narrow oop passed to Atomic::cmpxchg + - JDK-8316581: Improve performance of Symbol::print_value_on() + - JDK-8316585: [REDO] runtime/InvocationTests spend a lot of time on dependency verification + - JDK-8316645: RISC-V: Remove dependency on libatomic by adding cmpxchg 1b + - JDK-8316648: jrt-fs.jar classes not reproducible between standard and bootcycle builds + - JDK-8316659: assert(LockingMode != LM_LIGHTWEIGHT || flag == CCR0) failed: bad condition register + - JDK-8316671: sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java test fails intermittent with Read timed out + - JDK-8316679: C2 SuperWord: wrong result, load should not be moved before store if not comparable + - JDK-8316710: Exclude java/awt/font/Rotate/RotatedTextTest.java + - JDK-8316719: C2 compilation still fails with "bad AD file" + - JDK-8316735: Print LockStack in hs_err files + - JDK-8316741: BasicStroke.createStrokedShape miter-limits failing on small shapes + - JDK-8316743: RISC-V: Change UseVectorizedMismatchIntrinsic option result to warning + - JDK-8316746: Top of lock-stack does not match the unlocked object + - JDK-8316778: test hprof lib: invalid array element type from JavaValueArray.elementSize + - JDK-8316859: RISC-V: Disable detection of V through HWCAP + - JDK-8316879: RegionMatches1Tests fails if CompactStrings are disabled after JDK-8302163 + - JDK-8316880: AArch64: "stop: Header is not fast-locked" with -XX:-UseLSE since JDK-8315880 + - JDK-8316894: make test TEST="jtreg:test/jdk/..." fails on AIX + - JDK-8316906: Clarify TLABWasteTargetPercent flag + - JDK-8316929: Shenandoah: Shenandoah degenerated GC and full GC need to cleanup old OopMapCache entries + - JDK-8316933: RISC-V: compiler/vectorapi/VectorCastShape128Test.java fails when using RVV + - JDK-8316935: [s390x] Use consistent naming for lightweight locking in MacroAssembler + - JDK-8316958: Add test for unstructured locking + - JDK-8316967: Correct the scope of vmtimer in UnregisteredClasses::load_class + - JDK-8317039: Enable specifying the JDK used to run jtreg + - JDK-8317136: [AIX] Problem List runtime/jni/terminatedThread/TestTerminatedThread.java + - JDK-8317257: RISC-V: llvm build broken + - JDK-8317262: LockStack::contains(oop) fails "assert(t->is_Java_thread()) failed: incorrect cast to JavaThread" + - JDK-8317294: Classloading throws exceptions over already pending exceptions + - JDK-8317327: Remove JT_JAVA dead code in jib-profiles.js + - JDK-8317331: Solaris build failed with "declaration can not follow a statement (E_DECLARATION_IN_CODE)" + - JDK-8317335: Build on windows fails after 8316645 + - JDK-8317336: Assertion error thrown during 'this' escape analysis + - JDK-8317340: Windows builds are not reproducible if MS VS compiler install path differs + - JDK-8317373: Add Telia Root CA v2 + - JDK-8317374: Add Let's Encrypt ISRG Root X2 + - JDK-8317439: Updating RE Configs for BUILD REQUEST 21.0.2+1 + - JDK-8317507: C2 compilation fails with "Exceeded _node_regs array" + - JDK-8317510: Change Windows debug symbol files naming to avoid losing info when an executable and a library share the same name + - JDK-8317581: [s390x] Multiple test failure with LockingMode=2 + - JDK-8317601: Windows build on WSL broken after JDK-8317340 + - JDK-8317603: Improve exception messages thrown by sun.nio.ch.Net native methods (win) + - JDK-8317692: jcmd GC.heap_dump performance regression after JDK-8292818 + - JDK-8317705: ProblemList sun/tools/jstat/jstatLineCountsX.sh on linux-ppc64le and aix due to JDK-8248691 + - JDK-8317706: Exclude java/awt/Graphics2D/DrawString/RotTransText.java on linux + - JDK-8317711: Exclude gtest/GTestWrapper.java on AIX + - JDK-8317736: Stream::handleReset locks twice + - JDK-8317751: ProblemList ConsumeForModalDialogTest.java, MenuItemActivatedTest.java & MouseModifiersUnitTest_Standard.java for windows + - JDK-8317772: NMT: Make peak values available in release builds + - JDK-8317790: Fix Bug entry for exclusion of runtime/jni/terminatedThread/TestTerminatedThread.java on AIX + - JDK-8317803: Exclude java/net/Socket/asyncClose/Race.java on AIX + - JDK-8317807: JAVA_FLAGS removed from jtreg running in JDK-8317039 + - JDK-8317818: Combinatorial explosion during 'this' escape analysis + - JDK-8317834: java/lang/Thread/IsAlive.java timed out + - JDK-8317839: Exclude java/nio/channels/Channels/SocketChannelStreams.java on AIX + - JDK-8317920: JDWP-agent sends broken exception event with onthrow option + - JDK-8317959: Check return values of malloc in native java.base coding + - JDK-8317964: java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java fails on macosx-all after JDK-8317751 + - JDK-8317967: Enhance test/jdk/javax/net/ssl/TLSCommon/SSLEngineTestCase.java to handle default cases + - JDK-8317987: C2 recompilations cause high memory footprint + - JDK-8318078: ADLC: pass ASSERT and PRODUCT flags + - JDK-8318089: Class space not marked as such with NMT when CDS is off + - JDK-8318137: Change milestone to fcs for all releases + - JDK-8318144: Match on enum constants with body compiles but fails with MatchException + - JDK-8318183: C2: VM may crash after hitting node limit + - JDK-8318240: [AIX] Cleaners.java test failure + - JDK-8318415: Adjust describing comment of os_getChildren after 8315026 + - JDK-8318474: Fix memory reporter for thread_count + - JDK-8318525: Atomic gtest should run as TEST_VM to access VM capabilities + - JDK-8318528: Rename TestUnstructuredLocking test + - JDK-8318540: make test cannot run .jasm tests directly + - JDK-8318562: Computational test more than 2x slower when AVX instructions are used + - JDK-8318587: refresh libraries cache on AIX in print_vm_info + - JDK-8318591: avoid leaks in loadlib_aix.cpp reload_table() + - JDK-8318669: Target OS detection in 'test-prebuilt' makefile target is incorrect when running on MSYS2 + - JDK-8318705: [macos] ProblemList java/rmi/registry/multipleRegistries/MultipleRegistries.java + - JDK-8318736: com/sun/jdi/JdwpOnThrowTest.java failed with "transport error 202: bind failed: Address already in use" + - JDK-8318759: Add four DigiCert root certificates + - JDK-8318889: C2: add bailout after assert Bad graph detected in build_loop_late + - JDK-8318895: Deoptimization results in incorrect lightweight locking stack + - JDK-8318951: Additional negative value check in JPEG decoding + - JDK-8318953: RISC-V: Small refactoring for MacroAssembler::test_bit + - JDK-8318955: Add ReleaseIntArrayElements in Java_sun_awt_X11_XlibWrapper_SetBitmapShape XlbWrapper.c to early return + - JDK-8318957: enhance agentlib:jdwp help output by info about allow option + - JDK-8318961: increase javacserver connection timeout values and max retry attempts + - JDK-8318981: compiler/compilercontrol/TestConflictInlineCommands.java fails intermittent with 'disallowed by CompileCommand' missing from stdout/stderr + - JDK-8319104: GtestWrapper crashes with SIGILL in AsyncLogTest::test_asynclog_raw on AIX opt + - JDK-8319120: Unbound ScopedValue.get() throws the wrong exception + - JDK-8319184: RISC-V: improve MD5 intrinsic + - JDK-8319187: Add three eMudhra emSign roots + - JDK-8319195: Move most tier 1 vector API regression tests to tier 3 + - JDK-8319268: Build failure with GCC8.3.1 after 8313643 + - JDK-8319339: Internal error on spurious markup in a hybrid snippet + - JDK-8319436: Proxy.newProxyInstance throws NPE if loader is null and interface not visible from class loader + - JDK-8319525: RISC-V: Rename *_riscv64.ad files to *_riscv.ad under riscv/gc + - JDK-8319532: jshell - Non-sealed declarations sometimes break a snippet evaluation + - JDK-8319542: Fix boundaries of region to be tested with os::is_readable_range + - JDK-8319700: [AArch64] C2 compilation fails with "Field too big for insn" + - JDK-8319828: runtime/NMT/VirtualAllocCommitMerge.java may fail if mixing interpreted and compiled native invocations + - JDK-8319922: libCreationTimeHelper.so fails to link in JDK 21 + - JDK-8319958: test/jdk/java/io/File/libGetXSpace.c does not compile on Windows 32-bit + - JDK-8319961: JvmtiEnvBase doesn't zero _ext_event_callbacks + - JDK-8320001: javac crashes while adding type annotations to the return type of a constructor + - JDK-8320053: GHA: Cross-compile gtest code + - JDK-8320209: VectorMaskGen clobbers rflags on x86_64 + - JDK-8320280: RISC-V: Avoid passing t0 as temp register to MacroAssembler::lightweight_lock/unlock + - JDK-8320363: ppc64 TypeEntries::type_unknown logic looks wrong, missed optimization opportunity + - JDK-8320597: RSA signature verification fails on signed data that does not encode params correctly + - JDK-8320601: ProblemList java/lang/invoke/lambda/LambdaFileEncodingSerialization.java on linux-all + - JDK-8321067: Unlock experimental options in EATests.java + - JDK-8322883: [BACKOUT] 8225377: type annotations are not visible to javac plugins across compilation boundaries + - JDK-8322985: [BACKOUT] 8318562: Computational test more than 2x slower when AVX instructions are used + +Notes on individual issues: +=========================== + +core-libs/java.net: + +JDK-8308593: Add KEEPALIVE Extended Socket Options Support for Windows +====================================================================== +On Windows 10 version 1709 and above, TCP_KEEPIDLE and +TCP_KEEPINTERVAL are now supported in the +java.net.ExtendedSocketOptions class. Similarly, on Windows 10 +version 1703 and above, TCP_KEEPCOUNT is now supported. + +hotspot/compiler: + +JDK-8315082: [REDO] Generational ZGC: Tests crash with assert(index == 0 || is_power_of_2(index)) +================================================================================================= +In the initial release of JDK 21, running the JVM with -XX:+UseZGC and +a non-default value of -XX:ObjectAlignmentInBytes could lead to JVM +crashes or incorrect execution. This issue should now be resolved and +it should be possible to use these options again. + +hotspot/runtime: + +JDK-8317772: NMT: Make peak values available in release builds +============================================================== +The peak value is the highest value for committed memory in a given +Native Memory Tracking (NMT) category over the lifetime of the JVM +process. NMT reports will now show the peak value for all categories. + +If the committed memory for a category is at its peak, NMT will +print "at peak". Otherwise, it prints the peak value. + +For example, "Compiler (arena=196KB #4) (peak=6126KB #16)" shows that +compiler arena memory peaked above 6 MB, but now hovers around 200KB. + +JDK-8313782: Add user-facing warning if THPs are enabled but cannot be used +=========================================================================== +On Linux, the JVM will now print the following message to standard +output if Transparent Huge Pages (THPs) are requested, but are not +supported on the operating system: + +"UseTransparentHugePages disabled; transparent huge pages are not +supported by the operating system." + +security-libs/java.security: + +JDK-8317374: Added ISRG Root X2 CA Certificate from Let's Encrypt +================================================================= +The following root certificate has been added to the cacerts +truststore: + +Name: Let's Encrypt +Alias Name: letsencryptisrgx2 +Distinguished Name: CN=ISRG Root X2, O=Internet Security Research Group, C=US + +JDK-8318759: Added Four Root Certificates from DigiCert, Inc. +============================================================= +The following root certificates have been added to the cacerts +truststore: + +Name: DigiCert, Inc. +Alias Name: digicertcseccrootg5 +Distinguished Name: CN=DigiCert CS ECC P384 Root G5, O="DigiCert, Inc.", C=US + +Name: DigiCert, Inc. +Alias Name: digicertcsrsarootg5 +Distinguished Name: CN=DigiCert CS RSA4096 Root G5, O="DigiCert, Inc.", C=US + +Name: DigiCert, Inc. +Alias Name: digicerttlseccrootg5 +Distinguished Name: CN=DigiCert TLS ECC P384 Root G5, O="DigiCert, Inc.", C=US + +Name: DigiCert, Inc. +Alias Name: digicerttlsrsarootg5 +Distinguished Name: CN=DigiCert TLS RSA4096 Root G5, O="DigiCert, Inc.", C=US + +JDK-8319187: Added Three Root Certificates from eMudhra Technologies Limited +============================================================================ +The following root certificates have been added to the cacerts +truststore: + +Name: eMudhra Technologies Limited +Alias Name: emsignrootcag1 +Distinguished Name: CN=emSign Root CA - G1, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + +Name: eMudhra Technologies Limited +Alias Name: emsigneccrootcag3 +Distinguished Name: CN=emSign ECC Root CA - G3, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + +Name: eMudhra Technologies Limited +Alias Name: emsignrootcag2 +Distinguished Name: CN=emSign Root CA - G2, O=eMudhra Technologies Limited, OU=emSign PKI, C=IN + +JDK-8317373: Added Telia Root CA v2 Certificate +=============================================== +The following root certificate has been added to the cacerts +truststore: + +Name: Telia Root CA v2 +Alias Name: teliarootcav2 +Distinguished Name: CN=Telia Root CA v2, O=Telia Finland Oyj, C=FI ``` + New in release OpenJDK 21.0.1 (2023-10-17): =========================================== diff --git a/README.md b/README.md index 4dadffe..b4a565b 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ OpenJDK 21 is the latest Long-Term Support (LTS) release of the Java platform. For a list of major changes from OpenJDK 17 (java-17-openjdk), see the upstream release page for OpenJDK 21 and the preceding interim releases: -* 12: https://openjdk.java.net/projects/jdk/18/ -* 13: https://openjdk.java.net/projects/jdk/19/ -* 14: https://openjdk.java.net/projects/jdk/20/ -* 15: https://openjdk.java.net/projects/jdk/21/ +* 18: https://openjdk.java.net/projects/jdk/18/ +* 19: https://openjdk.java.net/projects/jdk/19/ +* 20: https://openjdk.java.net/projects/jdk/20/ +* 21: https://openjdk.java.net/projects/jdk/21/ diff --git a/generate_source_tarball.sh b/generate_source_tarball.sh index 5d6efd9..ed24d3e 100755 --- a/generate_source_tarball.sh +++ b/generate_source_tarball.sh @@ -31,9 +31,6 @@ OPENJDK_URL_DEFAULT=https://github.com COMPRESSION_DEFAULT=xz if [ "x$1" = "xhelp" ] ; then - if [ "x$VERSION" = "x" ] ; then - VERSION=""; - fi echo -e "Behaviour may be specified by setting the following variables:\n" echo "VERSION - the version of the specified OpenJDK project" echo "PROJECT_NAME -- the name of the OpenJDK project being archived (optional; only needed by defaults)" diff --git a/java-21-openjdk-portable.spec b/java-21-openjdk-portable.spec index 41a3acc..bfa9505 100644 --- a/java-21-openjdk-portable.spec +++ b/java-21-openjdk-portable.spec @@ -1,8 +1,3 @@ -%if (0%{?rhel} > 0 && 0%{?rhel} < 8) -# portable jdk 17 specific bug, _jvmdir being missing -%define _jvmdir /usr/lib/jvm -%endif - # debug_package %%{nil} is portable-jdks specific %define debug_package %{nil} @@ -328,7 +323,7 @@ # New Version-String scheme-style defines %global featurever 21 %global interimver 0 -%global updatever 1 +%global updatever 2 %global patchver 0 # buildjdkver is usually same as %%{featurever}, # but in time of bootstrap of next jdk, it is featurever-1, @@ -392,8 +387,8 @@ %global origin_nice OpenJDK %global top_level_dir_name %{vcstag} %global top_level_dir_name_backup %{top_level_dir_name}-backup -%global buildver 12 -%global rpmrelease 5 +%global buildver 13 +%global rpmrelease 1 #%%global tagsuffix %%{nil} # Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit %if %is_system_jdk @@ -470,7 +465,6 @@ %define jdkportablearchiveForFiles() %(echo %{jdkportablearchive -- ""}) %define jdkportablesourcesarchiveForFiles() %(echo %{jdkportablesourcesarchive -- ""}) %define staticlibsportablearchiveForFiles() %(echo %{staticlibsportablearchive -- ""}) -%define jdkportablesourcesnameForFiles() %(echo %{jdkportablesourcesname -- ""}) ################################################################# # fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349 @@ -554,9 +548,9 @@ ExcludeArch: %{ix86} # portables have grown out of its component, moving back to java-x-vendor # this expression, when declared as global, filled component with java-x-vendor portable -%define component %(echo %{name} | sed "s;-portable;;g") +%define component %(echo %{name} | sed "s;-portable%{?pkgos:-%{pkgos}};;g") -Name: java-%{javaver}-%{origin}-portable +Name: java-%{javaver}-%{origin}-portable%{?pkgos:-%{pkgos}} Version: %{newjavaver}.%{buildver} Release: %{?eaprefix}%{rpmrelease}%{?extraver}%{?dist} # java-1.5.0-ibm from jpackage.org set Epoch to 1 for unknown reasons @@ -692,9 +686,6 @@ Patch6: jdk8009550-rh910107-fail_to_load_pcsc_library.patch # ############################################# -# JDK-8311630: [s390] Implementation of Foreign Function & Memory API (Preview) -Patch100: jdk8311630-s390_ffmapi.patch - ############################################# # # Portable build specific patches @@ -747,9 +738,10 @@ BuildRequires: zip BuildRequires: tar BuildRequires: unzip %if (0%{?rhel} > 0 && 0%{?rhel} < 8) -# No javapackages-filesystem on el7,nor is needed for portables +BuildRequires: javapackages-tools +BuildRequires: java-%{buildjdkver}-%{origin}%{?pkgos:-%{pkgos}}-devel %else -# BuildRequires: javapackages-filesystem +BuildRequires: javapackages-filesystem BuildRequires: java-latest-openjdk-devel %endif # Zero-assembler build requirement @@ -784,13 +776,13 @@ Provides: bundled(freetype) = 2.13.0 # Version in src/java.desktop/share/native/libsplashscreen/giflib/gif_lib.h Provides: bundled(giflib) = 5.2.1 # Version in src/java.desktop/share/native/libharfbuzz/hb-version.h -Provides: bundled(harfbuzz) = 7.2.0 +Provides: bundled(harfbuzz) = 8.2.2 # Version in src/java.desktop/share/native/liblcms/lcms2.h Provides: bundled(lcms2) = 2.15.0 # Version in src/java.desktop/share/native/libjavajpeg/jpeglib.h Provides: bundled(libjpeg) = 6b # Version in src/java.desktop/share/native/libsplashscreen/libpng/png.h -Provides: bundled(libpng) = 1.6.39 +Provides: bundled(libpng) = 1.6.40 # We link statically against libstdc++ to increase portability BuildRequires: libstdc++-static %endif @@ -1000,8 +992,6 @@ pushd %{top_level_dir_name} %patch1001 -p1 # Patches in need of upstreaming %patch6 -p1 -# Patches in next release -%patch100 -p1 popd # openjdk @@ -1151,7 +1141,7 @@ function buildjdk() { cat spec.gmk %if (0%{?rhel} > 0 && 0%{?rhel} < 8) - scl enable devtoolset-%{dtsversion} -- make \ + scl enable devtoolset-%{dtsversion} -- make \ %else make \ %endif @@ -1780,8 +1770,11 @@ done %endif %changelog -* Wed Jan 10 2024 Jiri Vanek - 1:21.0.1.0.12-5 -* forked to java-21-openjdk-portable +* Tue Jan 09 2024 Andrew Hughes - 1:21.0.2.0.13-1 +- Update to jdk-21.0.2+13 (GA) +- Update release notes to 21.0.2+13 +- Drop no longer needed local patch to fix versioning +- ** This tarball is embargoed until 2024-01-16 @ 1pm PT. ** * Wed Dec 13 2023 Jiri Vanek - 1:21.0.1.0.12-3.rolling - packing generated sources diff --git a/jdk8311630-s390_ffmapi.patch b/jdk8311630-s390_ffmapi.patch deleted file mode 100644 index cd3bc08..0000000 --- a/jdk8311630-s390_ffmapi.patch +++ /dev/null @@ -1,1906 +0,0 @@ -commit 27f635fabe7c2933674ad40443906fc35eecf785 -Author: Sidraya Jayagond -Date: Tue Sep 12 09:07:09 2023 +0000 - - 8311630: [s390] Implementation of Foreign Function & Memory API (Preview) - - Backport-of: ec1f7a8480db025a6f405817a106af8e92b69c44 - -diff --git a/src/hotspot/cpu/s390/downcallLinker_s390.cpp b/src/hotspot/cpu/s390/downcallLinker_s390.cpp -index baee7d7a043..f831da90755 100644 ---- a/src/hotspot/cpu/s390/downcallLinker_s390.cpp -+++ b/src/hotspot/cpu/s390/downcallLinker_s390.cpp -@@ -23,8 +23,76 @@ - */ - - #include "precompiled.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "code/codeBlob.hpp" -+#include "code/codeCache.hpp" -+#include "code/vmreg.inline.hpp" -+#include "compiler/oopMap.hpp" -+#include "logging/logStream.hpp" -+#include "memory/resourceArea.hpp" - #include "prims/downcallLinker.hpp" --#include "utilities/debug.hpp" -+#include "runtime/globals.hpp" -+#include "runtime/stubCodeGenerator.hpp" -+ -+#define __ _masm-> -+ -+class DowncallStubGenerator : public StubCodeGenerator { -+ BasicType* _signature; -+ int _num_args; -+ BasicType _ret_bt; -+ const ABIDescriptor& _abi; -+ -+ const GrowableArray& _input_registers; -+ const GrowableArray& _output_registers; -+ -+ bool _needs_return_buffer; -+ int _captured_state_mask; -+ bool _needs_transition; -+ -+ int _frame_complete; -+ int _frame_size_slots; -+ OopMapSet* _oop_maps; -+ public: -+ DowncallStubGenerator(CodeBuffer* buffer, -+ BasicType* signature, -+ int num_args, -+ BasicType ret_bt, -+ const ABIDescriptor& abi, -+ const GrowableArray& input_registers, -+ const GrowableArray& output_registers, -+ bool needs_return_buffer, -+ int captured_state_mask, -+ bool needs_transition) -+ :StubCodeGenerator(buffer, PrintMethodHandleStubs), -+ _signature(signature), -+ _num_args(num_args), -+ _ret_bt(ret_bt), -+ _abi(abi), -+ _input_registers(input_registers), -+ _output_registers(output_registers), -+ _needs_return_buffer(needs_return_buffer), -+ _captured_state_mask(captured_state_mask), -+ _needs_transition(needs_transition), -+ _frame_complete(0), -+ _frame_size_slots(0), -+ _oop_maps(nullptr) { -+ } -+ void generate(); -+ int frame_complete() const { -+ return _frame_complete; -+ } -+ -+ int framesize() const { -+ return (_frame_size_slots >> (LogBytesPerWord - LogBytesPerInt)); -+ } -+ -+ OopMapSet* oop_maps() const { -+ return _oop_maps; -+ } -+}; -+ -+static const int native_invoker_code_base_size = 512; -+static const int native_invoker_size_per_args = 8; - - RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, - int num_args, -@@ -35,6 +103,197 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature, - bool needs_return_buffer, - int captured_state_mask, - bool needs_transition) { -- Unimplemented(); -- return nullptr; -+ -+ int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_args); -+ int locs_size = 1; //must be non zero -+ CodeBuffer code("nep_invoker_blob", code_size, locs_size); -+ -+ DowncallStubGenerator g(&code, signature, num_args, ret_bt, abi, -+ input_registers, output_registers, -+ needs_return_buffer, captured_state_mask, -+ needs_transition); -+ g.generate(); -+ code.log_section_sizes("nep_invoker_blob"); -+ -+ RuntimeStub* stub = -+ RuntimeStub::new_runtime_stub("nep_invoker_blob", -+ &code, -+ g.frame_complete(), -+ g.framesize(), -+ g.oop_maps(), false); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, downcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ stub->print_on(&ls); -+ } -+#endif -+ -+ return stub; -+} -+ -+void DowncallStubGenerator::generate() { -+ Register call_target_address = Z_R1_scratch, -+ tmp = Z_R0_scratch; -+ -+ VMStorage shuffle_reg = _abi._scratch1; -+ -+ JavaCallingConvention in_conv; -+ NativeCallingConvention out_conv(_input_registers); -+ ArgumentShuffle arg_shuffle(_signature, _num_args, _signature, _num_args, &in_conv, &out_conv, shuffle_reg); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, downcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ arg_shuffle.print_on(&ls); -+ } -+#endif -+ -+ assert(_abi._shadow_space_bytes == frame::z_abi_160_size, "expected space according to ABI"); -+ int allocated_frame_size = _abi._shadow_space_bytes; -+ allocated_frame_size += arg_shuffle.out_arg_bytes(); -+ -+ assert(!_needs_return_buffer, "unexpected needs_return_buffer"); -+ RegSpiller out_reg_spiller(_output_registers); -+ int spill_offset = allocated_frame_size; -+ allocated_frame_size += BytesPerWord; -+ -+ StubLocations locs; -+ locs.set(StubLocations::TARGET_ADDRESS, _abi._scratch2); -+ -+ if (_captured_state_mask != 0) { -+ __ block_comment("{ _captured_state_mask is set"); -+ locs.set_frame_data(StubLocations::CAPTURED_STATE_BUFFER, allocated_frame_size); -+ allocated_frame_size += BytesPerWord; -+ __ block_comment("} _captured_state_mask is set"); -+ } -+ -+ allocated_frame_size = align_up(allocated_frame_size, StackAlignmentInBytes); -+ _frame_size_slots = allocated_frame_size >> LogBytesPerInt; -+ -+ _oop_maps = _needs_transition ? new OopMapSet() : nullptr; -+ address start = __ pc(); -+ -+ __ save_return_pc(); -+ __ push_frame(allocated_frame_size, Z_R11); // Create a new frame for the wrapper. -+ -+ _frame_complete = __ pc() - start; // frame build complete. -+ -+ if (_needs_transition) { -+ __ block_comment("{ thread java2native"); -+ __ get_PC(Z_R1_scratch); -+ address the_pc = __ pc(); -+ __ set_last_Java_frame(Z_SP, Z_R1_scratch); -+ -+ OopMap* map = new OopMap(_frame_size_slots, 0); -+ _oop_maps->add_gc_map(the_pc - start, map); -+ -+ // State transition -+ __ set_thread_state(_thread_in_native); -+ __ block_comment("} thread java2native"); -+ } -+ __ block_comment("{ argument shuffle"); -+ arg_shuffle.generate(_masm, shuffle_reg, frame::z_jit_out_preserve_size, _abi._shadow_space_bytes, locs); -+ __ block_comment("} argument shuffle"); -+ -+ __ call(as_Register(locs.get(StubLocations::TARGET_ADDRESS))); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ if (_captured_state_mask != 0) { -+ __ block_comment("{ save thread local"); -+ -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, DowncallLinker::capture_state)); -+ __ z_lg(Z_ARG1, Address(Z_SP, locs.data_offset(StubLocations::CAPTURED_STATE_BUFFER))); -+ __ load_const_optimized(Z_ARG2, _captured_state_mask); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ block_comment("} save thread local"); -+ } -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ Label L_after_safepoint_poll; -+ Label L_safepoint_poll_slow_path; -+ Label L_reguard; -+ Label L_after_reguard; -+ -+ if (_needs_transition) { -+ __ block_comment("{ thread native2java"); -+ __ set_thread_state(_thread_in_native_trans); -+ -+ if (!UseSystemMemoryBarrier) { -+ __ z_fence(); // Order state change wrt. safepoint poll. -+ } -+ -+ __ safepoint_poll(L_safepoint_poll_slow_path, tmp); -+ -+ __ load_and_test_int(tmp, Address(Z_thread, JavaThread::suspend_flags_offset())); -+ __ z_brne(L_safepoint_poll_slow_path); -+ -+ __ bind(L_after_safepoint_poll); -+ -+ // change thread state -+ __ set_thread_state(_thread_in_Java); -+ -+ __ block_comment("reguard stack check"); -+ __ z_cli(Address(Z_thread, JavaThread::stack_guard_state_offset() + in_ByteSize(sizeof(StackOverflow::StackGuardState) - 1)), -+ StackOverflow::stack_guard_yellow_reserved_disabled); -+ __ z_bre(L_reguard); -+ __ bind(L_after_reguard); -+ -+ __ reset_last_Java_frame(); -+ __ block_comment("} thread native2java"); -+ } -+ -+ __ pop_frame(); -+ __ restore_return_pc(); // This is the way back to the caller. -+ __ z_br(Z_R14); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ if (_needs_transition) { -+ __ block_comment("{ L_safepoint_poll_slow_path"); -+ __ bind(L_safepoint_poll_slow_path); -+ -+ // Need to save the native result registers around any runtime calls. -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, JavaThread::check_special_condition_for_native_trans)); -+ __ z_lgr(Z_ARG1, Z_thread); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ z_bru(L_after_safepoint_poll); -+ __ block_comment("} L_safepoint_poll_slow_path"); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ __ block_comment("{ L_reguard"); -+ __ bind(L_reguard); -+ -+ // Need to save the native result registers around any runtime calls. -+ out_reg_spiller.generate_spill(_masm, spill_offset); -+ -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, SharedRuntime::reguard_yellow_pages)); -+ __ call(call_target_address); -+ -+ out_reg_spiller.generate_fill(_masm, spill_offset); -+ -+ __ z_bru(L_after_reguard); -+ -+ __ block_comment("} L_reguard"); -+ } -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ __ flush(); - } -diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -index d3a318536bd..9796ab4ffe4 100644 ---- a/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -+++ b/src/hotspot/cpu/s390/foreignGlobals_s390.cpp -@@ -23,34 +23,209 @@ - */ - - #include "precompiled.hpp" --#include "code/vmreg.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "code/vmreg.inline.hpp" -+#include "runtime/jniHandles.hpp" -+#include "runtime/jniHandles.inline.hpp" -+#include "oops/typeArrayOop.inline.hpp" -+#include "oops/oopCast.inline.hpp" - #include "prims/foreignGlobals.hpp" --#include "utilities/debug.hpp" -+#include "prims/foreignGlobals.inline.hpp" -+#include "prims/vmstorage.hpp" -+#include "utilities/formatBuffer.hpp" - --class MacroAssembler; -+#define __ masm-> -+ -+bool ABIDescriptor::is_volatile_reg(Register reg) const { -+ return _integer_volatile_registers.contains(reg); -+} -+ -+bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const { -+ return _float_argument_registers.contains(reg) -+ || _float_additional_volatile_registers.contains(reg); -+} - - bool ForeignGlobals::is_foreign_linker_supported() { -- return false; -+ return true; - } - - const ABIDescriptor ForeignGlobals::parse_abi_descriptor(jobject jabi) { -- Unimplemented(); -- return {}; -+ oop abi_oop = JNIHandles::resolve_non_null(jabi); -+ ABIDescriptor abi; -+ -+ objArrayOop inputStorage = jdk_internal_foreign_abi_ABIDescriptor::inputStorage(abi_oop); -+ parse_register_array(inputStorage, StorageType::INTEGER, abi._integer_argument_registers, as_Register); -+ parse_register_array(inputStorage, StorageType::FLOAT, abi._float_argument_registers, as_FloatRegister); -+ -+ objArrayOop outputStorage = jdk_internal_foreign_abi_ABIDescriptor::outputStorage(abi_oop); -+ parse_register_array(outputStorage, StorageType::INTEGER, abi._integer_return_registers, as_Register); -+ parse_register_array(outputStorage, StorageType::FLOAT, abi._float_return_registers, as_FloatRegister); -+ -+ objArrayOop volatileStorage = jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(abi_oop); -+ parse_register_array(volatileStorage, StorageType::INTEGER, abi._integer_volatile_registers, as_Register); -+ parse_register_array(volatileStorage, StorageType::FLOAT, abi._float_additional_volatile_registers, as_FloatRegister); -+ -+ abi._stack_alignment_bytes = jdk_internal_foreign_abi_ABIDescriptor::stackAlignment(abi_oop); -+ abi._shadow_space_bytes = jdk_internal_foreign_abi_ABIDescriptor::shadowSpace(abi_oop); -+ -+ abi._scratch1 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch1(abi_oop)); -+ abi._scratch2 = parse_vmstorage(jdk_internal_foreign_abi_ABIDescriptor::scratch2(abi_oop)); -+ -+ return abi; - } - - int RegSpiller::pd_reg_size(VMStorage reg) { -- Unimplemented(); -- return -1; -+ if (reg.type() == StorageType::INTEGER || reg.type() == StorageType::FLOAT) { -+ return 8; -+ } -+ return 0; // stack and BAD - } - - void RegSpiller::pd_store_reg(MacroAssembler* masm, int offset, VMStorage reg) { -- Unimplemented(); -+ if (reg.type() == StorageType::INTEGER) { -+ __ reg2mem_opt(as_Register(reg), Address(Z_SP, offset), true); -+ } else if (reg.type() == StorageType::FLOAT) { -+ __ freg2mem_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); -+ } else { -+ // stack and BAD -+ } - } - - void RegSpiller::pd_load_reg(MacroAssembler* masm, int offset, VMStorage reg) { -- Unimplemented(); -+ if (reg.type() == StorageType::INTEGER) { -+ __ mem2reg_opt(as_Register(reg), Address(Z_SP, offset), true); -+ } else if (reg.type() == StorageType::FLOAT) { -+ __ mem2freg_opt(as_FloatRegister(reg), Address(Z_SP, offset), true); -+ } else { -+ // stack and BAD -+ } -+} -+ -+static int reg2offset(VMStorage vms, int stk_bias) { -+ assert(!vms.is_reg(), "wrong usage"); -+ return vms.index_or_offset() + stk_bias; -+} -+ -+static void move_reg(MacroAssembler* masm, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ int out_bias = 0; -+ switch (to_reg.type()) { -+ case StorageType::INTEGER: -+ if (to_reg.segment_mask() == REG64_MASK && from_reg.segment_mask() == REG32_MASK ) { -+ // see CCallingConventionRequiresIntsAsLongs -+ __ z_lgfr(as_Register(to_reg), as_Register(from_reg)); -+ } else { -+ __ lgr_if_needed(as_Register(to_reg), as_Register(from_reg)); -+ } -+ break; -+ case StorageType::STACK: -+ out_bias = out_stk_bias; //fallthrough -+ case StorageType::FRAME_DATA: { -+ // Integer types always get a 64 bit slot in C. -+ if (from_reg.segment_mask() == REG32_MASK) { -+ // see CCallingConventionRequiresIntsAsLongs -+ __ z_lgfr(as_Register(from_reg), as_Register(from_reg)); -+ } -+ switch (to_reg.stack_size()) { -+ case 8: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), true); break; -+ case 4: __ reg2mem_opt(as_Register(from_reg), Address(Z_SP, reg2offset(to_reg, out_bias)), false); break; -+ default: ShouldNotReachHere(); -+ } -+ } break; -+ default: ShouldNotReachHere(); -+ } -+} -+ -+static void move_float(MacroAssembler* masm, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ switch (to_reg.type()) { -+ case StorageType::FLOAT: -+ if (from_reg.segment_mask() == REG64_MASK) -+ __ move_freg_if_needed(as_FloatRegister(to_reg), T_DOUBLE, as_FloatRegister(from_reg), T_DOUBLE); -+ else -+ __ move_freg_if_needed(as_FloatRegister(to_reg), T_FLOAT, as_FloatRegister(from_reg), T_FLOAT); -+ break; -+ case StorageType::STACK: -+ if (from_reg.segment_mask() == REG64_MASK) { -+ assert(to_reg.stack_size() == 8, "size should match"); -+ __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), true); -+ } else { -+ assert(to_reg.stack_size() == 4, "size should match"); -+ __ freg2mem_opt(as_FloatRegister(from_reg), Address(Z_SP, reg2offset(to_reg, out_stk_bias)), false); -+ } -+ break; -+ default: ShouldNotReachHere(); -+ } -+} -+ -+static void move_stack(MacroAssembler* masm, Register tmp_reg, int in_stk_bias, int out_stk_bias, -+ VMStorage from_reg, VMStorage to_reg) { -+ int out_bias = 0; -+ Address from_addr(Z_R11, reg2offset(from_reg, in_stk_bias)); -+ switch (to_reg.type()) { -+ case StorageType::INTEGER: -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2reg_opt(as_Register(to_reg), from_addr, true);break; -+ case 4: __ mem2reg_opt(as_Register(to_reg), from_addr, false);break; -+ default: ShouldNotReachHere(); -+ } -+ break; -+ case StorageType::FLOAT: -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, true);break; -+ case 4: __ mem2freg_opt(as_FloatRegister(to_reg), from_addr, false);break; -+ default: ShouldNotReachHere(); -+ } -+ break; -+ case StorageType::STACK: -+ out_bias = out_stk_bias; // fallthrough -+ case StorageType::FRAME_DATA: { -+ switch (from_reg.stack_size()) { -+ case 8: __ mem2reg_opt(tmp_reg, from_addr, true); break; -+ case 4: if (to_reg.stack_size() == 8) { -+ __ mem2reg_signed_opt(tmp_reg, from_addr); -+ } else { -+ __ mem2reg_opt(tmp_reg, from_addr, false); -+ } -+ break; -+ default: ShouldNotReachHere(); -+ } -+ switch (to_reg.stack_size()) { -+ case 8: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), true); break; -+ case 4: __ reg2mem_opt(tmp_reg, Address (Z_SP, reg2offset(to_reg, out_bias)), false); break; -+ default: ShouldNotReachHere(); -+ } -+ } break; -+ default: ShouldNotReachHere(); -+ } - } - - void ArgumentShuffle::pd_generate(MacroAssembler* masm, VMStorage tmp, int in_stk_bias, int out_stk_bias, const StubLocations& locs) const { -- Unimplemented(); -+ Register tmp_reg = as_Register(tmp); -+ for (int i = 0; i < _moves.length(); i++) { -+ Move move = _moves.at(i); -+ VMStorage from_reg = move.from; -+ VMStorage to_reg = move.to; -+ -+ // replace any placeholders -+ if (from_reg.type() == StorageType::PLACEHOLDER) { -+ from_reg = locs.get(from_reg); -+ } -+ if (to_reg.type() == StorageType::PLACEHOLDER) { -+ to_reg = locs.get(to_reg); -+ } -+ -+ switch (from_reg.type()) { -+ case StorageType::INTEGER: -+ move_reg(masm, out_stk_bias, from_reg, to_reg); -+ break; -+ case StorageType::FLOAT: -+ move_float(masm, out_stk_bias, from_reg, to_reg); -+ break; -+ case StorageType::STACK: -+ move_stack(masm, tmp_reg, in_stk_bias, out_stk_bias, from_reg, to_reg); -+ break; -+ default: ShouldNotReachHere(); -+ } -+ } - } -diff --git a/src/hotspot/cpu/s390/foreignGlobals_s390.hpp b/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -index 8b86a2b06a6..4ff3b3e40b4 100644 ---- a/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -+++ b/src/hotspot/cpu/s390/foreignGlobals_s390.hpp -@@ -24,6 +24,23 @@ - #ifndef CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP - #define CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP - --class ABIDescriptor {}; -+struct ABIDescriptor { -+ GrowableArray _integer_argument_registers; -+ GrowableArray _integer_return_registers; -+ GrowableArray _float_argument_registers; -+ GrowableArray _float_return_registers; -+ -+ GrowableArray _integer_volatile_registers; -+ GrowableArray _float_additional_volatile_registers; -+ -+ int32_t _stack_alignment_bytes; -+ int32_t _shadow_space_bytes; -+ -+ VMStorage _scratch1; -+ VMStorage _scratch2; -+ -+ bool is_volatile_reg(Register reg) const; -+ bool is_volatile_reg(FloatRegister reg) const; -+}; - - #endif // CPU_S390_VM_FOREIGN_GLOBALS_S390_HPP -diff --git a/src/hotspot/cpu/s390/frame_s390.cpp b/src/hotspot/cpu/s390/frame_s390.cpp -index 23547fa6617..ac24e43f00c 100644 ---- a/src/hotspot/cpu/s390/frame_s390.cpp -+++ b/src/hotspot/cpu/s390/frame_s390.cpp -@@ -218,13 +218,32 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const { - } - - UpcallStub::FrameData* UpcallStub::frame_data_for_frame(const frame& frame) const { -- ShouldNotCallThis(); -- return nullptr; -+ assert(frame.is_upcall_stub_frame(), "wrong frame"); -+ // need unextended_sp here, since normal sp is wrong for interpreter callees -+ return reinterpret_cast( -+ reinterpret_cast
(frame.unextended_sp()) + in_bytes(_frame_data_offset)); - } - - bool frame::upcall_stub_frame_is_first() const { -- ShouldNotCallThis(); -- return false; -+ assert(is_upcall_stub_frame(), "must be optimized entry frame"); -+ UpcallStub* blob = _cb->as_upcall_stub(); -+ JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); -+ return jfa->last_Java_sp() == nullptr; -+} -+ -+frame frame::sender_for_upcall_stub_frame(RegisterMap* map) const { -+ assert(map != nullptr, "map must be set"); -+ UpcallStub* blob = _cb->as_upcall_stub(); -+ // Java frame called from C; skip all C frames and return top C -+ // frame of that chunk as the sender -+ JavaFrameAnchor* jfa = blob->jfa_for_frame(*this); -+ assert(!upcall_stub_frame_is_first(), "must have a frame anchor to go back to"); -+ assert(jfa->last_Java_sp() > sp(), "must be above this frame on stack"); -+ map->clear(); -+ assert(map->include_argument_oops(), "should be set by clear"); -+ frame fr(jfa->last_Java_sp(), jfa->last_Java_pc()); -+ -+ return fr; - } - - frame frame::sender_for_interpreter_frame(RegisterMap *map) const { -diff --git a/src/hotspot/cpu/s390/frame_s390.inline.hpp b/src/hotspot/cpu/s390/frame_s390.inline.hpp -index dfa68940bac..c188618653d 100644 ---- a/src/hotspot/cpu/s390/frame_s390.inline.hpp -+++ b/src/hotspot/cpu/s390/frame_s390.inline.hpp -@@ -352,12 +352,10 @@ inline frame frame::sender(RegisterMap* map) const { - // update it accordingly. - map->set_include_argument_oops(false); - -- if (is_entry_frame()) { -- return sender_for_entry_frame(map); -- } -- if (is_interpreted_frame()) { -- return sender_for_interpreter_frame(map); -- } -+ if (is_entry_frame()) return sender_for_entry_frame(map); -+ if (is_upcall_stub_frame()) return sender_for_upcall_stub_frame(map); -+ if (is_interpreted_frame()) return sender_for_interpreter_frame(map); -+ - assert(_cb == CodeCache::find_blob(pc()),"Must be the same"); - if (_cb != nullptr) return sender_for_compiled_frame(map); - -diff --git a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -index 99906bb369e..2232215a587 100644 ---- a/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -+++ b/src/hotspot/cpu/s390/globalDefinitions_s390.hpp -@@ -28,7 +28,7 @@ - - #define ShortenBranches true - --const int StackAlignmentInBytes = 16; -+const int StackAlignmentInBytes = 8; - - #define SUPPORTS_NATIVE_CX8 - -diff --git a/src/hotspot/cpu/s390/methodHandles_s390.cpp b/src/hotspot/cpu/s390/methodHandles_s390.cpp -index 6392ba45a6c..ef8722f2499 100644 ---- a/src/hotspot/cpu/s390/methodHandles_s390.cpp -+++ b/src/hotspot/cpu/s390/methodHandles_s390.cpp -@@ -349,7 +349,16 @@ address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* - - void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_reg, Register temp_target) { - BLOCK_COMMENT("jump_to_native_invoker {"); -- __ should_not_reach_here(); -+ assert(nep_reg != noreg, "required register"); -+ -+ // Load the invoker, as NEP -> .invoker -+ __ verify_oop(nep_reg); -+ -+ __ z_lg(temp_target, Address(nep_reg, -+ NONZERO(jdk_internal_foreign_abi_NativeEntryPoint::downcall_stub_address_offset_in_bytes()))); -+ -+ __ z_br(temp_target); -+ - BLOCK_COMMENT("} jump_to_native_invoker"); - } - -diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp -index 3e1fb04218b..b748ec547cc 100644 ---- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp -+++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp -@@ -22,15 +22,287 @@ - */ - - #include "precompiled.hpp" -+#include "asm/macroAssembler.inline.hpp" -+#include "logging/logStream.hpp" -+#include "memory/resourceArea.hpp" - #include "prims/upcallLinker.hpp" --#include "utilities/debug.hpp" -+#include "runtime/sharedRuntime.hpp" -+#include "runtime/signature.hpp" -+#include "runtime/stubRoutines.hpp" -+#include "utilities/formatBuffer.hpp" -+#include "utilities/globalDefinitions.hpp" - -+#define __ _masm-> -+ -+// for callee saved regs, according to the caller's ABI -+static int compute_reg_save_area_size(const ABIDescriptor& abi) { -+ int size = 0; -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ size += 8; // bytes -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ size += 8; // bytes -+ } -+ } -+ -+ return size; -+} -+ -+static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { -+ // 1. iterate all registers in the architecture -+ // - check if they are volatile or not for the given abi -+ // - if NOT, we need to save it here -+ -+ int offset = reg_save_area_offset; -+ -+ __ block_comment("{ preserve_callee_saved_regs "); -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_stg(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_std(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ __ block_comment("} preserve_callee_saved_regs "); -+} -+ -+static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) { -+ // 1. iterate all registers in the architecture -+ // - check if they are volatile or not for the given abi -+ // - if NOT, we need to restore it here -+ -+ int offset = reg_save_area_offset; -+ -+ __ block_comment("{ restore_callee_saved_regs "); -+ for (int i = 0; i < Register::number_of_registers; i++) { -+ Register reg = as_Register(i); -+ // Z_SP saved/restored by prologue/epilogue -+ if (reg == Z_SP) continue; -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_lg(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ for (int i = 0; i < FloatRegister::number_of_registers; i++) { -+ FloatRegister reg = as_FloatRegister(i); -+ if (!abi.is_volatile_reg(reg)) { -+ __ z_ld(reg, Address(Z_SP, offset)); -+ offset += 8; -+ } -+ } -+ -+ __ block_comment("} restore_callee_saved_regs "); -+} -+ -+static const int upcall_stub_code_base_size = 1024; // depends on GC (resolve_jobject) -+static const int upcall_stub_size_per_arg = 16; // arg save & restore + move - address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry, - BasicType* in_sig_bt, int total_in_args, - BasicType* out_sig_bt, int total_out_args, - BasicType ret_type, - jobject jabi, jobject jconv, - bool needs_return_buffer, int ret_buf_size) { -- ShouldNotCallThis(); -- return nullptr; -+ ResourceMark rm; -+ const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi); -+ const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv); -+ int code_size = upcall_stub_code_base_size + (total_in_args * upcall_stub_size_per_arg); -+ CodeBuffer buffer("upcall_stub", code_size, /* locs_size = */ 0); -+ -+ Register call_target_address = Z_R1_scratch; -+ -+ VMStorage shuffle_reg = abi._scratch1; -+ JavaCallingConvention out_conv; -+ NativeCallingConvention in_conv(call_regs._arg_regs); -+ ArgumentShuffle arg_shuffle(in_sig_bt, total_in_args, out_sig_bt, total_out_args, &in_conv, &out_conv, shuffle_reg); -+ -+ // The Java call uses the JIT ABI, but we also call C. -+ int out_arg_area = MAX2(frame::z_jit_out_preserve_size + arg_shuffle.out_arg_bytes(), (int)frame::z_abi_160_size); -+ -+#ifndef PRODUCT -+ LogTarget(Trace, foreign, upcall) lt; -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ arg_shuffle.print_on(&ls); -+ } -+#endif -+ -+ -+ int reg_save_area_size = compute_reg_save_area_size(abi); -+ RegSpiller arg_spiller(call_regs._arg_regs); -+ RegSpiller result_spiller(call_regs._ret_regs); -+ -+ int res_save_area_offset = out_arg_area; -+ int arg_save_area_offset = res_save_area_offset + result_spiller.spill_size_bytes(); -+ int reg_save_area_offset = arg_save_area_offset + arg_spiller.spill_size_bytes(); -+ int frame_data_offset = reg_save_area_offset + reg_save_area_size; -+ int frame_bottom_offset = frame_data_offset + sizeof(UpcallStub::FrameData); -+ -+ int frame_size = align_up(frame_bottom_offset, StackAlignmentInBytes); -+ StubLocations locs; -+ -+ // The space we have allocated will look like: -+ // -+ // -+ // FP-> | | -+ // |---------------------| = frame_bottom_offset = frame_size -+ // | | -+ // | FrameData | -+ // |---------------------| = frame_data_offset -+ // | | -+ // | reg_save_area | -+ // |---------------------| = reg_save_are_offset -+ // | | -+ // | arg_save_area | -+ // |---------------------| = arg_save_are_offset -+ // | | -+ // | res_save_area | -+ // |---------------------| = res_save_are_offset -+ // | | -+ // SP-> | out_arg_area | needs to be at end for shadow space -+ // -+ // -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ MacroAssembler* _masm = new MacroAssembler(&buffer); -+ address start = __ pc(); -+ -+ __ save_return_pc(); -+ assert((abi._stack_alignment_bytes % StackAlignmentInBytes) == 0, "must be 8 byte aligned"); -+ // allocate frame (frame_size is also aligned, so stack is still aligned) -+ __ push_frame(frame_size); -+ -+ // we have to always spill args since we need to do a call to get the thread -+ // (and maybe attach it). -+ arg_spiller.generate_spill(_masm, arg_save_area_offset); -+ // Java methods won't preserve them, so save them here: -+ preserve_callee_saved_registers(_masm, abi, reg_save_area_offset); -+ -+ __ block_comment("{ on_entry"); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry)); -+ __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); -+ __ call(call_target_address); -+ __ z_lgr(Z_thread, Z_RET); -+ __ block_comment("} on_entry"); -+ -+ arg_spiller.generate_fill(_masm, arg_save_area_offset); -+ __ block_comment("{ argument shuffle"); -+ arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size, locs); -+ __ block_comment("} argument shuffle"); -+ -+ __ block_comment("{ receiver "); -+ __ load_const_optimized(Z_ARG1, (intptr_t)receiver); -+ __ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2); -+ __ block_comment("} receiver "); -+ -+ __ load_const_optimized(Z_method, (intptr_t)entry); -+ __ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset()))); -+ -+ __ z_lg(call_target_address, Address(Z_method, in_bytes(Method::from_compiled_offset()))); -+ __ call(call_target_address); -+ -+ // return value shuffle -+ assert(!needs_return_buffer, "unexpected needs_return_buffer"); -+ // CallArranger can pick a return type that goes in the same reg for both CCs. -+ if (call_regs._ret_regs.length() > 0) { // 0 or 1 -+ VMStorage ret_reg = call_regs._ret_regs.at(0); -+ // Check if the return reg is as expected. -+ switch (ret_type) { -+ case T_BOOLEAN: -+ case T_BYTE: -+ case T_SHORT: -+ case T_CHAR: -+ case T_INT: -+ __ z_lgfr(Z_RET, Z_RET); // Clear garbage in high half. -+ // fallthrough -+ case T_LONG: -+ assert(as_Register(ret_reg) == Z_RET, "unexpected result register"); -+ break; -+ case T_FLOAT: -+ case T_DOUBLE: -+ assert(as_FloatRegister(ret_reg) == Z_FRET, "unexpected result register"); -+ break; -+ default: -+ fatal("unexpected return type: %s", type2name(ret_type)); -+ } -+ } -+ -+ result_spiller.generate_spill(_masm, res_save_area_offset); -+ -+ __ block_comment("{ on_exit"); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_exit)); -+ __ z_aghik(Z_ARG1, Z_SP, frame_data_offset); -+ __ call(call_target_address); -+ __ block_comment("} on_exit"); -+ -+ restore_callee_saved_registers(_masm, abi, reg_save_area_offset); -+ -+ result_spiller.generate_fill(_masm, res_save_area_offset); -+ -+ __ pop_frame(); -+ __ restore_return_pc(); -+ __ z_br(Z_R14); -+ -+ ////////////////////////////////////////////////////////////////////////////// -+ -+ __ block_comment("{ exception handler"); -+ -+ intptr_t exception_handler_offset = __ pc() - start; -+ -+ // Native caller has no idea how to handle exceptions, -+ // so we just crash here. Up to callee to catch exceptions. -+ __ verify_oop(Z_ARG1); -+ __ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception)); -+ __ call_c(call_target_address); -+ __ should_not_reach_here(); -+ -+ __ block_comment("} exception handler"); -+ -+ _masm->flush(); -+ -+#ifndef PRODUCT -+ stringStream ss; -+ ss.print("upcall_stub_%s", entry->signature()->as_C_string()); -+ const char* name = _masm->code_string(ss.as_string()); -+#else // PRODUCT -+ const char* name = "upcall_stub"; -+#endif // PRODUCT -+ -+ buffer.log_section_sizes(name); -+ UpcallStub* blob -+ = UpcallStub::create(name, -+ &buffer, -+ exception_handler_offset, -+ receiver, -+ in_ByteSize(frame_data_offset)); -+#ifndef PRODUCT -+ if (lt.is_enabled()) { -+ ResourceMark rm; -+ LogStream ls(lt); -+ blob->print_on(&ls); -+ } -+#endif -+ -+ return blob->code_begin(); - } -diff --git a/src/hotspot/cpu/s390/vmstorage_s390.hpp b/src/hotspot/cpu/s390/vmstorage_s390.hpp -index 192159adc4c..6a595670920 100644 ---- a/src/hotspot/cpu/s390/vmstorage_s390.hpp -+++ b/src/hotspot/cpu/s390/vmstorage_s390.hpp -@@ -29,24 +29,79 @@ - #include "asm/register.hpp" - - enum class StorageType : int8_t { -- STACK = 0, -- PLACEHOLDER = 1, --// special locations used only by native code -- FRAME_DATA = PLACEHOLDER + 1, -+ INTEGER = 0, -+ FLOAT = 1, -+ STACK = 2, -+ PLACEHOLDER = 3, -+ // special locations used only by native code -+ FRAME_DATA = 4, - INVALID = -1 - }; - - // need to define this before constructing VMStorage (below) - constexpr inline bool VMStorage::is_reg(StorageType type) { -- return false; -+ return type == StorageType::INTEGER || type == StorageType::FLOAT; - } - constexpr inline StorageType VMStorage::stack_type() { return StorageType::STACK; } - constexpr inline StorageType VMStorage::placeholder_type() { return StorageType::PLACEHOLDER; } - constexpr inline StorageType VMStorage::frame_data_type() { return StorageType::FRAME_DATA; } - -+// Needs to be consistent with S390Architecture.java. -+constexpr uint16_t REG32_MASK = 0b0000000000000001; -+constexpr uint16_t REG64_MASK = 0b0000000000000011; -+ -+inline Register as_Register(VMStorage vms) { -+ assert(vms.type() == StorageType::INTEGER, "not the right type"); -+ return ::as_Register(vms.index()); -+} -+ -+inline FloatRegister as_FloatRegister(VMStorage vms) { -+ assert(vms.type() == StorageType::FLOAT, "not the right type"); -+ return ::as_FloatRegister(vms.index()); -+} -+ -+inline VMStorage as_VMStorage(Register reg, uint16_t segment_mask = REG64_MASK) { -+ return VMStorage::reg_storage(StorageType::INTEGER, segment_mask, reg->encoding()); -+} -+ -+inline VMStorage as_VMStorage(FloatRegister reg, uint16_t segment_mask = REG64_MASK) { -+ return VMStorage::reg_storage(StorageType::FLOAT, segment_mask, reg->encoding()); -+} -+ - inline VMStorage as_VMStorage(VMReg reg, BasicType bt) { -+ if (reg->is_Register()) { -+ uint16_t segment_mask = 0; -+ switch (bt) { -+ case T_BOOLEAN: -+ case T_CHAR : -+ case T_BYTE : -+ case T_SHORT : -+ case T_INT : segment_mask = REG32_MASK; break; -+ default : segment_mask = REG64_MASK; break; -+ } -+ return as_VMStorage(reg->as_Register(), segment_mask); -+ } else if (reg->is_FloatRegister()) { -+ // FP regs always use double format. However, we need the correct format for loads /stores. -+ return as_VMStorage(reg->as_FloatRegister(), (bt == T_FLOAT) ? REG32_MASK : REG64_MASK); -+ } else if (reg->is_stack()) { -+ uint16_t size = 0; -+ switch (bt) { -+ case T_BOOLEAN: -+ case T_CHAR : -+ case T_BYTE : -+ case T_SHORT : -+ case T_INT : -+ case T_FLOAT : size = 4; break; -+ default : size = 8; break; -+ } -+ return VMStorage(StorageType::STACK, size, -+ checked_cast(reg->reg2stack() * VMRegImpl::stack_slot_size)); -+ } else if (!reg->is_valid()) { -+ return VMStorage::invalid(); -+ } -+ - ShouldNotReachHere(); - return VMStorage::invalid(); - } - --#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP -\ No newline at end of file -+#endif // CPU_S390_VMSTORAGE_S390_INLINE_HPP -diff --git a/src/java.base/share/classes/jdk/internal/foreign/CABI.java b/src/java.base/share/classes/jdk/internal/foreign/CABI.java -index eee4ae67457..d376a196333 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/CABI.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/CABI.java -@@ -41,6 +41,7 @@ public enum CABI { - WIN_AARCH_64, - LINUX_PPC_64_LE, - LINUX_RISCV_64, -+ LINUX_S390, - FALLBACK, - UNSUPPORTED; - -@@ -81,7 +82,11 @@ public enum CABI { - if (OperatingSystem.isLinux()) { - return LINUX_RISCV_64; - } -- } -+ } else if (arch.equals("s390x")) { -+ if (OperatingSystem.isLinux()) { -+ return LINUX_S390; -+ } -+ } - } else if (FallbackLinker.isSupported()) { - return FALLBACK; // fallback linker - } -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -index b5eb1029ff5..8a322cdcf7a 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java -@@ -32,6 +32,7 @@ import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker; - import jdk.internal.foreign.abi.fallback.FallbackLinker; - import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; - import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; -+import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; - import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; - import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; - import jdk.internal.foreign.layout.AbstractLayout; -@@ -60,7 +61,8 @@ import java.util.Set; - public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker, - SysVx64Linker, WindowsAArch64Linker, - Windowsx64Linker, LinuxPPC64leLinker, -- LinuxRISCV64Linker, FallbackLinker { -+ LinuxRISCV64Linker, LinuxS390Linker, -+ FallbackLinker { - - public interface UpcallStubFactory { - MemorySegment makeStub(MethodHandle target, Arena arena); -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -index 1e417245543..92d10a1dbdf 100644 ---- a/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java -@@ -35,6 +35,7 @@ import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker; - import jdk.internal.foreign.abi.fallback.FallbackLinker; - import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker; - import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker; -+import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker; - import jdk.internal.foreign.abi.x64.sysv.SysVx64Linker; - import jdk.internal.foreign.abi.x64.windows.Windowsx64Linker; - import jdk.internal.vm.annotation.ForceInline; -@@ -242,6 +243,7 @@ public final class SharedUtils { - case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance(); - case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance(); - case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance(); -+ case LINUX_S390 -> LinuxS390Linker.getInstance(); - case FALLBACK -> FallbackLinker.getInstance(); - case UNSUPPORTED -> throw new UnsupportedOperationException("Platform does not support native linker"); - }; -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java -new file mode 100644 -index 00000000000..bbafef2f3dc ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/S390Architecture.java -@@ -0,0 +1,151 @@ -+/* -+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+package jdk.internal.foreign.abi.s390; -+ -+import jdk.internal.foreign.abi.ABIDescriptor; -+import jdk.internal.foreign.abi.Architecture; -+import jdk.internal.foreign.abi.StubLocations; -+import jdk.internal.foreign.abi.VMStorage; -+ -+public final class S390Architecture implements Architecture { -+ public static final Architecture INSTANCE = new S390Architecture(); -+ -+ // Needs to be consistent with vmstorage_s390.hpp. -+ public static final short REG32_MASK = 0b0000_0000_0000_0001; -+ public static final short REG64_MASK = 0b0000_0000_0000_0011; -+ -+ private static final int INTEGER_REG_SIZE = 8; -+ private static final int FLOAT_REG_SIZE = 8; -+ private static final int STACK_SLOT_SIZE = 8; -+ -+ // Suppresses default constructor, ensuring non-instantiability. -+ private S390Architecture() { -+ } -+ -+ @Override -+ public boolean isStackType(int cls) { -+ return cls == StorageType.STACK; -+ } -+ -+ @Override -+ public int typeSize(int cls) { -+ switch (cls) { -+ case StorageType.INTEGER: -+ return INTEGER_REG_SIZE; -+ case StorageType.FLOAT: -+ return FLOAT_REG_SIZE; -+ // STACK is deliberately omitted -+ } -+ -+ throw new IllegalArgumentException("Invalid Storage Class: " + cls); -+ } -+ -+ public interface StorageType { -+ byte INTEGER = 0; -+ byte FLOAT = 1; -+ byte STACK = 2; -+ byte PLACEHOLDER = 3; -+ } -+ -+ public static class Regs { // break circular dependency -+ public static final VMStorage r0 = integerRegister(0); -+ public static final VMStorage r1 = integerRegister(1); -+ public static final VMStorage r2 = integerRegister(2); -+ public static final VMStorage r3 = integerRegister(3); -+ public static final VMStorage r4 = integerRegister(4); -+ public static final VMStorage r5 = integerRegister(5); -+ public static final VMStorage r6 = integerRegister(6); -+ public static final VMStorage r7 = integerRegister(7); -+ public static final VMStorage r8 = integerRegister(8); -+ public static final VMStorage r9 = integerRegister(9); -+ public static final VMStorage r10 = integerRegister(10); -+ public static final VMStorage r11 = integerRegister(11); -+ public static final VMStorage r12 = integerRegister(12); -+ public static final VMStorage r13 = integerRegister(13); -+ public static final VMStorage r14 = integerRegister(14); -+ public static final VMStorage r15 = integerRegister(15); -+ -+ public static final VMStorage f0 = floatRegister(0); -+ public static final VMStorage f1 = floatRegister(1); -+ public static final VMStorage f2 = floatRegister(2); -+ public static final VMStorage f3 = floatRegister(3); -+ public static final VMStorage f4 = floatRegister(4); -+ public static final VMStorage f5 = floatRegister(5); -+ public static final VMStorage f6 = floatRegister(6); -+ public static final VMStorage f7 = floatRegister(7); -+ public static final VMStorage f8 = floatRegister(8); -+ public static final VMStorage f9 = floatRegister(9); -+ public static final VMStorage f10 = floatRegister(10); -+ public static final VMStorage f11 = floatRegister(11); -+ public static final VMStorage f12 = floatRegister(12); -+ public static final VMStorage f13 = floatRegister(13); -+ public static final VMStorage f14 = floatRegister(14); -+ public static final VMStorage f15 = floatRegister(15); -+ } -+ -+ private static VMStorage integerRegister(int index) { -+ return new VMStorage(StorageType.INTEGER, REG64_MASK, index, "r" + index); -+ } -+ -+ private static VMStorage floatRegister(int index) { -+ return new VMStorage(StorageType.FLOAT, REG64_MASK, index, "f" + index); -+ } -+ -+ public static VMStorage stackStorage(short size, int byteOffset) { -+ return new VMStorage(StorageType.STACK, size, byteOffset); -+ } -+ -+ public static ABIDescriptor abiFor(VMStorage[] inputIntRegs, -+ VMStorage[] inputFloatRegs, -+ VMStorage[] outputIntRegs, -+ VMStorage[] outputFloatRegs, -+ VMStorage[] volatileIntRegs, -+ VMStorage[] volatileFloatRegs, -+ int stackAlignment, -+ int shadowSpace, -+ VMStorage scratch1, VMStorage scratch2) { -+ return new ABIDescriptor( -+ INSTANCE, -+ new VMStorage[][] { -+ inputIntRegs, -+ inputFloatRegs, -+ }, -+ new VMStorage[][] { -+ outputIntRegs, -+ outputFloatRegs, -+ }, -+ new VMStorage[][] { -+ volatileIntRegs, -+ volatileFloatRegs, -+ }, -+ stackAlignment, -+ shadowSpace, -+ scratch1, scratch2, -+ StubLocations.TARGET_ADDRESS.storage(StorageType.PLACEHOLDER), -+ StubLocations.RETURN_BUFFER.storage(StorageType.PLACEHOLDER), -+ StubLocations.CAPTURED_STATE_BUFFER.storage(StorageType.PLACEHOLDER)); -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java -new file mode 100644 -index 00000000000..84392e45089 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390CallArranger.java -@@ -0,0 +1,311 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+package jdk.internal.foreign.abi.s390.linux; -+ -+import java.lang.foreign.AddressLayout; -+import java.lang.foreign.FunctionDescriptor; -+import java.lang.foreign.GroupLayout; -+import java.lang.foreign.MemoryLayout; -+import java.lang.foreign.MemorySegment; -+import jdk.internal.foreign.abi.ABIDescriptor; -+import jdk.internal.foreign.abi.AbstractLinker.UpcallStubFactory; -+import jdk.internal.foreign.abi.Binding; -+import jdk.internal.foreign.abi.CallingSequence; -+import jdk.internal.foreign.abi.CallingSequenceBuilder; -+import jdk.internal.foreign.abi.DowncallLinker; -+import jdk.internal.foreign.abi.LinkerOptions; -+import jdk.internal.foreign.abi.UpcallLinker; -+import jdk.internal.foreign.abi.SharedUtils; -+import jdk.internal.foreign.abi.VMStorage; -+import jdk.internal.foreign.Utils; -+ -+import java.lang.foreign.ValueLayout; -+import java.lang.invoke.MethodHandle; -+import java.lang.invoke.MethodType; -+import java.util.List; -+import java.util.Map; -+import java.util.Optional; -+ -+import static jdk.internal.foreign.abi.s390.linux.TypeClass.*; -+import static jdk.internal.foreign.abi.s390.S390Architecture.*; -+import static jdk.internal.foreign.abi.s390.S390Architecture.Regs.*; -+ -+/** -+ * For the S390 C ABI specifically, this class uses CallingSequenceBuilder -+ * to translate a C FunctionDescriptor into a CallingSequence, which can then be turned into a MethodHandle. -+ * -+ * This includes taking care of synthetic arguments like pointers to return buffers for 'in-memory' returns. -+ */ -+public class LinuxS390CallArranger { -+ -+ private static final int STACK_SLOT_SIZE = 8; -+ public static final int MAX_REGISTER_ARGUMENTS = 5; -+ public static final int MAX_FLOAT_REGISTER_ARGUMENTS = 4; -+ -+ private static final ABIDescriptor CLinux = abiFor( -+ new VMStorage[] { r2, r3, r4, r5, r6, }, // GP input -+ new VMStorage[] { f0, f2, f4, f6 }, // FP input -+ new VMStorage[] { r2, }, // GP output -+ new VMStorage[] { f0, }, // FP output -+ new VMStorage[] { r0, r1, r2, r3, r4, r5, r14 }, // volatile GP -+ new VMStorage[] { f1, f3, f5, f7 }, // volatile FP (excluding argument registers) -+ 8, // Stack is always 8 byte aligned on S390 -+ 160, // ABI header -+ r0, r1 // scratch reg r0 & r1 -+ ); -+ -+ public record Bindings(CallingSequence callingSequence, boolean isInMemoryReturn) {} -+ -+ public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall) { -+ return getBindings(mt, cDesc, forUpcall, LinkerOptions.empty()); -+ } -+ -+ public static Bindings getBindings(MethodType mt, FunctionDescriptor cDesc, boolean forUpcall, LinkerOptions options) { -+ CallingSequenceBuilder csb = new CallingSequenceBuilder(CLinux, forUpcall, options); -+ -+ BindingCalculator argCalc = forUpcall ? new BoxBindingCalculator(true) : new UnboxBindingCalculator(true); -+ BindingCalculator retCalc = forUpcall ? new UnboxBindingCalculator(false) : new BoxBindingCalculator(false); -+ -+ boolean returnInMemory = isInMemoryReturn(cDesc.returnLayout()); -+ if (returnInMemory) { -+ Class carrier = MemorySegment.class; -+ MemoryLayout layout =SharedUtils.C_POINTER; -+ csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); -+ } else if (cDesc.returnLayout().isPresent()) { -+ Class carrier = mt.returnType(); -+ MemoryLayout layout = cDesc.returnLayout().get(); -+ csb.setReturnBindings(carrier, layout, retCalc.getBindings(carrier, layout)); -+ } -+ -+ for (int i = 0; i < mt.parameterCount(); i++) { -+ Class carrier = mt.parameterType(i); -+ MemoryLayout layout = cDesc.argumentLayouts().get(i); -+ csb.addArgumentBindings(carrier, layout, argCalc.getBindings(carrier, layout)); -+ } -+ -+ return new Bindings(csb.build(), returnInMemory); -+ } -+ -+ public static MethodHandle arrangeDowncall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { -+ Bindings bindings = getBindings(mt, cDesc, false, options); -+ -+ MethodHandle handle = new DowncallLinker(CLinux, bindings.callingSequence).getBoundMethodHandle(); -+ -+ if (bindings.isInMemoryReturn) { -+ handle = SharedUtils.adaptDowncallForIMR(handle, cDesc, bindings.callingSequence); -+ } -+ -+ return handle; -+ } -+ -+ public static UpcallStubFactory arrangeUpcall(MethodType mt, FunctionDescriptor cDesc, LinkerOptions options) { -+ Bindings bindings = getBindings(mt, cDesc, true, options); -+ -+ final boolean dropReturn = true; /* drop return, since we don't have bindings for it */ -+ return SharedUtils.arrangeUpcallHelper(mt, bindings.isInMemoryReturn, dropReturn, CLinux, -+ bindings.callingSequence); -+ } -+ -+ private static boolean isInMemoryReturn(Optional returnLayout) { -+ return returnLayout -+ .filter(layout -> layout instanceof GroupLayout) -+ .isPresent(); -+ } -+ -+ static class StorageCalculator { -+ private final boolean forArguments; -+ -+ private final int[] nRegs = new int[] { 0, 0 }; -+ private long stackOffset = 0; -+ -+ public StorageCalculator(boolean forArguments) { -+ this.forArguments = forArguments; -+ } -+ -+ VMStorage stackAlloc(long size, long alignment) { -+ long alignedStackOffset = Utils.alignUp(stackOffset, alignment); -+ -+ short encodedSize = (short) size; -+ assert (encodedSize & 0xFFFF) == size; -+ -+ VMStorage storage = stackStorage(encodedSize, (int) alignedStackOffset); -+ stackOffset = alignedStackOffset + size; -+ return storage; -+ } -+ -+ VMStorage regAlloc(int type) { -+ int gpRegCnt = (type == StorageType.INTEGER) ? 1 : 0; -+ int fpRegCnt = (type == StorageType.FLOAT) ? 1 : 0; -+ -+ // Use stack if not enough registers available. -+ if ((type == StorageType.FLOAT && (nRegs[StorageType.FLOAT] + fpRegCnt) > MAX_FLOAT_REGISTER_ARGUMENTS) -+ || (type == StorageType.INTEGER && (nRegs[StorageType.INTEGER] + gpRegCnt) > MAX_REGISTER_ARGUMENTS)) return null; -+ -+ VMStorage[] source = (forArguments ? CLinux.inputStorage : CLinux.outputStorage)[type]; -+ VMStorage result = source[nRegs[type]]; -+ -+ nRegs[StorageType.INTEGER] += gpRegCnt; -+ nRegs[StorageType.FLOAT] += fpRegCnt; -+ return result; -+ -+ } -+ VMStorage getStorage(int type, boolean is32Bit) { -+ VMStorage reg = regAlloc(type); -+ if (reg != null) { -+ if (is32Bit) { -+ reg = new VMStorage(reg.type(), REG32_MASK, reg.indexOrOffset()); -+ } -+ return reg; -+ } -+ VMStorage stack; -+ if (is32Bit) { -+ stackAlloc(4, STACK_SLOT_SIZE); // Skip first half of stack slot. -+ stack = stackAlloc(4, 4); -+ } else -+ stack = stackAlloc(8, STACK_SLOT_SIZE); -+ -+ return stack; -+ } -+ } -+ -+ abstract static class BindingCalculator { -+ protected final StorageCalculator storageCalculator; -+ -+ protected BindingCalculator(boolean forArguments) { -+ this.storageCalculator = new LinuxS390CallArranger.StorageCalculator(forArguments); -+ } -+ -+ abstract List getBindings(Class carrier, MemoryLayout layout); -+ } -+ -+ // Compute recipe for transferring arguments / return values to C from Java. -+ static class UnboxBindingCalculator extends BindingCalculator { -+ UnboxBindingCalculator(boolean forArguments) { -+ super(forArguments); -+ } -+ -+ @Override -+ List getBindings(Class carrier, MemoryLayout layout) { -+ TypeClass argumentClass = TypeClass.classifyLayout(layout); -+ Binding.Builder bindings = Binding.builder(); -+ switch (argumentClass) { -+ case STRUCT_REGISTER -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); -+ bindings.bufferLoad(0, type) -+ .vmStore(storage, type); -+ } -+ case STRUCT_SFA -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); -+ bindings.bufferLoad(0, type) -+ .vmStore(storage, type); -+ } -+ case STRUCT_REFERENCE -> { -+ assert carrier == MemorySegment.class; -+ bindings.copy(layout) -+ .unboxAddress(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmStore(storage, long.class); -+ } -+ case POINTER -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.unboxAddress() -+ .vmStore(storage, long.class); -+ } -+ case INTEGER -> { -+ // ABI requires all int types to get extended to 64 bit. -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmStore(storage, carrier); -+ } -+ case FLOAT -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); -+ bindings.vmStore(storage, carrier); -+ } -+ default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); -+ } -+ return bindings.build(); -+ } -+ } -+ -+ // Compute recipe for transferring arguments / return values from C to Java. -+ static class BoxBindingCalculator extends BindingCalculator { -+ BoxBindingCalculator(boolean forArguments) { -+ super(forArguments); -+ } -+ -+ @Override -+ List getBindings(Class carrier, MemoryLayout layout) { -+ TypeClass argumentClass = TypeClass.classifyLayout(layout); -+ Binding.Builder bindings = Binding.builder(); -+ switch (argumentClass) { -+ case STRUCT_REGISTER -> { -+ assert carrier == MemorySegment.class; -+ bindings.allocate(layout) -+ .dup(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), false); -+ bindings.vmLoad(storage, type) -+ .bufferStore(0, type); -+ } -+ case STRUCT_SFA -> { -+ assert carrier == MemorySegment.class; -+ bindings.allocate(layout) -+ .dup(); -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, layout.byteSize() == 4); -+ Class type = SharedUtils.primitiveCarrierForSize(layout.byteSize(), true); -+ bindings.vmLoad(storage, type) -+ .bufferStore(0, type); -+ } -+ case STRUCT_REFERENCE -> { -+ assert carrier == MemorySegment.class; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, long.class) -+ .boxAddress(layout); -+ } -+ case POINTER -> { -+ AddressLayout addressLayout = (AddressLayout) layout; -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, long.class) -+ .boxAddressRaw(Utils.pointeeByteSize(addressLayout), Utils.pointeeByteAlign(addressLayout)); -+ } -+ case INTEGER -> { -+ // We could use carrier != long.class for BoxBindingCalculator, but C always uses 64 bit slots. -+ VMStorage storage = storageCalculator.getStorage(StorageType.INTEGER, false); -+ bindings.vmLoad(storage, carrier); -+ } -+ case FLOAT -> { -+ VMStorage storage = storageCalculator.getStorage(StorageType.FLOAT, carrier == float.class); -+ bindings.vmLoad(storage, carrier); -+ } -+ default -> throw new UnsupportedOperationException("Unhandled class " + argumentClass); -+ } -+ return bindings.build(); -+ } -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java -new file mode 100644 -index 00000000000..ac004b9e1e0 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/LinuxS390Linker.java -@@ -0,0 +1,64 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+package jdk.internal.foreign.abi.s390.linux; -+ -+import jdk.internal.foreign.abi.AbstractLinker; -+import jdk.internal.foreign.abi.LinkerOptions; -+ -+import java.lang.foreign.FunctionDescriptor; -+import java.lang.invoke.MethodHandle; -+import java.lang.invoke.MethodType; -+import java.nio.ByteOrder; -+ -+public final class LinuxS390Linker extends AbstractLinker { -+ -+ public static LinuxS390Linker getInstance() { -+ final class Holder { -+ private static final LinuxS390Linker INSTANCE = new LinuxS390Linker(); -+ } -+ -+ return Holder.INSTANCE; -+ } -+ -+ private LinuxS390Linker() { -+ // Ensure there is only one instance -+ } -+ -+ @Override -+ protected MethodHandle arrangeDowncall(MethodType inferredMethodType, FunctionDescriptor function, LinkerOptions options) { -+ return LinuxS390CallArranger.arrangeDowncall(inferredMethodType, function, options); -+ } -+ -+ @Override -+ protected UpcallStubFactory arrangeUpcall(MethodType targetType, FunctionDescriptor function, LinkerOptions options) { -+ return LinuxS390CallArranger.arrangeUpcall(targetType, function, options); -+ } -+ -+ @Override -+ protected ByteOrder linkerByteOrder() { -+ return ByteOrder.BIG_ENDIAN; -+ } -+} -diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java -new file mode 100644 -index 00000000000..095cb2c08a8 ---- /dev/null -+++ b/src/java.base/share/classes/jdk/internal/foreign/abi/s390/linux/TypeClass.java -@@ -0,0 +1,126 @@ -+/* -+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. -+ * Copyright (c) 2023 IBM Corp. All rights reserved. -+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -+ * -+ * This code is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 only, as -+ * published by the Free Software Foundation. Oracle designates this -+ * particular file as subject to the "Classpath" exception as provided -+ * by Oracle in the LICENSE file that accompanied this code. -+ * -+ * This code is distributed in the hope that it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * version 2 for more details (a copy is included in the LICENSE file that -+ * accompanied this code). -+ * -+ * You should have received a copy of the GNU General Public License version -+ * 2 along with this work; if not, write to the Free Software Foundation, -+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -+ * -+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -+ * or visit www.oracle.com if you need additional information or have any -+ * questions. -+ */ -+package jdk.internal.foreign.abi.s390.linux; -+ -+import java.lang.foreign.GroupLayout; -+import java.lang.foreign.MemoryLayout; -+import java.lang.foreign.MemorySegment; -+import java.lang.foreign.SequenceLayout; -+import java.lang.foreign.ValueLayout; -+import java.util.List; -+import java.util.ArrayList; -+ -+public enum TypeClass { -+ STRUCT_REGISTER, -+ STRUCT_SFA, // Single Float Aggregate -+ STRUCT_REFERENCE, -+ POINTER, -+ INTEGER, -+ FLOAT; -+ -+ private static TypeClass classifyValueType(ValueLayout type) { -+ Class carrier = type.carrier(); -+ if (carrier == boolean.class || carrier == byte.class || carrier == char.class || -+ carrier == short.class || carrier == int.class || carrier == long.class) { -+ return INTEGER; -+ } else if (carrier == float.class || carrier == double.class) { -+ return FLOAT; -+ } else if (carrier == MemorySegment.class) { -+ return POINTER; -+ } else { -+ throw new IllegalStateException("Cannot get here: " + carrier.getName()); -+ } -+ } -+ -+ private static boolean isRegisterAggregate(MemoryLayout type) { -+ long byteSize = type.byteSize(); -+ if (byteSize > 8 || byteSize == 3 || byteSize == 5 || byteSize == 6 || byteSize == 7) -+ return false; -+ return true; -+ } -+ -+ static List scalarLayouts(GroupLayout gl) { -+ List out = new ArrayList<>(); -+ scalarLayoutsInternal(out, gl); -+ return out; -+ } -+ -+ private static void scalarLayoutsInternal(List out, GroupLayout gl) { -+ for (MemoryLayout member : gl.memberLayouts()) { -+ if (member instanceof GroupLayout memberGl) { -+ scalarLayoutsInternal(out, memberGl); -+ } else if (member instanceof SequenceLayout memberSl) { -+ for (long i = 0; i < memberSl.elementCount(); i++) { -+ out.add(memberSl.elementLayout()); -+ } -+ } else { -+ // padding or value layouts -+ out.add(member); -+ } -+ } -+ } -+ -+ static boolean isSingleFloatAggregate(MemoryLayout type) { -+ List scalarLayouts = scalarLayouts((GroupLayout) type); -+ -+ final int numElements = scalarLayouts.size(); -+ if (numElements > 1 || numElements == 0) -+ return false; -+ -+ MemoryLayout baseType = scalarLayouts.get(0); -+ -+ if (!(baseType instanceof ValueLayout)) -+ return false; -+ -+ TypeClass baseArgClass = classifyValueType((ValueLayout) baseType); -+ if (baseArgClass != FLOAT) -+ return false; -+ -+ return true; -+ } -+ -+ private static TypeClass classifyStructType(MemoryLayout layout) { -+ -+ if (!isRegisterAggregate(layout)) { -+ return TypeClass.STRUCT_REFERENCE; -+ } -+ -+ if (isSingleFloatAggregate(layout)) { -+ return TypeClass.STRUCT_SFA; -+ } -+ return TypeClass.STRUCT_REGISTER; -+ } -+ -+ public static TypeClass classifyLayout(MemoryLayout type) { -+ if (type instanceof ValueLayout) { -+ return classifyValueType((ValueLayout) type); -+ } else if (type instanceof GroupLayout) { -+ return classifyStructType(type); -+ } else { -+ throw new IllegalArgumentException("Unsupported layout: " + type); -+ } -+ } -+} -diff --git a/test/jdk/java/foreign/TestClassLoaderFindNative.java b/test/jdk/java/foreign/TestClassLoaderFindNative.java -index 3f5fec0c195..44ec8732ed4 100644 ---- a/test/jdk/java/foreign/TestClassLoaderFindNative.java -+++ b/test/jdk/java/foreign/TestClassLoaderFindNative.java -@@ -31,9 +31,10 @@ - import java.lang.foreign.Arena; - import java.lang.foreign.MemorySegment; - import java.lang.foreign.SymbolLookup; -+import java.nio.ByteOrder; - import org.testng.annotations.Test; - --import static java.lang.foreign.ValueLayout.JAVA_BYTE; -+import static java.lang.foreign.ValueLayout.JAVA_INT; - import static org.testng.Assert.*; - - // FYI this test is run on 64-bit platforms only for now, -@@ -58,8 +59,8 @@ public class TestClassLoaderFindNative { - - @Test - public void testVariableSymbolLookup() { -- MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(1); -- assertEquals(segment.get(JAVA_BYTE, 0), 42); -+ MemorySegment segment = SymbolLookup.loaderLookup().find("c").get().reinterpret(4); -+ assertEquals(segment.get(JAVA_INT, 0), 42); - } - - @Test -diff --git a/test/jdk/java/foreign/TestIllegalLink.java b/test/jdk/java/foreign/TestIllegalLink.java -index 677f0bce62f..5d8277a5d4c 100644 ---- a/test/jdk/java/foreign/TestIllegalLink.java -+++ b/test/jdk/java/foreign/TestIllegalLink.java -@@ -54,6 +54,7 @@ import static org.testng.Assert.fail; - public class TestIllegalLink extends NativeTestHelper { - - private static final boolean IS_SYSV = CABI.current() == CABI.SYS_V; -+ private static final boolean IS_LE = ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN; - - private static final MemorySegment DUMMY_TARGET = MemorySegment.ofAddress(1); - private static final MethodHandle DUMMY_TARGET_MH = MethodHandles.empty(MethodType.methodType(void.class)); -@@ -113,27 +114,27 @@ public class TestIllegalLink extends NativeTestHelper { - { - FunctionDescriptor.of(MemoryLayout.sequenceLayout(2, C_INT)), - NO_OPTIONS, -- "Unsupported layout: [2:i4]" -+ IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.sequenceLayout(2, C_INT)), - NO_OPTIONS, -- "Unsupported layout: [2:i4]" -+ IS_LE ? "Unsupported layout: [2:i4]" : "Unsupported layout: [2:I4]" - }, - { - FunctionDescriptor.ofVoid(C_INT.withByteAlignment(2)), - NO_OPTIONS, -- "Unsupported layout: 2%i4" -+ IS_LE ? "Unsupported layout: 2%i4" : "Unsupported layout: 2%I4" - }, - { - FunctionDescriptor.ofVoid(C_POINTER.withByteAlignment(2)), - NO_OPTIONS, -- "Unsupported layout: 2%a8" -+ IS_LE ? "Unsupported layout: 2%a8" : "Unsupported layout: 2%A8" - }, - { - FunctionDescriptor.ofVoid(ValueLayout.JAVA_CHAR.withByteAlignment(4)), - NO_OPTIONS, -- "Unsupported layout: 4%c2" -+ IS_LE ? "Unsupported layout: 4%c2" : "Unsupported layout: 4%C2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -142,7 +143,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withName("z").withByteAlignment(1) - ).withByteAlignment(1)), - NO_OPTIONS, -- "Unsupported layout: 1%s2" -+ IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -152,7 +153,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withName("z").withByteAlignment(1) - ))), - NO_OPTIONS, -- "Unsupported layout: 1%s2" -+ IS_LE ? "Unsupported layout: 1%s2" : "Unsupported layout: 1%S2" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -160,7 +161,7 @@ public class TestIllegalLink extends NativeTestHelper { - C_INT.withByteAlignment(1) - ))), - NO_OPTIONS, -- "Unsupported layout: 1%i4" -+ IS_LE ? "Unsupported layout: 1%i4" : "Unsupported layout: 1%I4" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -173,17 +174,17 @@ public class TestIllegalLink extends NativeTestHelper { - { - FunctionDescriptor.of(C_INT.withOrder(nonNativeOrder())), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.of(MemoryLayout.structLayout(C_INT.withOrder(nonNativeOrder()))), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.of(MemoryLayout.structLayout(MemoryLayout.sequenceLayout(C_INT.withOrder(nonNativeOrder())))), - NO_OPTIONS, -- "Unsupported layout: I4" -+ IS_LE ? "Unsupported layout: I4" : "Unsupported layout: i4" - }, - { - FunctionDescriptor.ofVoid(MemoryLayout.structLayout( -@@ -227,5 +228,4 @@ public class TestIllegalLink extends NativeTestHelper { - ? ByteOrder.BIG_ENDIAN - : ByteOrder.LITTLE_ENDIAN; - } -- - } -diff --git a/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java b/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -index 1646063fb08..97856075bef 100644 ---- a/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -+++ b/test/jdk/java/foreign/callarranger/platform/PlatformLayouts.java -@@ -305,5 +305,4 @@ public final class PlatformLayouts { - public static final AddressLayout C_POINTER = SharedUtils.C_POINTER; - - } -- - } diff --git a/sources b/sources index b2b5901..ec9f16c 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (openjdk-21.0.1+12.tar.xz) = 96513e1346dea623183ae68f88690aa7ea41d65f6a2499b7f9c08954643dd2a6f10d3f4f529fc34e00ff14e8c1bd3764ac78a5c669937a200c910ebcc74e782b +SHA512 (openjdk-21.0.2+13.tar.xz) = 2a5e7a7bafad5387973980f3c1241817a7a7fd98595eabb390efca9ab7c9ea42a251b99497a063097b1a8ba1a71943b5264bae9a05a958f766f80216e9bc1f4e