diff --git a/make/langtools/tools/previewfeature/SetupPreviewFeature.java b/make/langtools/tools/previewfeature/SetupPreviewFeature.java index 2d5207f0e17..5f9b00edc6d 100644 --- a/make/langtools/tools/previewfeature/SetupPreviewFeature.java +++ b/make/langtools/tools/previewfeature/SetupPreviewFeature.java @@ -30,6 +30,7 @@ import java.io.StringWriter; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; @@ -76,7 +77,7 @@ public class SetupPreviewFeature { var target = Path.of(args[1]); Files.createDirectories(target.getParent()); if (constantsToAdd.isEmpty()) { - Files.copy(source, target); + Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); } else { String sourceCode = Files.readString(source); try (var out = Files.newBufferedWriter(target)) { diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index b5e15402941..7fa2e8086ad 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -3454,7 +3454,7 @@ void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement void MacroAssembler::reinit_heapbase() { if (UseCompressedOops) { - if (Universe::is_fully_initialized()) { + if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) { mov(rheapbase, CompressedOops::base()); } else { lea(rheapbase, ExternalAddress(CompressedOops::base_addr())); @@ -5128,7 +5128,8 @@ void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) { if (CompressedKlassPointers::base() == nullptr) { cmp(klass, tmp, LSL, CompressedKlassPointers::shift()); return; - } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0 + } else if (!AOTCodeCache::is_on_for_dump() && + ((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0 && CompressedKlassPointers::shift() == 0) { // Only the bottom 32 bits matter cmpw(klass, tmp); @@ -5371,7 +5372,7 @@ void MacroAssembler::encode_klass_not_null_for_aot(Register dst, Register src) { } void MacroAssembler::encode_klass_not_null(Register dst, Register src) { - if (AOTCodeCache::is_on_for_dump()) { + if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) { encode_klass_not_null_for_aot(dst, src); return; } diff --git a/src/hotspot/cpu/aarch64/runtime_aarch64.cpp b/src/hotspot/cpu/aarch64/runtime_aarch64.cpp index e36aa21b567..638e57b03fe 100644 --- a/src/hotspot/cpu/aarch64/runtime_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/runtime_aarch64.cpp @@ -290,7 +290,7 @@ ExceptionBlob* OptoRuntime::generate_exception_blob() { assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned"); const char* name = OptoRuntime::stub_name(StubId::c2_exception_id); - CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::C2Blob, (uint)BlobId::c2_exception_id, name); + CodeBlob* blob = AOTCodeCache::load_code_blob(AOTCodeEntry::C2Blob, BlobId::c2_exception_id); if (blob != nullptr) { return blob->as_exception_blob(); } diff --git a/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp index 695534604b8..9dac6a39b82 100644 --- a/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp @@ -84,8 +84,7 @@ do_stub(compiler, count_positives) \ do_arch_entry(aarch64, compiler, count_positives, count_positives, \ count_positives) \ - do_stub(compiler, count_positives_long) \ - do_arch_entry(aarch64, compiler, count_positives_long, \ + do_arch_entry(aarch64, compiler, count_positives, \ count_positives_long, count_positives_long) \ do_stub(compiler, compare_long_string_LL) \ do_arch_entry(aarch64, compiler, compare_long_string_LL, \ @@ -108,8 +107,9 @@ do_stub(compiler, string_indexof_linear_ul) \ do_arch_entry(aarch64, compiler, string_indexof_linear_ul, \ string_indexof_linear_ul, string_indexof_linear_ul) \ - /* this uses the entry for ghash_processBlocks */ \ - do_stub(compiler, ghash_processBlocks_wide) \ + do_stub(compiler, ghash_processBlocks_small) \ + do_arch_entry(aarch64, compiler, ghash_processBlocks_small, \ + ghash_processBlocks_small, ghash_processBlocks_small) \ #define STUBGEN_FINAL_BLOBS_ARCH_DO(do_stub, \ @@ -139,9 +139,49 @@ do_stub(final, spin_wait) \ do_arch_entry_init(aarch64, final, spin_wait, spin_wait, \ spin_wait, empty_spin_wait) \ - /* stub only -- entries are not stored in StubRoutines::aarch64 */ \ /* n.b. these are not the same as the generic atomic stubs */ \ do_stub(final, atomic_entry_points) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_fetch_add_4_impl, atomic_fetch_add_4_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_fetch_add_8_impl, atomic_fetch_add_8_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_fetch_add_4_relaxed_impl, \ + atomic_fetch_add_4_relaxed_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_fetch_add_8_relaxed_impl, \ + atomic_fetch_add_8_relaxed_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_xchg_4_impl, atomic_xchg_4_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_xchg_8_impl, atomic_xchg_8_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_1_impl, atomic_cmpxchg_1_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_4_impl, atomic_cmpxchg_4_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_8_impl, atomic_cmpxchg_8_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_1_relaxed_impl, \ + atomic_cmpxchg_1_relaxed_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_4_relaxed_impl, \ + atomic_cmpxchg_4_relaxed_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_8_relaxed_impl, \ + atomic_cmpxchg_8_relaxed_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_4_release_impl, \ + atomic_cmpxchg_4_release_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_8_release_impl, \ + atomic_cmpxchg_8_release_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_4_seq_cst_impl, \ + atomic_cmpxchg_4_seq_cst_impl) \ + do_arch_entry(aarch64, final, atomic_entry_points, \ + atomic_cmpxchg_8_seq_cst_impl, \ + atomic_cmpxchg_8_seq_cst_impl) \ #endif // CPU_AARCH64_STUBDECLARATIONS_HPP diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 21a1124a8ec..32fd8afb268 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -79,6 +79,166 @@ #define BIND(label) bind(label); BLOCK_COMMENT(#label ":") +// Constant data definitions + +static const uint32_t _sha256_round_consts[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; + +static const uint64_t _sha512_round_consts[80] = { + 0x428A2F98D728AE22L, 0x7137449123EF65CDL, 0xB5C0FBCFEC4D3B2FL, + 0xE9B5DBA58189DBBCL, 0x3956C25BF348B538L, 0x59F111F1B605D019L, + 0x923F82A4AF194F9BL, 0xAB1C5ED5DA6D8118L, 0xD807AA98A3030242L, + 0x12835B0145706FBEL, 0x243185BE4EE4B28CL, 0x550C7DC3D5FFB4E2L, + 0x72BE5D74F27B896FL, 0x80DEB1FE3B1696B1L, 0x9BDC06A725C71235L, + 0xC19BF174CF692694L, 0xE49B69C19EF14AD2L, 0xEFBE4786384F25E3L, + 0x0FC19DC68B8CD5B5L, 0x240CA1CC77AC9C65L, 0x2DE92C6F592B0275L, + 0x4A7484AA6EA6E483L, 0x5CB0A9DCBD41FBD4L, 0x76F988DA831153B5L, + 0x983E5152EE66DFABL, 0xA831C66D2DB43210L, 0xB00327C898FB213FL, + 0xBF597FC7BEEF0EE4L, 0xC6E00BF33DA88FC2L, 0xD5A79147930AA725L, + 0x06CA6351E003826FL, 0x142929670A0E6E70L, 0x27B70A8546D22FFCL, + 0x2E1B21385C26C926L, 0x4D2C6DFC5AC42AEDL, 0x53380D139D95B3DFL, + 0x650A73548BAF63DEL, 0x766A0ABB3C77B2A8L, 0x81C2C92E47EDAEE6L, + 0x92722C851482353BL, 0xA2BFE8A14CF10364L, 0xA81A664BBC423001L, + 0xC24B8B70D0F89791L, 0xC76C51A30654BE30L, 0xD192E819D6EF5218L, + 0xD69906245565A910L, 0xF40E35855771202AL, 0x106AA07032BBD1B8L, + 0x19A4C116B8D2D0C8L, 0x1E376C085141AB53L, 0x2748774CDF8EEB99L, + 0x34B0BCB5E19B48A8L, 0x391C0CB3C5C95A63L, 0x4ED8AA4AE3418ACBL, + 0x5B9CCA4F7763E373L, 0x682E6FF3D6B2B8A3L, 0x748F82EE5DEFB2FCL, + 0x78A5636F43172F60L, 0x84C87814A1F0AB72L, 0x8CC702081A6439ECL, + 0x90BEFFFA23631E28L, 0xA4506CEBDE82BDE9L, 0xBEF9A3F7B2C67915L, + 0xC67178F2E372532BL, 0xCA273ECEEA26619CL, 0xD186B8C721C0C207L, + 0xEADA7DD6CDE0EB1EL, 0xF57D4F7FEE6ED178L, 0x06F067AA72176FBAL, + 0x0A637DC5A2C898A6L, 0x113F9804BEF90DAEL, 0x1B710B35131C471BL, + 0x28DB77F523047D84L, 0x32CAAB7B40C72493L, 0x3C9EBE0A15C9BEBCL, + 0x431D67C49C100D4CL, 0x4CC5D4BECB3E42B6L, 0x597F299CFC657E2AL, + 0x5FCB6FAB3AD6FAECL, 0x6C44198C4A475817L +}; + +static const uint64_t _sha3_round_consts[24] = { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, + 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, + 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, + 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L +}; + +static const uint64_t _double_keccak_round_consts[24] = { + 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, + 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, + 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, + 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, + 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L +}; + +static const char _encodeBlock_toBase64[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' +}; + +static const char _encodeBlock_toBase64URL[64] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' +}; + +// Non-SIMD lookup tables are mostly dumped from fromBase64 array used in java.util.Base64, +// except the trailing character '=' is also treated illegal value in this intrinsic. That +// is java.util.Base64.fromBase64['='] = -2, while fromBase(URL)64ForNoSIMD['='] = 255 here. +static const uint8_t _decodeBlock_fromBase64ForNoSIMD[256] = { + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, 255u, 63u, + 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, + 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, 255u, + 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, + 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, +}; + +static const uint8_t _decodeBlock_fromBase64URLForNoSIMD[256] = { + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, + 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, + 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, 63u, + 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, + 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, +}; + +// A legal value of base64 code is in range [0, 127]. We need two lookups +// with tbl/tbx and combine them to get the decode data. The 1st table vector +// lookup use tbl, out of range indices are set to 0 in destination. The 2nd +// table vector lookup use tbx, out of range indices are unchanged in +// destination. Input [64..126] is mapped to index [65, 127] in second lookup. +// The value of index 64 is set to 0, so that we know that we already get the +// decoded data with the 1st lookup. +static const uint8_t _decodeBlock_fromBase64ForSIMD[128] = { + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, 255u, 63u, + 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, + 0u, 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, + 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, + 255u, 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, + 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, +}; + +static const uint8_t _decodeBlock_fromBase64URLForSIMD[128] = { + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, + 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, + 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, + 0u, 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, + 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, + 63u, 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, + 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, +}; + + // Stub Code definitions class StubGenerator: public StubCodeGenerator { @@ -203,8 +363,17 @@ class StubGenerator: public StubCodeGenerator { "adjust this code"); StubId stub_id = StubId::stubgen_call_stub_id; + GrowableArray
entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 2, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == 1, "expected 1 extra entry"); + return_address = entries.at(0); + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Address sp_after_call (rfp, sp_after_call_off * wordSize); @@ -323,6 +492,7 @@ class StubGenerator: public StubCodeGenerator { // save current address for use by exception handling code return_address = __ pc(); + entries.append(return_address); // store result depending on type (everything that is not // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) @@ -406,6 +576,9 @@ class StubGenerator: public StubCodeGenerator { __ strd(j_farg0, Address(j_rarg2, 0)); __ br(Assembler::AL, exit); + // record the stub entry and end plus the auxiliary entry + store_archive_data(stub_id, start, __ pc(), &entries); + return start; } @@ -423,8 +596,14 @@ class StubGenerator: public StubCodeGenerator { address generate_catch_exception() { StubId stub_id = StubId::stubgen_catch_exception_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // same as in generate_call_stub(): const Address sp_after_call(rfp, sp_after_call_off * wordSize); @@ -450,7 +629,9 @@ class StubGenerator: public StubCodeGenerator { __ verify_oop(r0); __ str(r0, Address(rthread, Thread::pending_exception_offset())); - __ mov(rscratch1, (address)__FILE__); + // special case -- add file name string to AOT address table + address file = (address)AOTCodeCache::add_C_string(__FILE__); + __ lea(rscratch1, ExternalAddress(file)); __ str(rscratch1, Address(rthread, Thread::exception_file_offset())); __ movw(rscratch1, (int)__LINE__); __ strw(rscratch1, Address(rthread, Thread::exception_line_offset())); @@ -458,7 +639,10 @@ class StubGenerator: public StubCodeGenerator { // complete return to VM assert(StubRoutines::_call_stub_return_address != nullptr, "_call_stub_return_address must have been generated before"); - __ b(StubRoutines::_call_stub_return_address); + __ b(RuntimeAddress(StubRoutines::_call_stub_return_address)); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); return start; } @@ -479,8 +663,14 @@ class StubGenerator: public StubCodeGenerator { address generate_forward_exception() { StubId stub_id = StubId::stubgen_forward_exception_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Upon entry, LR points to the return address returning into // Java (interpreted or compiled) code; i.e., the return address @@ -551,6 +741,9 @@ class StubGenerator: public StubCodeGenerator { __ verify_oop(r0); __ br(r19); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -569,8 +762,14 @@ class StubGenerator: public StubCodeGenerator { // [tos + 5]: saved rscratch1 address generate_verify_oop() { StubId stub_id = StubId::stubgen_verify_oop_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label exit, error; @@ -613,14 +812,23 @@ class StubGenerator: public StubCodeGenerator { __ blr(rscratch1); __ hlt(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // Generate indices for iota vector. address generate_iota_indices(StubId stub_id) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // B __ emit_data64(0x0706050403020100, relocInfo::none); __ emit_data64(0x0F0E0D0C0B0A0908, relocInfo::none); @@ -639,6 +847,10 @@ class StubGenerator: public StubCodeGenerator { // D - FP __ emit_data64(0x0000000000000000, relocInfo::none); // 0.0d __ emit_data64(0x3FF0000000000000, relocInfo::none); // 1.0d + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -656,15 +868,21 @@ class StubGenerator: public StubCodeGenerator { // r11 < MacroAssembler::zero_words_block_size. address generate_zero_blocks() { + StubId stub_id = StubId::stubgen_zero_blocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); Label done; Label base_aligned; Register base = r10, cnt = r11; - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_zero_blocks_id; - StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); if (UseBlockZeroing) { int zva_length = VM_Version::zva_length(); @@ -707,6 +925,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -803,6 +1024,12 @@ class StubGenerator: public StubCodeGenerator { // s and d are adjusted to point to the remaining words to copy // address generate_copy_longs(StubId stub_id, DecoratorSet decorators, Register s, Register d, Register count) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } BasicType type; copy_direction direction; @@ -854,7 +1081,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label unaligned_copy_long; if (AvoidUnalignedAccesses) { @@ -1154,6 +1381,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); } + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1445,19 +1675,25 @@ class StubGenerator: public StubCodeGenerator { } if (direction == copy_forwards) { if (type != T_OBJECT) { - __ bl(StubRoutines::aarch64::copy_byte_f()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_byte_f())); + __ blr(rscratch1); } else if ((decorators & IS_DEST_UNINITIALIZED) != 0) { - __ bl(StubRoutines::aarch64::copy_oop_uninit_f()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_oop_uninit_f())); + __ blr(rscratch1); } else { - __ bl(StubRoutines::aarch64::copy_oop_f()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_oop_f())); + __ blr(rscratch1); } } else { if (type != T_OBJECT) { - __ bl(StubRoutines::aarch64::copy_byte_b()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_byte_b())); + __ blr(rscratch1); } else if ((decorators & IS_DEST_UNINITIALIZED) != 0) { - __ bl(StubRoutines::aarch64::copy_oop_uninit_b()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_oop_uninit_b())); + __ blr(rscratch1); } else { - __ bl(StubRoutines::aarch64::copy_oop_b()); + __ lea(rscratch1, RuntimeAddress(StubRoutines::aarch64::copy_oop_b())); + __ blr(rscratch1); } } @@ -1508,8 +1744,8 @@ class StubGenerator: public StubCodeGenerator { // stub_id - is used to name the stub and identify all details of // how to perform the copy. // - // entry - is assigned to the stub's post push entry point unless - // it is null + // nopush_entry - is assigned to the stub's post push entry point + // unless it is null // // Inputs: // c_rarg0 - source array address @@ -1525,8 +1761,6 @@ class StubGenerator: public StubCodeGenerator { // copy method // address generate_disjoint_copy(StubId stub_id, address *nopush_entry) { - Register s = c_rarg0, d = c_rarg1, count = c_rarg2; - RegSet saved_reg = RegSet::of(s, d, count); int size; bool aligned; bool is_oop; @@ -1607,17 +1841,45 @@ class StubGenerator: public StubCodeGenerator { ShouldNotReachHere(); break; } + // all stubs provide a 2nd entry which omits the frame push for + // use when bailing out from a conjoint copy. However we may also + // need some extra addressses for memory access protection. + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 2, "sanity check"); + assert(nopush_entry != nullptr, "all disjoint copy stubs export a nopush entry"); + + bool add_extras = !is_oop && (!aligned || sizeof(jlong) == size); + int extra_count = ((add_extras ? 1 : 0) * UnsafeMemoryAccess::COLUMN_COUNT); + GrowableArray entries; + GrowableArray extras; + GrowableArray *extras_ptr = (extra_count > 0 ? &extras : nullptr); + address start = load_archive_data(stub_id, &entries, extras_ptr); + if (start != nullptr) { + assert(entries.length() == entry_count - 1, + "unexpected entries count %d", entries.length()); + *nopush_entry = entries.at(0); + assert(extras.length() == extra_count, + "unexpected extra count %d", extras.length()); + if (add_extras) { + // register one handler at offset 0 + register_unsafe_access_handlers(extras, 0, 1); + } + return start; + } + + Register s = c_rarg0, d = c_rarg1, count = c_rarg2; + RegSet saved_reg = RegSet::of(s, d, count); __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); - if (nopush_entry != nullptr) { - *nopush_entry = __ pc(); - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) - BLOCK_COMMENT("Entry:"); - } + *nopush_entry = __ pc(); + entries.append(*nopush_entry); + + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) + BLOCK_COMMENT("Post-Push Entry:"); DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; if (dest_uninitialized) { @@ -1636,8 +1898,7 @@ class StubGenerator: public StubCodeGenerator { } { // UnsafeMemoryAccess page error: continue after unsafe access - bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size); - UnsafeMemoryAccessMark umam(this, add_entry, true); + UnsafeMemoryAccessMark umam(this, add_extras, true); copy_memory(decorators, is_oop ? T_OBJECT : T_BYTE, aligned, s, d, count, size); } @@ -1652,6 +1913,20 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ mov(r0, zr); // return 0 __ ret(lr); + + address end = __ pc(); + + if (add_extras) { + // retrieve the registered handler addresses + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == extra_count + , "incorrect handlers count %d", extras.length()); + } + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, &entries, extras_ptr); + return start; } @@ -1663,8 +1938,8 @@ class StubGenerator: public StubCodeGenerator { // corresponding disjoint copy routine which can be // jumped to if the ranges do not actually overlap // - // entry - is assigned to the stub's post push entry point unless - // it is null + // nopush_entry - is assigned to the stub's post push entry point + // unless it is null // // // Inputs: @@ -1681,8 +1956,6 @@ class StubGenerator: public StubCodeGenerator { // used by some other conjoint copy method // address generate_conjoint_copy(StubId stub_id, address nooverlap_target, address *nopush_entry) { - Register s = c_rarg0, d = c_rarg1, count = c_rarg2; - RegSet saved_regs = RegSet::of(s, d, count); int size; bool aligned; bool is_oop; @@ -1762,15 +2035,47 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } + // only some conjoint stubs generate a 2nd entry + int entry_count = StubInfo::entry_count(stub_id); + int expected_entry_count = (nopush_entry == nullptr ? 1 : 2); + assert(entry_count == expected_entry_count, + "expected entry count %d does not match declared entry count %d for stub %s", + expected_entry_count, entry_count, StubInfo::name(stub_id)); + // We need to protect memory accesses in certain cases + bool add_extras = !is_oop && (!aligned || sizeof(jlong) == size); + int extra_count = ((add_extras ? 1 : 0) * UnsafeMemoryAccess::COLUMN_COUNT); + GrowableArray entries; + GrowableArray extras; + GrowableArray *entries_ptr = (nopush_entry != nullptr ? &entries : nullptr); + GrowableArray *extras_ptr = (extra_count > 0 ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entries count %d", entries.length()); + assert(extras.length() == extra_count, + "unexpected extra count %d", extras.length()); + if (nopush_entry != nullptr) { + *nopush_entry = entries.at(0); + } + if (add_extras) { + // register one handler at offset 0 + register_unsafe_access_handlers(extras, 0, 1); + } + return start; + } + + Register s = c_rarg0, d = c_rarg1, count = c_rarg2; + RegSet saved_regs = RegSet::of(s, d, count); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); if (nopush_entry != nullptr) { *nopush_entry = __ pc(); + entries.append(*nopush_entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) - BLOCK_COMMENT("Entry:"); + BLOCK_COMMENT("Post-Push Entry:"); } // use fwd copy when (d-s) above_equal (count*size) @@ -1798,8 +2103,7 @@ class StubGenerator: public StubCodeGenerator { } { // UnsafeMemoryAccess page error: continue after unsafe access - bool add_entry = !is_oop && (!aligned || sizeof(jlong) == size); - UnsafeMemoryAccessMark umam(this, add_entry, true); + UnsafeMemoryAccessMark umam(this, add_extras, true); copy_memory(decorators, is_oop ? T_OBJECT : T_BYTE, aligned, s, d, count, -size); } if (is_oop) { @@ -1811,6 +2115,23 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ mov(r0, zr); // return 0 __ ret(lr); + + assert(entries.length() == expected_entry_count - 1, + "unexpected entries count %d", entries.length()); + + address end = __ pc(); + + if (add_extras) { + // retrieve the registered handler addresses + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == extra_count, + "incorrect handlers count %d", extras.length()); + } + + // record the stub entry and end plus any no_push entry and/or + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -1864,6 +2185,27 @@ class StubGenerator: public StubCodeGenerator { ShouldNotReachHere(); } + // The normal stub provides a 2nd entry which omits the frame push + // for use when bailing out from a disjoint copy. + // Only some conjoint stubs generate a 2nd entry + int entry_count = StubInfo::entry_count(stub_id); + int expected_entry_count = (nopush_entry == nullptr ? 1 : 2); + GrowableArray entries; + GrowableArray *entries_ptr = (expected_entry_count == 1 ? nullptr : &entries); + assert(entry_count == expected_entry_count, + "expected entry count %d does not match declared entry count %d for stub %s", + expected_entry_count, entry_count, StubInfo::name(stub_id)); + address start = load_archive_data(stub_id, entries_ptr); + if (start != nullptr) { + assert(entries.length() + 1 == expected_entry_count, + "expected entry count %d does not match return entry count %d for stub %s", + expected_entry_count, entries.length() + 1, StubInfo::name(stub_id)); + if (nopush_entry != nullptr) { + *nopush_entry = entries.at(0); + } + return start; + } + Label L_load_element, L_store_element, L_do_card_marks, L_done, L_done_pop; // Input registers (after setup_arg_regs) @@ -1896,7 +2238,7 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -1913,6 +2255,7 @@ class StubGenerator: public StubCodeGenerator { // Caller of this entry point must set up the argument registers. if (nopush_entry != nullptr) { *nopush_entry = __ pc(); + entries.append(*nopush_entry); BLOCK_COMMENT("Entry:"); } @@ -2010,6 +2353,8 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end plus any no_push entry + store_archive_data(stub_id, start, __ pc() , entries_ptr); return start; } @@ -2072,13 +2417,18 @@ class StubGenerator: public StubCodeGenerator { address int_copy_entry, address long_copy_entry) { StubId stub_id = StubId::stubgen_unsafe_arraycopy_id; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Label L_long_aligned, L_int_aligned, L_short_aligned; Register s = c_rarg0, d = c_rarg1, count = c_rarg2; __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame // bump this on entry, not on exit: @@ -2104,6 +2454,9 @@ class StubGenerator: public StubCodeGenerator { __ lsr(count, count, LogBytesPerLong); // size => long_count __ b(RuntimeAddress(long_copy_entry)); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2125,7 +2478,12 @@ class StubGenerator: public StubCodeGenerator { address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry) { StubId stub_id = StubId::stubgen_generic_arraycopy_id; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Label L_failed, L_objArray; Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs; @@ -2144,7 +2502,7 @@ class StubGenerator: public StubCodeGenerator { StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2383,6 +2741,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2427,10 +2788,15 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); }; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -2563,15 +2929,32 @@ class StubGenerator: public StubCodeGenerator { __ bind(L_exit2); __ leave(); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address generate_unsafecopy_common_error_exit() { - address start_pc = __ pc(); + StubId stub_id = StubId::stubgen_unsafecopy_common_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); + start = __ pc(); __ leave(); __ mov(r0, 0); __ ret(lr); - return start_pc; + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + + return start; } // @@ -2589,13 +2972,28 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - byte value // address generate_unsafe_setmemory() { + StubId stub_id = StubId::stubgen_unsafe_setmemory_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + // we expect one set of extra unsafememory access handler entries + GrowableArray extras; + int extra_count = 1 * UnsafeMemoryAccess::COLUMN_COUNT; + address start = load_archive_data(stub_id, nullptr, &extras); + if (start != nullptr) { + assert(extras.length() == extra_count, + "unexpected extra entry count %d", extras.length()); + register_unsafe_access_handlers(extras, 0, 1); + return start; + } + __ align(CodeEntryAlignment); - StubCodeMark mark(this, StubId::stubgen_unsafe_setmemory_id); - address start = __ pc(); + StubCodeMark mark(this, stub_id); + start = __ pc(); Register dest = c_rarg0, count = c_rarg1, value = c_rarg2; Label tail; + { UnsafeMemoryAccessMark umam(this, true, false); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2679,6 +3077,17 @@ class StubGenerator: public StubCodeGenerator { __ bind(finished); __ leave(); __ ret(lr); + // have to exit the block and destroy the UnsafeMemoryAccessMark + // in order to retrieve the handler end address + } + + // install saved handler addresses in extras + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == extra_count, + "incorrect handlers count %d", extras.length()); + // record the stub entry and end plus the extras + store_archive_data(stub_id, start, end, nullptr, &extras); return start; } @@ -2686,33 +3095,45 @@ class StubGenerator: public StubCodeGenerator { address generate_data_cache_writeback() { const Register line = c_rarg0; // address of line to write back - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_data_cache_writeback_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); __ cache_wb(Address(line, 0)); __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address generate_data_cache_writeback_sync() { - const Register is_pre = c_rarg0; // pre or post sync - - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_data_cache_writeback_sync_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + const Register is_pre = c_rarg0; // pre or post sync + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); // pre wbsync is a no-op // post wbsync translates to an sfence Label skip; - address start = __ pc(); + start = __ pc(); __ enter(); __ cbnz(is_pre, skip); __ cache_wbsync(false); @@ -2720,6 +3141,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2882,8 +3306,15 @@ class StubGenerator: public StubCodeGenerator { // c_rarg2 - sessionKe (key) in little endian int array // address generate_aescrypt_encryptBlock() { - __ align(CodeEntryAlignment); + assert(UseAES, "need AES cryptographic extension support"); StubId stub_id = StubId::stubgen_aescrypt_encryptBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); const Register from = c_rarg0; // source array address @@ -2891,7 +3322,7 @@ class StubGenerator: public StubCodeGenerator { const Register key = c_rarg2; // key array address const Register keylen = rscratch1; - address start = __ pc(); + start = __ pc(); __ enter(); __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -2904,6 +3335,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2916,8 +3350,14 @@ class StubGenerator: public StubCodeGenerator { // address generate_aescrypt_decryptBlock() { assert(UseAES, "need AES cryptographic extension support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_aescrypt_decryptBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label L_doLast; @@ -2926,7 +3366,7 @@ class StubGenerator: public StubCodeGenerator { const Register key = c_rarg2; // key array address const Register keylen = rscratch1; - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame __ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT))); @@ -2938,6 +3378,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2955,8 +3398,14 @@ class StubGenerator: public StubCodeGenerator { // address generate_cipherBlockChaining_encryptAESCrypt() { assert(UseAES, "need AES cryptographic extension support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_encryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; @@ -2969,7 +3418,7 @@ class StubGenerator: public StubCodeGenerator { const Register len_reg = c_rarg4; // src len (must be multiple of blocksize 16) const Register keylen = rscratch1; - address start = __ pc(); + start = __ pc(); __ enter(); @@ -3043,6 +3492,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3060,8 +3512,14 @@ class StubGenerator: public StubCodeGenerator { // address generate_cipherBlockChaining_decryptAESCrypt() { assert(UseAES, "need AES cryptographic extension support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label L_loadkeys_44, L_loadkeys_52, L_aes_loop, L_rounds_44, L_rounds_52; @@ -3074,7 +3532,7 @@ class StubGenerator: public StubCodeGenerator { const Register len_reg = c_rarg4; // src len (must be multiple of blocksize 16) const Register keylen = rscratch1; - address start = __ pc(); + start = __ pc(); __ enter(); @@ -3152,6 +3610,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3188,6 +3649,13 @@ class StubGenerator: public StubCodeGenerator { // r0 - input length // address generate_counterMode_AESCrypt() { + StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } const Register in = c_rarg0; const Register out = c_rarg1; const Register key = c_rarg2; @@ -3248,9 +3716,8 @@ class StubGenerator: public StubCodeGenerator { // Wide bulk encryption of whole blocks. __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id; StubCodeMark mark(this, stub_id); - const address start = __ pc(); + start = __ pc(); __ enter(); Label DONE, CTR_large_block, large_block_return; @@ -3435,6 +3902,9 @@ class StubGenerator: public StubCodeGenerator { __ strw(used, Address(used_ptr)); __ b(large_block_return); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3451,11 +3921,16 @@ class StubGenerator: public StubCodeGenerator { // return - number of processed bytes address generate_galoisCounterMode_AESCrypt() { Label ghash_polynomial; // local data generated after code - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register in = c_rarg0; @@ -3567,6 +4042,9 @@ class StubGenerator: public StubCodeGenerator { // 128-bit vector __ emit_int64(0x87); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3685,10 +4163,16 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -3815,6 +4299,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3838,11 +4325,16 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -3919,6 +4411,9 @@ class StubGenerator: public StubCodeGenerator { __ emit_int32(0x8f1bbcdc); __ emit_int32(0xca62c1d6); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3943,30 +4438,15 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } - - static const uint32_t round_consts[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, - }; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -3987,7 +4467,7 @@ class StubGenerator: public StubCodeGenerator { // t1 == v7 // load 16 keys to v16..v31 - __ lea(rscratch1, ExternalAddress((address)round_consts)); + __ lea(rscratch1, ExternalAddress((address)_sha256_round_consts)); __ ld1(v16, v17, v18, v19, __ T4S, __ post(rscratch1, 64)); __ ld1(v20, v21, v22, v23, __ T4S, __ post(rscratch1, 64)); __ ld1(v24, v25, v26, v27, __ T4S, __ post(rscratch1, 64)); @@ -4048,6 +4528,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4099,41 +4582,15 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } - - static const uint64_t round_consts[80] = { - 0x428A2F98D728AE22L, 0x7137449123EF65CDL, 0xB5C0FBCFEC4D3B2FL, - 0xE9B5DBA58189DBBCL, 0x3956C25BF348B538L, 0x59F111F1B605D019L, - 0x923F82A4AF194F9BL, 0xAB1C5ED5DA6D8118L, 0xD807AA98A3030242L, - 0x12835B0145706FBEL, 0x243185BE4EE4B28CL, 0x550C7DC3D5FFB4E2L, - 0x72BE5D74F27B896FL, 0x80DEB1FE3B1696B1L, 0x9BDC06A725C71235L, - 0xC19BF174CF692694L, 0xE49B69C19EF14AD2L, 0xEFBE4786384F25E3L, - 0x0FC19DC68B8CD5B5L, 0x240CA1CC77AC9C65L, 0x2DE92C6F592B0275L, - 0x4A7484AA6EA6E483L, 0x5CB0A9DCBD41FBD4L, 0x76F988DA831153B5L, - 0x983E5152EE66DFABL, 0xA831C66D2DB43210L, 0xB00327C898FB213FL, - 0xBF597FC7BEEF0EE4L, 0xC6E00BF33DA88FC2L, 0xD5A79147930AA725L, - 0x06CA6351E003826FL, 0x142929670A0E6E70L, 0x27B70A8546D22FFCL, - 0x2E1B21385C26C926L, 0x4D2C6DFC5AC42AEDL, 0x53380D139D95B3DFL, - 0x650A73548BAF63DEL, 0x766A0ABB3C77B2A8L, 0x81C2C92E47EDAEE6L, - 0x92722C851482353BL, 0xA2BFE8A14CF10364L, 0xA81A664BBC423001L, - 0xC24B8B70D0F89791L, 0xC76C51A30654BE30L, 0xD192E819D6EF5218L, - 0xD69906245565A910L, 0xF40E35855771202AL, 0x106AA07032BBD1B8L, - 0x19A4C116B8D2D0C8L, 0x1E376C085141AB53L, 0x2748774CDF8EEB99L, - 0x34B0BCB5E19B48A8L, 0x391C0CB3C5C95A63L, 0x4ED8AA4AE3418ACBL, - 0x5B9CCA4F7763E373L, 0x682E6FF3D6B2B8A3L, 0x748F82EE5DEFB2FCL, - 0x78A5636F43172F60L, 0x84C87814A1F0AB72L, 0x8CC702081A6439ECL, - 0x90BEFFFA23631E28L, 0xA4506CEBDE82BDE9L, 0xBEF9A3F7B2C67915L, - 0xC67178F2E372532BL, 0xCA273ECEEA26619CL, 0xD186B8C721C0C207L, - 0xEADA7DD6CDE0EB1EL, 0xF57D4F7FEE6ED178L, 0x06F067AA72176FBAL, - 0x0A637DC5A2C898A6L, 0x113F9804BEF90DAEL, 0x1B710B35131C471BL, - 0x28DB77F523047D84L, 0x32CAAB7B40C72493L, 0x3C9EBE0A15C9BEBCL, - 0x431D67C49C100D4CL, 0x4CC5D4BECB3E42B6L, 0x597F299CFC657E2AL, - 0x5FCB6FAB3AD6FAECL, 0x6C44198C4A475817L - }; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -4151,7 +4608,7 @@ class StubGenerator: public StubCodeGenerator { __ ld1(v8, v9, v10, v11, __ T2D, state); // load first 4 round constants - __ lea(rscratch1, ExternalAddress((address)round_consts)); + __ lea(rscratch1, ExternalAddress((address)_sha512_round_consts)); __ ld1(v20, v21, v22, v23, __ T2D, __ post(rscratch1, 64)); __ BIND(sha512_loop); @@ -4236,6 +4693,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4349,22 +4809,15 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } - - static const uint64_t round_consts[24] = { - 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, - 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, - 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, - 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, - 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, - 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, - 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, - 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L - }; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); - StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -4396,7 +4849,7 @@ class StubGenerator: public StubCodeGenerator { __ movw(rscratch2, 24); // load round_constants base - __ lea(rscratch1, ExternalAddress((address) round_consts)); + __ lea(rscratch1, ExternalAddress((address) _sha3_round_consts)); // load input __ ld1(v25, v26, v27, v28, __ T8B, __ post(buf, 32)); @@ -4488,6 +4941,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4495,22 +4951,18 @@ class StubGenerator: public StubCodeGenerator { // c_rarg0 - long[] state0 // c_rarg1 - long[] state1 address generate_double_keccak() { - static const uint64_t round_consts[24] = { - 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, - 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, - 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, - 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, - 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, - 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, - 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, - 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L - }; - + StubId stub_id = StubId::stubgen_double_keccak_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } // Implements the double_keccak() method of the // sun.secyrity.provider.SHA3Parallel class __ align(CodeEntryAlignment); - StubCodeMark mark(this, "StubRoutines", "double_keccak"); - address start = __ pc(); + StubCodeMark mark(this, stub_id); + start = __ pc(); __ enter(); Register state0 = c_rarg0; @@ -4546,7 +4998,7 @@ class StubGenerator: public StubCodeGenerator { __ movw(rscratch2, 24); // load round_constants base - __ lea(rscratch1, ExternalAddress((address) round_consts)); + __ lea(rscratch1, ExternalAddress((address) _double_keccak_round_consts)); __ BIND(rounds24_loop); __ subw(rscratch2, rscratch2, 1); @@ -4578,6 +5030,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4611,11 +5066,17 @@ class StubGenerator: public StubCodeGenerator { // vectors write their first lane back to the keystream buffer, followed // by the second lane from all vectors and so on. address generate_chacha20Block_blockpar() { + StubId stub_id = StubId::stubgen_chacha20Block_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Label L_twoRounds, L_cc20_const; __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_chacha20Block_id; StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); int i, j; @@ -4770,6 +5231,9 @@ class StubGenerator: public StubCodeGenerator { __ emit_int64(0x0605040702010003UL); __ emit_int64(0x0E0D0C0F0A09080BUL); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -5258,11 +5722,16 @@ class StubGenerator: public StubCodeGenerator { // coeffs (short[256]) = c_rarg0 // ntt_zetas (short[256]) = c_rarg1 address generate_kyberNtt() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -5486,6 +5955,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -5496,11 +5968,16 @@ class StubGenerator: public StubCodeGenerator { // coeffs (short[256]) = c_rarg0 // ntt_zetas (short[256]) = c_rarg1 address generate_kyberInverseNtt() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberInverseNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -5770,6 +6247,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -5783,11 +6263,16 @@ class StubGenerator: public StubCodeGenerator { // nttb (short[256]) = c_rarg2 // zetas (short[128]) = c_rarg3 address generate_kyberNttMult() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberNttMult_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -5889,6 +6374,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -5900,11 +6388,16 @@ class StubGenerator: public StubCodeGenerator { // a (short[256]) = c_rarg1 // b (short[256]) = c_rarg2 address generate_kyberAddPoly_2() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberAddPoly_2_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -5973,6 +6466,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -5985,11 +6481,16 @@ class StubGenerator: public StubCodeGenerator { // b (short[256]) = c_rarg2 // c (short[256]) = c_rarg3 address generate_kyberAddPoly_3() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberAddPoly_3_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -6072,6 +6573,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6092,12 +6596,18 @@ class StubGenerator: public StubCodeGenerator { // parsed (short[]) = c_rarg2 // parsedLength = c_rarg3 address generate_kyber12To16() { + StubId stub_id = StubId::stubgen_kyber12To16_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Label L_F00, L_loop; __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_kyber12To16_id; StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register condensed = c_rarg0; @@ -6225,6 +6735,9 @@ class StubGenerator: public StubCodeGenerator { __ emit_int64(0x0f000f000f000f00); __ emit_int64(0x0f000f000f000f00); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6234,11 +6747,16 @@ class StubGenerator: public StubCodeGenerator { // // coeffs (short[256]) = c_rarg0 address generate_kyberBarrettReduce() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberBarrettReduce_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -6318,6 +6836,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6481,11 +7002,16 @@ class StubGenerator: public StubCodeGenerator { // coeffs (int[256]) = c_rarg0 // zetas (int[256]) = c_rarg1 address generate_dilithiumAlmostNtt() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumAlmostNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -6596,6 +7122,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6688,11 +7217,16 @@ class StubGenerator: public StubCodeGenerator { // coeffs (int[256]) = c_rarg0 // zetas (int[256]) = c_rarg1 address generate_dilithiumAlmostInverseNtt() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumAlmostInverseNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -6788,6 +7322,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6801,11 +7338,16 @@ class StubGenerator: public StubCodeGenerator { // poly1 (int[256]) = c_rarg1 // poly2 (int[256]) = c_rarg2 address generate_dilithiumNttMult() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumNttMult_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); Label L_loop; @@ -6854,6 +7396,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6865,11 +7410,16 @@ class StubGenerator: public StubCodeGenerator { // coeffs (int[256]) = c_rarg0 // constant (int) = c_rarg1 address generate_dilithiumMontMulByConstant() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumMontMulByConstant_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); Label L_loop; @@ -6915,6 +7465,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -6929,11 +7482,16 @@ class StubGenerator: public StubCodeGenerator { // twoGamma2 (int) = c_rarg3 // multiplier (int) = c_rarg4 address generate_dilithiumDecomposePoly() { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumDecomposePoly_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_loop; const Register input = c_rarg0; @@ -7073,6 +7631,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(r0, zr); // return 0 __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7212,21 +7773,15 @@ class StubGenerator: public StubCodeGenerator { default: ShouldNotReachHere(); } - - static const uint64_t round_consts[24] = { - 0x0000000000000001L, 0x0000000000008082L, 0x800000000000808AL, - 0x8000000080008000L, 0x000000000000808BL, 0x0000000080000001L, - 0x8000000080008081L, 0x8000000000008009L, 0x000000000000008AL, - 0x0000000000000088L, 0x0000000080008009L, 0x000000008000000AL, - 0x000000008000808BL, 0x800000000000008BL, 0x8000000000008089L, - 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, - 0x000000000000800AL, 0x800000008000000AL, 0x8000000080008081L, - 0x8000000000008080L, 0x0000000080000001L, 0x8000000080008008L - }; - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -7378,7 +7933,7 @@ class StubGenerator: public StubCodeGenerator { __ fmovs(v1, 1.0); // exact representation __ str(buf, Address(sp, 16)); - __ lea(tmp3, ExternalAddress((address) round_consts)); + __ lea(tmp3, ExternalAddress((address) _sha3_round_consts)); __ BIND(loop_body); keccak_round_gpr(can_use_fp, can_use_r18, tmp3, @@ -7433,6 +7988,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7449,12 +8007,17 @@ class StubGenerator: public StubCodeGenerator { */ address generate_updateBytesCRC32() { assert(UseCRC32Intrinsics, "what are we doing here?"); - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesCRC32_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register crc = c_rarg0; // crc const Register buf = c_rarg1; // source java byte array address @@ -7474,6 +8037,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7491,12 +8057,17 @@ class StubGenerator: public StubCodeGenerator { */ address generate_updateBytesCRC32C() { assert(UseCRC32CIntrinsics, "what are we doing here?"); - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesCRC32C_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register crc = c_rarg0; // crc const Register buf = c_rarg1; // source java byte array address @@ -7516,6 +8087,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7531,10 +8105,16 @@ class StubGenerator: public StubCodeGenerator { * c_rarg0 - int adler result */ address generate_updateBytesAdler32() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesAdler32_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_simple_by1_loop, L_nmax, L_nmax_loop, L_by16, L_by16_loop, L_by1_loop, L_do_mod, L_combine, L_by1; @@ -7702,6 +8282,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7753,11 +8336,17 @@ class StubGenerator: public StubCodeGenerator { * c_rarg4 - z address */ address generate_multiplyToLen() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_multiplyToLen_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register x = r0; const Register xlen = r1; const Register y = r2; @@ -7779,6 +8368,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7786,10 +8378,16 @@ class StubGenerator: public StubCodeGenerator { // squareToLen algorithm for sizes 1..127 described in java code works // faster than multiply_to_len on some CPUs and slower on others, but // multiply_to_len shows a bit better overall results - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_squareToLen_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register x = r0; const Register xlen = r1; @@ -7816,15 +8414,25 @@ class StubGenerator: public StubCodeGenerator { __ pop(spilled_regs, sp); __ leave(); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address generate_mulAdd() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_mulAdd_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register out = r0; const Register in = r1; @@ -7838,6 +8446,9 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7851,10 +8462,16 @@ class StubGenerator: public StubCodeGenerator { // c_rarg4 - numIter // address generate_bigIntegerRightShift() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit; @@ -7961,6 +8578,9 @@ class StubGenerator: public StubCodeGenerator { __ BIND(Exit); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -7974,10 +8594,16 @@ class StubGenerator: public StubCodeGenerator { // c_rarg4 - numIter // address generate_bigIntegerLeftShift() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_bigIntegerLeftShiftWorker_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label ShiftSIMDLoop, ShiftTwoLoop, ShiftThree, ShiftTwo, ShiftOne, Exit; @@ -8072,10 +8698,25 @@ class StubGenerator: public StubCodeGenerator { __ BIND(Exit); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address generate_count_positives(address &count_positives_long) { + StubId stub_id = StubId::stubgen_count_positives_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + // We have an extra entry for count_positives_long. + assert(entry_count == 2, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == 1, + "unexpected extra entry count %d", entries.length()); + count_positives_long = entries.at(0); + return start; + } const u1 large_loop_size = 64; const uint64_t UPPER_BIT_MASK=0x8080808080808080; int dcache_line = VM_Version::dcache_line_size(); @@ -8083,8 +8724,6 @@ class StubGenerator: public StubCodeGenerator { Register ary1 = r1, len = r2, result = r0; __ align(CodeEntryAlignment); - - StubId stub_id = StubId::stubgen_count_positives_id; StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -8127,6 +8766,7 @@ class StubGenerator: public StubCodeGenerator { const RegSet spilled_regs = RegSet::range(tmp1, tmp5) + tmp6; count_positives_long = __ pc(); // 2nd entry point + entries.append(count_positives_long); __ enter(); @@ -8241,6 +8881,9 @@ class StubGenerator: public StubCodeGenerator { __ sub(result, result, len); __ ret(lr); + // record the stub entry and end plus the extra entry + store_archive_data(stub_id, entry, __ pc(), &entries); + return entry; } @@ -8331,6 +8974,13 @@ class StubGenerator: public StubCodeGenerator { // r3-r5 are reserved temporary registers // Clobbers: v0-v7 when UseSIMDForArrayEquals, rscratch1, rscratch2 address generate_large_array_equals() { + StubId stub_id = StubId::stubgen_large_array_equals_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Register a1 = r1, a2 = r2, result = r0, cnt1 = r10, tmp1 = rscratch1, tmp2 = rscratch2, tmp3 = r3, tmp4 = r4, tmp5 = r5, tmp6 = r11, tmp7 = r12, tmp8 = r13; @@ -8346,7 +8996,6 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_large_array_equals_id; StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -8421,6 +9070,10 @@ class StubGenerator: public StubCodeGenerator { __ bind(NOT_EQUAL_NO_POP); __ leave(); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -8429,6 +9082,33 @@ class StubGenerator: public StubCodeGenerator { // cnt = r2 - elements count // Clobbers: v0-v13, rscratch1, rscratch2 address generate_large_arrays_hashcode(BasicType eltype) { + StubId stub_id; + switch (eltype) { + case T_BOOLEAN: + stub_id = StubId::stubgen_large_arrays_hashcode_boolean_id; + break; + case T_BYTE: + stub_id = StubId::stubgen_large_arrays_hashcode_byte_id; + break; + case T_CHAR: + stub_id = StubId::stubgen_large_arrays_hashcode_char_id; + break; + case T_SHORT: + stub_id = StubId::stubgen_large_arrays_hashcode_short_id; + break; + case T_INT: + stub_id = StubId::stubgen_large_arrays_hashcode_int_id; + break; + default: + stub_id = StubId::NO_STUBID; + ShouldNotReachHere(); + }; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } const Register result = r0, ary = r1, cnt = r2; const FloatRegister vdata0 = v3, vdata1 = v2, vdata2 = v1, vdata3 = v0; const FloatRegister vmul0 = v4, vmul1 = v5, vmul2 = v6, vmul3 = v7; @@ -8472,28 +9152,6 @@ class StubGenerator: public StubCodeGenerator { __ align(CodeEntryAlignment); - StubId stub_id; - switch (eltype) { - case T_BOOLEAN: - stub_id = StubId::stubgen_large_arrays_hashcode_boolean_id; - break; - case T_BYTE: - stub_id = StubId::stubgen_large_arrays_hashcode_byte_id; - break; - case T_CHAR: - stub_id = StubId::stubgen_large_arrays_hashcode_char_id; - break; - case T_SHORT: - stub_id = StubId::stubgen_large_arrays_hashcode_short_id; - break; - case T_INT: - stub_id = StubId::stubgen_large_arrays_hashcode_int_id; - break; - default: - stub_id = StubId::NO_STUBID; - ShouldNotReachHere(); - }; - StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -8728,19 +9386,32 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } address generate_dsin_dcos(bool isCos) { - __ align(CodeEntryAlignment); StubId stub_id = (isCos ? StubId::stubgen_dcos_id : StubId::stubgen_dsin_id); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ generate_dsin_dcos(isCos, (address)StubRoutines::aarch64::_npio2_hw, (address)StubRoutines::aarch64::_two_over_pi, (address)StubRoutines::aarch64::_pio2, (address)StubRoutines::aarch64::_dsin_coef, (address)StubRoutines::aarch64::_dcos_coef); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -8784,8 +9455,14 @@ class StubGenerator: public StubCodeGenerator { // r10 = tmp1 // r11 = tmp2 address generate_compare_long_string_different_encoding(bool isLU) { - __ align(CodeEntryAlignment); StubId stub_id = (isLU ? StubId::stubgen_compare_long_string_LU_id : StubId::stubgen_compare_long_string_UL_id); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); Label SMALL_LOOP, TAIL, TAIL_LOAD_16, LOAD_LAST, DIFF1, DIFF2, @@ -8887,20 +9564,34 @@ class StubGenerator: public StubCodeGenerator { __ subw(result, tmp1, rscratch1); __ bind(DONE); __ ret(lr); - return entry; + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + + return entry; } // r0 = input (float16) // v0 = result (float) // v1 = temporary float register address generate_float16ToFloat() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_hf2f_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); BLOCK_COMMENT("Entry:"); __ flt16_to_flt(v0, r0, v1); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -8908,24 +9599,40 @@ class StubGenerator: public StubCodeGenerator { // r0 = result (float16) // v1 = temporary float register address generate_floatToFloat16() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_f2hf_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); BLOCK_COMMENT("Entry:"); __ flt_to_flt16(r0, v0, v1); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } address generate_method_entry_barrier() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_method_entry_barrier_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label deoptimize_label; - address start = __ pc(); + start = __ pc(); BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler(); @@ -8974,6 +9681,9 @@ class StubGenerator: public StubCodeGenerator { __ mov(sp, rscratch1); __ br(rscratch2); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -8985,8 +9695,14 @@ class StubGenerator: public StubCodeGenerator { // r10 = tmp1 // r11 = tmp2 address generate_compare_long_string_same_encoding(bool isLL) { - __ align(CodeEntryAlignment); StubId stub_id = (isLL ? StubId::stubgen_compare_long_string_LL_id : StubId::stubgen_compare_long_string_UU_id); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4, @@ -9094,6 +9810,10 @@ class StubGenerator: public StubCodeGenerator { __ bind(LENGTH_DIFF); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -9125,8 +9845,14 @@ class StubGenerator: public StubCodeGenerator { case UU: stub_id = StubId::stubgen_compare_long_string_UU_id; break; default: ShouldNotReachHere(); } - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); address entry = __ pc(); Register result = r0, str1 = r1, cnt1 = r2, str2 = r3, cnt2 = r4, tmp1 = r10, tmp2 = r11; @@ -9161,8 +9887,6 @@ class StubGenerator: public StubCodeGenerator { ShouldNotReachHere(); \ } - StubCodeMark mark(this, stub_id); - __ mov(idx, 0); __ sve_whilelt(pgtmp1, mode == LL ? __ B : __ H, idx, cnt); @@ -9206,6 +9930,10 @@ class StubGenerator: public StubCodeGenerator { __ bind(DONE); __ ret(lr); #undef LOAD_PAIR + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -9267,6 +9995,12 @@ class StubGenerator: public StubCodeGenerator { stub_id = StubId::stubgen_string_indexof_linear_uu_id; } } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); @@ -9535,6 +10269,10 @@ class StubGenerator: public StubCodeGenerator { __ BIND(DONE); __ pop(spilled_regs, sp); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -9565,8 +10303,14 @@ class StubGenerator: public StubCodeGenerator { // v1 = loaded 8 bytes // Clobbers: r0, r1, r3, rscratch1, rflags, v0-v6 address generate_large_byte_array_inflate() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_large_byte_array_inflate_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); address entry = __ pc(); Label LOOP, LOOP_START, LOOP_PRFM, LOOP_PRFM_START, DONE; @@ -9605,6 +10349,10 @@ class StubGenerator: public StubCodeGenerator { __ br(__ GE, LOOP); __ bind(DONE); __ ret(lr); + + // record the stub entry and end + store_archive_data(stub_id, entry, __ pc()); + return entry; } @@ -9620,7 +10368,7 @@ class StubGenerator: public StubCodeGenerator { * Output: * Updated state at c_rarg0 */ - address generate_ghash_processBlocks() { + address generate_ghash_processBlocks_small() { // Bafflingly, GCM uses little-endian for the byte order, but // big-endian for the bit order. For example, the polynomial 1 is // represented as the 16-byte string 80 00 00 00 | 12 bytes of 00. @@ -9632,11 +10380,17 @@ class StubGenerator: public StubCodeGenerator { // that) and keep the data in little-endian bit order through the // calculation, bit-reversing the inputs and outputs. - StubId stub_id = StubId::stubgen_ghash_processBlocks_id; + StubId stub_id = StubId::stubgen_ghash_processBlocks_small_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label polynomial; // local data generated at end of stub - __ align(CodeEntryAlignment); - address start = __ pc(); + start = __ pc(); Register state = c_rarg0; Register subkeyH = c_rarg1; @@ -9696,17 +10450,24 @@ class StubGenerator: public StubCodeGenerator { // 128-bit vector __ emit_int64(0x87); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } - address generate_ghash_processBlocks_wide() { - address small = generate_ghash_processBlocks(); - - StubId stub_id = StubId::stubgen_ghash_processBlocks_wide_id; - StubCodeMark mark(this, stub_id); + address generate_ghash_processBlocks(address small) { + StubId stub_id = StubId::stubgen_ghash_processBlocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } Label polynomial; // local data generated after stub __ align(CodeEntryAlignment); - address start = __ pc(); + StubCodeMark mark(this, stub_id); + start = __ pc(); Register state = c_rarg0; Register subkeyH = c_rarg1; @@ -9748,8 +10509,10 @@ class StubGenerator: public StubCodeGenerator { // 128-bit vector __ emit_int64(0x87); - return start; + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } void generate_base64_encode_simdround(Register src, Register dst, @@ -9800,26 +10563,16 @@ class StubGenerator: public StubCodeGenerator { */ address generate_base64_encodeBlock() { - static const char toBase64[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' - }; - - static const char toBase64URL[64] = { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_' - }; - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_base64_encodeBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register src = c_rarg0; // source array Register soff = c_rarg1; // source start offset @@ -9839,9 +10592,9 @@ class StubGenerator: public StubCodeGenerator { __ sub(length, send, soff); // load the codec base address - __ lea(codec, ExternalAddress((address) toBase64)); + __ lea(codec, ExternalAddress((address) _encodeBlock_toBase64)); __ cbz(isURL, ProcessData); - __ lea(codec, ExternalAddress((address) toBase64URL)); + __ lea(codec, ExternalAddress((address) _encodeBlock_toBase64URL)); __ BIND(ProcessData); @@ -9894,6 +10647,9 @@ class StubGenerator: public StubCodeGenerator { __ BIND(Exit); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10015,80 +10771,16 @@ class StubGenerator: public StubCodeGenerator { // on http://0x80.pl/articles/base64-simd-neon.html#encoding-quadwords, in section // titled "Base64 decoding". - // Non-SIMD lookup tables are mostly dumped from fromBase64 array used in java.util.Base64, - // except the trailing character '=' is also treated illegal value in this intrinsic. That - // is java.util.Base64.fromBase64['='] = -2, while fromBase(URL)64ForNoSIMD['='] = 255 here. - static const uint8_t fromBase64ForNoSIMD[256] = { - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, 255u, 63u, - 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, - 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, 255u, - 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, - 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - }; - - static const uint8_t fromBase64URLForNoSIMD[256] = { - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, - 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, 14u, - 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, 63u, - 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, 40u, - 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - }; - - // A legal value of base64 code is in range [0, 127]. We need two lookups - // with tbl/tbx and combine them to get the decode data. The 1st table vector - // lookup use tbl, out of range indices are set to 0 in destination. The 2nd - // table vector lookup use tbx, out of range indices are unchanged in - // destination. Input [64..126] is mapped to index [65, 127] in second lookup. - // The value of index 64 is set to 0, so that we know that we already get the - // decoded data with the 1st lookup. - static const uint8_t fromBase64ForSIMD[128] = { - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, 255u, 63u, - 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, - 0u, 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, - 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, - 255u, 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, - 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, - }; - - static const uint8_t fromBase64URLForSIMD[128] = { - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, - 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 255u, 62u, 255u, 255u, - 52u, 53u, 54u, 55u, 56u, 57u, 58u, 59u, 60u, 61u, 255u, 255u, 255u, 255u, 255u, 255u, - 0u, 255u, 0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 13u, - 14u, 15u, 16u, 17u, 18u, 19u, 20u, 21u, 22u, 23u, 24u, 25u, 255u, 255u, 255u, 255u, - 63u, 255u, 26u, 27u, 28u, 29u, 30u, 31u, 32u, 33u, 34u, 35u, 36u, 37u, 38u, 39u, - 40u, 41u, 42u, 43u, 44u, 45u, 46u, 47u, 48u, 49u, 50u, 51u, 255u, 255u, 255u, 255u, - }; - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_base64_decodeBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register src = c_rarg0; // source array Register soff = c_rarg1; // source start offset @@ -10115,9 +10807,9 @@ class StubGenerator: public StubCodeGenerator { __ sub(length, send, soff); __ bfm(length, zr, 0, 1); - __ lea(nosimd_codec, ExternalAddress((address) fromBase64ForNoSIMD)); + __ lea(nosimd_codec, ExternalAddress((address) _decodeBlock_fromBase64ForNoSIMD)); __ cbz(isURL, ProcessData); - __ lea(nosimd_codec, ExternalAddress((address) fromBase64URLForNoSIMD)); + __ lea(nosimd_codec, ExternalAddress((address) _decodeBlock_fromBase64URLForNoSIMD)); __ BIND(ProcessData); __ mov(rscratch1, length); @@ -10162,9 +10854,9 @@ class StubGenerator: public StubCodeGenerator { __ cbzw(rscratch1, Exit); __ sub(length, length, 80); - __ lea(simd_codec, ExternalAddress((address) fromBase64ForSIMD)); + __ lea(simd_codec, ExternalAddress((address) _decodeBlock_fromBase64ForSIMD)); __ cbz(isURL, SIMDEnter); - __ lea(simd_codec, ExternalAddress((address) fromBase64URLForSIMD)); + __ lea(simd_codec, ExternalAddress((address) _decodeBlock_fromBase64URLForSIMD)); __ BIND(SIMDEnter); __ ld1(v0, v1, v2, v3, __ T16B, __ post(simd_codec, 64)); @@ -10197,24 +10889,50 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // Support for spin waits. address generate_spin_wait() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_spin_wait_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ spin_wait(); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } void generate_lookup_secondary_supers_table_stub() { StubId stub_id = StubId::stubgen_lookup_secondary_supers_table_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == Klass::SECONDARY_SUPERS_TABLE_SIZE, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == Klass::SECONDARY_SUPERS_TABLE_SIZE - 1, + "unexpected extra entry count %d", entries.length()); + StubRoutines::_lookup_secondary_supers_table_stubs[0] = start; + for (int slot = 1; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = entries.at(slot - 1); + } + return; + } + StubCodeMark mark(this, stub_id); const Register @@ -10229,7 +10947,13 @@ class StubGenerator: public StubCodeGenerator { vtemp = v0; for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + address next_entry = __ pc(); + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = next_entry; + if (slot == 0) { + start = next_entry; + } else { + entries.append(next_entry); + } Label L_success; __ enter(); __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, @@ -10239,14 +10963,21 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); } + // record the stub entry and end plus all the auxiliary entries + store_archive_data(stub_id, start, __ pc(), &entries); } // Slow path implementation for UseSecondarySupersTable. address generate_lookup_secondary_supers_table_slow_path_stub() { StubId stub_id = StubId::stubgen_lookup_secondary_supers_table_slow_path_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - - address start = __ pc(); + start = __ pc(); const Register r_super_klass = r0, // argument r_array_base = r1, // argument @@ -10258,6 +10989,9 @@ class StubGenerator: public StubCodeGenerator { __ lookup_secondary_supers_table_slow_path(r_super_klass, r_array_base, r_array_index, r_bitmap, temp1, result); __ ret(lr); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10397,14 +11131,43 @@ class StubGenerator: public StubCodeGenerator { if (! UseLSE) { return; } - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_atomic_entry_points_id; - StubCodeMark mark(this, stub_id); - address first_entry = __ pc(); + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == entry_count - 1, + "unexpected extra entry count %d", entries.length()); + aarch64_atomic_fetch_add_4_impl = (aarch64_atomic_stub_t)start; + int idx = 0; + aarch64_atomic_fetch_add_8_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_fetch_add_4_relaxed_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_fetch_add_8_relaxed_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_xchg_4_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_xchg_8_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_1_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_4_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_8_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_1_relaxed_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_4_relaxed_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_8_relaxed_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_4_release_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_8_release_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_4_seq_cst_impl = (aarch64_atomic_stub_t)entries.at(idx++); + aarch64_atomic_cmpxchg_8_seq_cst_impl = (aarch64_atomic_stub_t)entries.at(idx++); + assert(idx == entries.length(), "sanity!"); + return; + } + __ align(CodeEntryAlignment); + StubCodeMark mark(this, stub_id); + start = __ pc(); + address end; + { // ADD, memory_order_conservative AtomicStubMark mark_fetch_add_4(_masm, &aarch64_atomic_fetch_add_4_impl); gen_ldadd_entry(Assembler::word, memory_order_conservative); + AtomicStubMark mark_fetch_add_8(_masm, &aarch64_atomic_fetch_add_8_impl); gen_ldadd_entry(Assembler::xword, memory_order_conservative); @@ -10412,6 +11175,7 @@ class StubGenerator: public StubCodeGenerator { AtomicStubMark mark_fetch_add_4_relaxed (_masm, &aarch64_atomic_fetch_add_4_relaxed_impl); gen_ldadd_entry(MacroAssembler::word, memory_order_relaxed); + AtomicStubMark mark_fetch_add_8_relaxed (_masm, &aarch64_atomic_fetch_add_8_relaxed_impl); gen_ldadd_entry(MacroAssembler::xword, memory_order_relaxed); @@ -10419,14 +11183,17 @@ class StubGenerator: public StubCodeGenerator { // XCHG, memory_order_conservative AtomicStubMark mark_xchg_4(_masm, &aarch64_atomic_xchg_4_impl); gen_swpal_entry(Assembler::word); - AtomicStubMark mark_xchg_8_impl(_masm, &aarch64_atomic_xchg_8_impl); + + AtomicStubMark mark_xchg_8(_masm, &aarch64_atomic_xchg_8_impl); gen_swpal_entry(Assembler::xword); // CAS, memory_order_conservative AtomicStubMark mark_cmpxchg_1(_masm, &aarch64_atomic_cmpxchg_1_impl); gen_cas_entry(MacroAssembler::byte, memory_order_conservative); + AtomicStubMark mark_cmpxchg_4(_masm, &aarch64_atomic_cmpxchg_4_impl); gen_cas_entry(MacroAssembler::word, memory_order_conservative); + AtomicStubMark mark_cmpxchg_8(_masm, &aarch64_atomic_cmpxchg_8_impl); gen_cas_entry(MacroAssembler::xword, memory_order_conservative); @@ -10434,9 +11201,11 @@ class StubGenerator: public StubCodeGenerator { AtomicStubMark mark_cmpxchg_1_relaxed (_masm, &aarch64_atomic_cmpxchg_1_relaxed_impl); gen_cas_entry(MacroAssembler::byte, memory_order_relaxed); + AtomicStubMark mark_cmpxchg_4_relaxed (_masm, &aarch64_atomic_cmpxchg_4_relaxed_impl); gen_cas_entry(MacroAssembler::word, memory_order_relaxed); + AtomicStubMark mark_cmpxchg_8_relaxed (_masm, &aarch64_atomic_cmpxchg_8_relaxed_impl); gen_cas_entry(MacroAssembler::xword, memory_order_relaxed); @@ -10444,6 +11213,7 @@ class StubGenerator: public StubCodeGenerator { AtomicStubMark mark_cmpxchg_4_release (_masm, &aarch64_atomic_cmpxchg_4_release_impl); gen_cas_entry(MacroAssembler::word, memory_order_release); + AtomicStubMark mark_cmpxchg_8_release (_masm, &aarch64_atomic_cmpxchg_8_release_impl); gen_cas_entry(MacroAssembler::xword, memory_order_release); @@ -10451,11 +11221,41 @@ class StubGenerator: public StubCodeGenerator { AtomicStubMark mark_cmpxchg_4_seq_cst (_masm, &aarch64_atomic_cmpxchg_4_seq_cst_impl); gen_cas_entry(MacroAssembler::word, memory_order_seq_cst); + AtomicStubMark mark_cmpxchg_8_seq_cst (_masm, &aarch64_atomic_cmpxchg_8_seq_cst_impl); gen_cas_entry(MacroAssembler::xword, memory_order_seq_cst); - ICache::invalidate_range(first_entry, __ pc() - first_entry); + end = __ pc(); + + ICache::invalidate_range(start, end - start); + // exit block to force update of AtomicStubMark targets + } + + assert(start == (address)aarch64_atomic_fetch_add_4_impl, + "atomic stub should be at start of buffer"); + // record the stub start and end plus all the entries saved by the + // AtomicStubMark destructor + entries.append((address)aarch64_atomic_fetch_add_8_impl); + entries.append((address)aarch64_atomic_fetch_add_4_relaxed_impl); + entries.append((address)aarch64_atomic_fetch_add_8_relaxed_impl); + entries.append((address)aarch64_atomic_xchg_4_impl); + entries.append((address)aarch64_atomic_xchg_8_impl); + entries.append((address)aarch64_atomic_cmpxchg_1_impl); + entries.append((address)aarch64_atomic_cmpxchg_4_impl); + entries.append((address)aarch64_atomic_cmpxchg_8_impl); + entries.append((address)aarch64_atomic_cmpxchg_1_relaxed_impl); + entries.append((address)aarch64_atomic_cmpxchg_4_relaxed_impl); + entries.append((address)aarch64_atomic_cmpxchg_8_relaxed_impl); + entries.append((address)aarch64_atomic_cmpxchg_4_release_impl); + entries.append((address)aarch64_atomic_cmpxchg_8_release_impl); + entries.append((address)aarch64_atomic_cmpxchg_4_seq_cst_impl); + entries.append((address)aarch64_atomic_cmpxchg_8_seq_cst_impl); + + assert(entries.length() == entry_count - 1, + "unexpected extra entry count %d", entries.length()); + + store_archive_data(stub_id, start, end, &entries); } #endif // LINUX @@ -10559,9 +11359,19 @@ class StubGenerator: public StubCodeGenerator { if (!Continuations::enabled()) return nullptr; StubId stub_id = StubId::stubgen_cont_thaw_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); generate_cont_thaw(Continuation::thaw_top); + + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10570,11 +11380,20 @@ class StubGenerator: public StubCodeGenerator { // TODO: will probably need multiple return barriers depending on return type StubId stub_id = StubId::stubgen_cont_returnBarrier_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10582,19 +11401,34 @@ class StubGenerator: public StubCodeGenerator { if (!Continuations::enabled()) return nullptr; StubId stub_id = StubId::stubgen_cont_returnBarrierExc_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); generate_cont_thaw(Continuation::thaw_return_barrier_exception); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } address generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; StubId stub_id = StubId::stubgen_cont_preempt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ reset_last_Java_frame(true); @@ -10619,6 +11453,9 @@ class StubGenerator: public StubCodeGenerator { __ ldr(rscratch1, Address(rscratch1)); __ br(rscratch1); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10674,10 +11511,16 @@ class StubGenerator: public StubCodeGenerator { // computation. address generate_poly1305_processBlocks() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_poly1305_processBlocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label here; __ enter(); RegSet callee_saved = RegSet::range(r19, r28); @@ -10785,14 +11628,23 @@ class StubGenerator: public StubCodeGenerator { __ leave(); __ ret(lr); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } // exception handler for upcall stubs address generate_upcall_stub_exception_handler() { StubId stub_id = StubId::stubgen_upcall_stub_exception_handler_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Native caller has no idea how to handle exceptions, // so we just crash here. Up to callee to catch exceptions. @@ -10801,6 +11653,9 @@ class StubGenerator: public StubCodeGenerator { __ blr(rscratch1); __ should_not_reach_here(); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -10809,8 +11664,14 @@ class StubGenerator: public StubCodeGenerator { // rmethod = result address generate_upcall_stub_load_target() { StubId stub_id = StubId::stubgen_upcall_stub_load_target_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ resolve_global_jobject(j_rarg0, rscratch1, rscratch2); // Load target method from receiver @@ -10824,6 +11685,9 @@ class StubGenerator: public StubCodeGenerator { __ ret(lr); + // record the stub start and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -11223,8 +12087,6 @@ class StubGenerator: public StubCodeGenerator { */ address generate_multiply() { Label argh, nothing; - bind(argh); - stop("MontgomeryMultiply total_allocation must be <= 8192"); align(CodeEntryAlignment); address entry = pc(); @@ -11331,6 +12193,10 @@ class StubGenerator: public StubCodeGenerator { bind(nothing); ret(lr); + // handler for error case + bind(argh); + stop("MontgomeryMultiply total_allocation must be <= 8192"); + return entry; } // In C, approximately: @@ -11434,8 +12300,6 @@ class StubGenerator: public StubCodeGenerator { */ address generate_square() { Label argh; - bind(argh); - stop("MontgomeryMultiply total_allocation must be <= 8192"); align(CodeEntryAlignment); address entry = pc(); @@ -11544,6 +12408,10 @@ class StubGenerator: public StubCodeGenerator { leave(); ret(lr); + // handler for error case + bind(argh); + stop("MontgomeryMultiply total_allocation must be <= 8192"); + return entry; } // In C, approximately: @@ -11798,18 +12666,32 @@ class StubGenerator: public StubCodeGenerator { if (UseMontgomeryMultiplyIntrinsic) { StubId stub_id = StubId::stubgen_montgomeryMultiply_id; - StubCodeMark mark(this, stub_id); - MontgomeryMultiplyGenerator g(_masm, /*squaring*/false); - StubRoutines::_montgomeryMultiply = g.generate_multiply(); + address start = load_archive_data(stub_id); + if (start == nullptr) { + // we have to generate it + StubCodeMark mark(this, stub_id); + MontgomeryMultiplyGenerator g(_masm, /*squaring*/false); + start = g.generate_multiply(); + // record the stub start and end + store_archive_data(stub_id, start, _masm->pc()); + } + StubRoutines::_montgomeryMultiply = start; } if (UseMontgomerySquareIntrinsic) { StubId stub_id = StubId::stubgen_montgomerySquare_id; - StubCodeMark mark(this, stub_id); - MontgomeryMultiplyGenerator g(_masm, /*squaring*/true); - // We use generate_multiply() rather than generate_square() - // because it's faster for the sizes of modulus we care about. - StubRoutines::_montgomerySquare = g.generate_multiply(); + address start = load_archive_data(stub_id); + if (start == nullptr) { + // we have to generate it + StubCodeMark mark(this, stub_id); + MontgomeryMultiplyGenerator g(_masm, /*squaring*/true); + // We use generate_multiply() rather than generate_square() + // because it's faster for the sizes of modulus we care about. + start = g.generate_multiply(); + // record the stub start and end + store_archive_data(stub_id, start, _masm->pc()); + } + StubRoutines::_montgomerySquare = start; } #endif // COMPILER2 @@ -11854,7 +12736,8 @@ class StubGenerator: public StubCodeGenerator { } if (UseGHASHIntrinsics) { // StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); - StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks_wide(); + StubRoutines::aarch64::_ghash_processBlocks_small = generate_ghash_processBlocks_small(); + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(StubRoutines::aarch64::_ghash_processBlocks_small); } if (UseAESIntrinsics && UseGHASHIntrinsics) { StubRoutines::_galoisCounterMode_AESCrypt = generate_galoisCounterMode_AESCrypt(); @@ -11898,7 +12781,7 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -11920,12 +12803,35 @@ class StubGenerator: public StubCodeGenerator { break; }; } + +#if INCLUDE_CDS + static void init_AOTAddressTable(GrowableArray& external_addresses) { + // external data defined in this file +#define ADD(addr) external_addresses.append((address)addr); + ADD(_sha256_round_consts); + ADD(_sha512_round_consts); + ADD(_sha3_round_consts); + ADD(_double_keccak_round_consts); + ADD(_encodeBlock_toBase64); + ADD(_encodeBlock_toBase64URL); + ADD(_decodeBlock_fromBase64ForNoSIMD); + ADD(_decodeBlock_fromBase64URLForNoSIMD); + ADD(_decodeBlock_fromBase64ForSIMD); + ADD(_decodeBlock_fromBase64URLForSIMD); +#undef ADD + } +#endif // INCLUDE_CDS }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) { + StubGenerator g(code, blob_id, stub_data); } +#if INCLUDE_CDS +void StubGenerator_init_AOTAddressTable(GrowableArray& addresses) { + StubGenerator::init_AOTAddressTable(addresses); +} +#endif // INCLUDE_CDS #if defined (LINUX) diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp index 88993818b47..35ec22b0897 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp @@ -413,3 +413,39 @@ ATTRIBUTE_ALIGNED(64) jdouble StubRoutines::aarch64::_pio2[] = { 2.73370053816464559624e-44, // 0x36E3822280000000 2.16741683877804819444e-51, // 0x3569F31D00000000 }; + +#if INCLUDE_CDS +extern void StubGenerator_init_AOTAddressTable(GrowableArray& addresses); + +void StubRoutines::init_AOTAddressTable() { + ResourceMark rm; + GrowableArray external_addresses; + // publish static addresses referred to by aarch64 generator + // n.b. we have to use use an extern call here because class + // StubGenerator, which provides the static method that knows how to + // add the relevant addresses, is declared in a source file rather + // than in a separately includeable header. + StubGenerator_init_AOTAddressTable(external_addresses); + // publish external data addresses defined in nested aarch64 class + StubRoutines::aarch64::init_AOTAddressTable(external_addresses); + AOTCodeCache::publish_external_addresses(external_addresses); +} + + +#define ADD(addr) external_addresses.append((address)addr); + +void StubRoutines::aarch64::init_AOTAddressTable(GrowableArray& external_addresses) { + ADD(_kyberConsts); + ADD(_dilithiumConsts); + // this is added in generic code + // ADD(_crc_table); + ADD(_adler_table); + ADD(_npio2_hw); + ADD(_dsin_coef); + ADD(_dcos_coef); + ADD(_two_over_pi); + ADD(_pio2); +} + +#undef ADD +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp index c35371e1083..f77192a3741 100644 --- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp @@ -110,6 +110,11 @@ private: _completed = true; } +#if INCLUDE_CDS + static void init_AOTAddressTable(GrowableArray& external_addresses); +#endif // INCLUDE_CDS + + private: static uint16_t _kyberConsts[]; static uint32_t _dilithiumConsts[]; diff --git a/src/hotspot/cpu/arm/stubGenerator_arm.cpp b/src/hotspot/cpu/arm/stubGenerator_arm.cpp index a36ad3a0c47..a705b15eff5 100644 --- a/src/hotspot/cpu/arm/stubGenerator_arm.cpp +++ b/src/hotspot/cpu/arm/stubGenerator_arm.cpp @@ -3211,7 +3211,7 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -3235,8 +3235,8 @@ class StubGenerator: public StubCodeGenerator { } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) { + StubGenerator g(code, blob_id, stub_data); } // implementation of internal development flag diff --git a/src/hotspot/cpu/arm/stubRoutines_arm.cpp b/src/hotspot/cpu/arm/stubRoutines_arm.cpp index a4f2b5e1bd9..3ed747ea11a 100644 --- a/src/hotspot/cpu/arm/stubRoutines_arm.cpp +++ b/src/hotspot/cpu/arm/stubRoutines_arm.cpp @@ -39,3 +39,9 @@ STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT) address StubRoutines::crc_table_addr() { ShouldNotCallThis(); return nullptr; } address StubRoutines::crc32c_table_addr() { ShouldNotCallThis(); return nullptr; } + +#if INCLUDE_CDS +// nothing to do for arm +void StubRoutines::init_AOTAddressTable() { +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index e48778a8b9f..f528587a8bb 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -5095,7 +5095,7 @@ void generate_lookup_secondary_supers_table_stub() { } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData *stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -5119,7 +5119,7 @@ void generate_lookup_secondary_supers_table_stub() { } }; -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData *stub_data) { + StubGenerator g(code, blob_id, stub_data); } diff --git a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp index 914c5a17a19..3b7ee66348a 100644 --- a/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/stubRoutines_ppc_64.cpp @@ -183,3 +183,9 @@ address StubRoutines::ppc::generate_crc_constants(juint reverse_poly) { return consts; } + +#if INCLUDE_CDS +// nothing to do for ppc +void StubRoutines::init_AOTAddressTable() { +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp index d94bf428fd2..9eb546a1888 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -56,8 +56,10 @@ void CardTableBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet d } } -void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Register tmp) { - assert_different_registers(obj, tmp); +void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2) { + precond(tmp1 != noreg); + precond(tmp2 != noreg); + assert_different_registers(obj, tmp1, tmp2); BarrierSet* bs = BarrierSet::barrier_set(); assert(bs->kind() == BarrierSet::CardTableBarrierSet, "Wrong barrier set kind"); @@ -65,17 +67,17 @@ void CardTableBarrierSetAssembler::store_check(MacroAssembler* masm, Register ob assert(CardTable::dirty_card_val() == 0, "must be"); - __ load_byte_map_base(tmp); - __ add(tmp, obj, tmp); + __ load_byte_map_base(tmp1); + __ add(tmp1, obj, tmp1); if (UseCondCardMark) { Label L_already_dirty; - __ lbu(t1, Address(tmp)); - __ beqz(t1, L_already_dirty); - __ sb(zr, Address(tmp)); + __ lbu(tmp2, Address(tmp1)); + __ beqz(tmp2, L_already_dirty); + __ sb(zr, Address(tmp1)); __ bind(L_already_dirty); } else { - __ sb(zr, Address(tmp)); + __ sb(zr, Address(tmp1)); } } @@ -119,10 +121,10 @@ void CardTableBarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorS if (needs_post_barrier) { // flatten object address if needed if (!precise || dst.offset() == 0) { - store_check(masm, dst.base(), tmp3); + store_check(masm, dst.base(), tmp1, tmp2); } else { __ la(tmp3, dst); - store_check(masm, tmp3, t0); + store_check(masm, tmp3, tmp1, tmp2); } } } diff --git a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp index 6f6e9065103..1576f0a6dd8 100644 --- a/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/gc/shared/cardTableBarrierSetAssembler_riscv.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,7 @@ class CardTableBarrierSetAssembler: public BarrierSetAssembler { protected: - void store_check(MacroAssembler* masm, Register obj, Register tmp); + void store_check(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2); virtual void gen_write_ref_array_pre_barrier(MacroAssembler* masm, DecoratorSet decorators, Register addr, Register count, RegSet saved_regs) {} diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 964c6d98e9c..4656b5c0d41 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -7348,7 +7348,7 @@ static const int64_t right_3_bits = right_n_bits(3); } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -7372,6 +7372,6 @@ static const int64_t right_3_bits = right_n_bits(3); } }; // end class declaration -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) { + StubGenerator g(code, blob_id, stub_data); } diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp index 2aac95d71fa..51e31aa3672 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp @@ -501,3 +501,9 @@ ATTRIBUTE_ALIGNED(4096) juint StubRoutines::riscv::_crc_table[] = 0x751997d0UL, 0x00000001UL, 0xccaa009eUL, 0x00000000UL, }; + +#if INCLUDE_CDS +// nothing to do for riscv +void StubRoutines::init_AOTAddressTable() { +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index 2aa365be999..3f16312eb48 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -3422,7 +3422,7 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -3479,6 +3479,6 @@ class StubGenerator: public StubCodeGenerator { }; -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) { + StubGenerator g(code, blob_id, stub_data); } diff --git a/src/hotspot/cpu/s390/stubRoutines_s390.cpp b/src/hotspot/cpu/s390/stubRoutines_s390.cpp index 6feb20f9604..3db4995338d 100644 --- a/src/hotspot/cpu/s390/stubRoutines_s390.cpp +++ b/src/hotspot/cpu/s390/stubRoutines_s390.cpp @@ -736,3 +736,9 @@ juint StubRoutines::zarch::_crc32c_table[CRC32_TABLES][CRC32_COLUMN_SIZE] = { } #endif }; + +#if INCLUDE_CDS +// nothing to do for s390 +void StubRoutines::init_AOTAddressTable() { +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp index 1242078e11d..29925e71aaf 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp @@ -71,6 +71,17 @@ static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], (jlong)UCONST64(0x8000000080000000), (jlong)UCONST64(0x8000000080000000)); static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], (jlong)UCONST64(0x8000000000000000), (jlong)UCONST64(0x8000000000000000)); +#if INCLUDE_CDS +// publish external addresses defined in this file +void LIR_Assembler::init_AOTAddressTable(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(float_signmask_pool); + ADD(double_signmask_pool); + ADD(float_signflip_pool); + ADD(double_signflip_pool); +#undef ADD +} +#endif // INCLUDE_CDS NEEDS_CLEANUP // remove this definitions ? const Register SYNC_header = rax; // synchronization header @@ -519,6 +530,15 @@ void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_cod } case T_LONG: { +#if INCLUDE_CDS + if (AOTCodeCache::is_on_for_dump()) { + address b = c->as_pointer(); + if (b == (address)ThreadIdentifier::unsafe_offset()) { + __ lea(dest->as_register_lo(), ExternalAddress(b)); + break; + } + } +#endif assert(patch_code == lir_patch_none, "no patching handled here"); #if INCLUDE_CDS if (AOTCodeCache::is_on_for_dump()) { diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.hpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.hpp index c4a368b54d8..6f179255e4a 100644 --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.hpp @@ -58,4 +58,7 @@ public: void store_parameter(jobject c, int offset_from_esp_in_words); void store_parameter(Metadata* c, int offset_from_esp_in_words); +#if INCLUDE_CDS + void static init_AOTAddressTable(GrowableArray& external_addresses); +#endif // INCLUDE_CDS #endif // CPU_X86_C1_LIRASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp index 47a3dad54e7..c20551b5084 100644 --- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp @@ -31,6 +31,7 @@ #include "gc/z/zBarrierSetAssembler.hpp" #include "gc/z/zBarrierSetRuntime.hpp" #include "gc/z/zThreadLocalData.hpp" +#include "logging/log.hpp" #include "memory/resourceArea.hpp" #include "runtime/jniHandles.hpp" #include "runtime/sharedRuntime.hpp" @@ -1391,10 +1392,13 @@ static uint16_t patch_barrier_relocation_value(int format) { } } -void ZBarrierSetAssembler::patch_barrier_relocation(address addr, int format) { +void ZBarrierSetAssembler::patch_barrier_relocation(address addr, int format, bool log) { const int offset = patch_barrier_relocation_offset(format); const uint16_t value = patch_barrier_relocation_value(format); uint8_t* const patch_addr = (uint8_t*)addr + offset; + if (log) { + log_trace(aot, codecache, stubs)("patching address " INTPTR_FORMAT " offset %d value 0x%x", p2i(addr), offset, value); + } if (format == ZBarrierRelocationFormatLoadGoodBeforeShl) { if (VM_Version::supports_apx_f()) { NativeInstruction* instruction = nativeInstruction_at(addr); @@ -1426,6 +1430,74 @@ void ZBarrierSetAssembler::patch_barriers() { #undef __ #define __ masm-> +void ZBarrierSetAssembler::register_reloc_addresses(GrowableArray &entries, int begin, int count) { + int formats[] = { + ZBarrierRelocationFormatLoadBadAfterTest, + ZBarrierRelocationFormatStoreBadAfterTest, + ZBarrierRelocationFormatStoreGoodAfterOr, + -1 + }; + int format_idx = 0; + int format = formats[format_idx++]; + for (int i = begin; i < begin + count; i++) { + address addr = entries.at(i); + // reloc addresses occur in 3 groups terminated with a nullptr + if (addr == nullptr) { + assert(format_idx < (int)(sizeof(formats) / sizeof(formats[0])), + "too many reloc groups"); + format = formats[format_idx++]; + } else { + switch(format) { + case ZBarrierRelocationFormatLoadBadAfterTest: + _load_bad_relocations.append(addr); + break; + case ZBarrierRelocationFormatStoreBadAfterTest: + _store_bad_relocations.append(addr); + break; + case ZBarrierRelocationFormatStoreGoodAfterOr: + _store_good_relocations.append(addr); + break; + default: + ShouldNotReachHere(); + break; + } + patch_barrier_relocation(addr, format, true); + } + } + assert(format == -1, "unterminated format list"); +} + +void ZBarrierSetAssembler::retrieve_reloc_addresses(address start, address end, GrowableArray &entries) { + assert(start != nullptr, "start address must not be null"); + assert(end != nullptr, "start address must not be null"); + assert(start < end, "stub range must not be empty"); + for (int i = 0; i < _load_bad_relocations.length(); i++) { + address addr = _load_bad_relocations.at(i); + assert(addr != nullptr, "load bad reloc address shoudl not be null!"); + if (start <= addr && addr < end) { + entries.append(addr); + } + } + entries.append(nullptr); + for (int i = 0; i < _store_bad_relocations.length(); i++) { + address addr = _store_bad_relocations.at(i); + assert(addr != nullptr, "store bad reloc address shoudl not be null!"); + if (start <= addr && addr < end) { + entries.append(addr); + } + } + entries.append(nullptr); + for (int i = 0; i < _store_good_relocations.length(); i++) { + address addr = _store_good_relocations.at(i); + assert(addr != nullptr, "store good reloc address shoudl not be null!"); + if (start <= addr && addr < end) { + entries.append(addr); + } + } + entries.append(nullptr); +} + + void ZBarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) { // C1 calls verfy_oop in the middle of barriers, before they have been uncolored // and after being colored. Therefore, we must deal with colored oops as well. diff --git a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp index e91e2b9ea20..ce0c4769716 100644 --- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp @@ -189,10 +189,14 @@ public: Label& slow_path, Label& slow_path_continuation) const; - void patch_barrier_relocation(address addr, int format); + void patch_barrier_relocation(address addr, int format, bool log = false); void patch_barriers(); + void register_reloc_addresses(GrowableArray &entries, int begin, int count); + + void retrieve_reloc_addresses(address start, address end, GrowableArray &entries); + void check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error); }; diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 356bf8af5c0..5ab3ca339aa 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -385,7 +385,8 @@ void MacroAssembler::warn(const char* msg) { // Windows always allocates space for its register args subq(rsp, frame::arg_reg_save_area_bytes); #endif - lea(c_rarg0, ExternalAddress((address) msg)); + const char* str = (code_section()->scratch_emit()) ? msg : AOTCodeCache::add_C_string(msg); + lea(c_rarg0, ExternalAddress((address) str)); call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning))); #ifdef _WIN64 @@ -5672,7 +5673,12 @@ void MacroAssembler::encode_and_move_klass_not_null(Register dst, Register src) BLOCK_COMMENT("encode_and_move_klass_not_null {"); assert_different_registers(src, dst); if (CompressedKlassPointers::base() != nullptr) { - movptr(dst, -(intptr_t)CompressedKlassPointers::base()); + if (AOTCodeCache::is_on_for_dump()) { + movptr(dst, ExternalAddress(CompressedKlassPointers::base_addr())); + negq(dst); + } else { + movptr(dst, -(intptr_t)CompressedKlassPointers::base()); + } addq(dst, src); } else { movptr(dst, src); @@ -5720,7 +5726,11 @@ void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) } else { if (CompressedKlassPointers::shift() <= Address::times_8) { if (CompressedKlassPointers::base() != nullptr) { - movptr(dst, (intptr_t)CompressedKlassPointers::base()); + if (AOTCodeCache::is_on_for_dump()) { + movptr(dst, ExternalAddress(CompressedKlassPointers::base_addr())); + } else { + movptr(dst, (intptr_t)CompressedKlassPointers::base()); + } } else { xorq(dst, dst); } @@ -5732,9 +5742,14 @@ void MacroAssembler::decode_and_move_klass_not_null(Register dst, Register src) } } else { if (CompressedKlassPointers::base() != nullptr) { - const intptr_t base_right_shifted = - (intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift(); - movptr(dst, base_right_shifted); + if (AOTCodeCache::is_on_for_dump()) { + movptr(dst, ExternalAddress(CompressedKlassPointers::base_addr())); + shrq(dst, CompressedKlassPointers::shift()); + } else { + const intptr_t base_right_shifted = + (intptr_t)CompressedKlassPointers::base() >> CompressedKlassPointers::shift(); + movptr(dst, base_right_shifted); + } } else { xorq(dst, dst); } @@ -5811,7 +5826,7 @@ void MacroAssembler::cmp_narrow_klass(Address dst, Klass* k) { void MacroAssembler::reinit_heapbase() { if (UseCompressedOops) { - if (Universe::heap() != nullptr) { + if (Universe::heap() != nullptr && !AOTCodeCache::is_on_for_dump()) { if (CompressedOops::base() == nullptr) { MacroAssembler::xorptr(r12_heapbase, r12_heapbase); } else { diff --git a/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp b/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp index 9f0232075cd..401d5dc22cc 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86_sha.cpp @@ -242,7 +242,6 @@ void MacroAssembler::fast_sha256(XMMRegister msg, XMMRegister state0, XMMRegiste Label done_hash, loop0; address K256 = StubRoutines::x86::k256_addr(); - address pshuffle_byte_flip_mask = StubRoutines::x86::pshuffle_byte_flip_mask_addr(); movdqu(state0, Address(state, 0)); movdqu(state1, Address(state, 16)); @@ -253,7 +252,7 @@ void MacroAssembler::fast_sha256(XMMRegister msg, XMMRegister state0, XMMRegiste palignr(state0, state1, 8); pblendw(state1, msgtmp4, 0xF0); - movdqu(shuf_mask, ExternalAddress(pshuffle_byte_flip_mask)); + movdqu(shuf_mask, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_addr())); lea(rax, ExternalAddress(K256)); bind(loop0); @@ -661,8 +660,6 @@ void MacroAssembler::sha256_AVX2(XMMRegister msg, XMMRegister state0, XMMRegiste compute_size1, compute_size_end1; address K256_W = StubRoutines::x86::k256_W_addr(); - address pshuffle_byte_flip_mask = StubRoutines::x86::pshuffle_byte_flip_mask_addr(); - address pshuffle_byte_flip_mask_addr = nullptr; const XMMRegister& SHUF_00BA = xmm10; // ymm10: shuffle xBxA -> 00BA const XMMRegister& SHUF_DC00 = xmm12; // ymm12: shuffle xDxC -> DC00 @@ -791,10 +788,14 @@ enum { // load g - r10 after it is used as scratch movl(h, Address(CTX, 4*7)); - pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask; - vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // [PSHUFFLE_BYTE_FLIP_MASK wrt rip] - vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32)); // [_SHUF_00BA wrt rip] - vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64)); // [_SHUF_DC00 wrt rip] + // the three successive pshuffle_byte_flip_mask stub entries should + // be offset by 32 bytes + assert(StubRoutines::x86::pshuffle_byte_flip_mask_addr() + 32 == StubRoutines::x86::pshuffle_byte_flip_mask_00ba_addr(), "sanity"); + assert(StubRoutines::x86::pshuffle_byte_flip_mask_addr() + 64 == StubRoutines::x86::pshuffle_byte_flip_mask_dc00_addr(), "sanity"); + + vmovdqu(BYTE_FLIP_MASK, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_addr())); // [PSHUFFLE_BYTE_FLIP_MASK wrt rip] + vmovdqu(SHUF_00BA, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_00ba_addr())); // [_SHUF_00BA wrt rip] + vmovdqu(SHUF_DC00, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_dc00_addr())); // [_SHUF_DC00 wrt rip] movl(g, Address(CTX, 4*6)); @@ -953,11 +954,9 @@ bind(only_one_block); // load g - r10 after use as scratch movl(h, Address(CTX, 4*7)); // 0x5be0cd19 - - pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask; - vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // [PSHUFFLE_BYTE_FLIP_MASK wrt rip] - vmovdqu(SHUF_00BA, ExternalAddress(pshuffle_byte_flip_mask_addr + 32)); // [_SHUF_00BA wrt rip] - vmovdqu(SHUF_DC00, ExternalAddress(pshuffle_byte_flip_mask_addr + 64)); // [_SHUF_DC00 wrt rip] + vmovdqu(BYTE_FLIP_MASK, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_addr())); // [PSHUFFLE_BYTE_FLIP_MASK wrt rip] + vmovdqu(SHUF_00BA, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_00ba_addr())); // [_SHUF_00BA wrt rip] + vmovdqu(SHUF_DC00, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_dc00_addr())); // [_SHUF_DC00 wrt rip] movl(g, Address(CTX, 4*6)); // 0x1f83d9ab @@ -1346,9 +1345,12 @@ void MacroAssembler::sha512_AVX2(XMMRegister msg, XMMRegister state0, XMMRegiste // load g - r10 after it is used as scratch movq(h, Address(CTX, 8 * 7)); - pshuffle_byte_flip_mask_addr = pshuffle_byte_flip_mask_sha512; - vmovdqu(BYTE_FLIP_MASK, ExternalAddress(pshuffle_byte_flip_mask_addr + 0)); // PSHUFFLE_BYTE_FLIP_MASK wrt rip - vmovdqu(YMM_MASK_LO, ExternalAddress(pshuffle_byte_flip_mask_addr + 32)); + // the two successive pshuffle_byte_flip_mask_sha512 stub entries should + // be offset by 32 bytes + assert(StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512() + 32 == StubRoutines::x86::pshuffle_byte_flip_mask_ymm_lo_addr_sha512(), "sanity"); + + vmovdqu(BYTE_FLIP_MASK, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_addr_sha512())); // PSHUFFLE_BYTE_FLIP_MASK wrt rip + vmovdqu(YMM_MASK_LO, ExternalAddress(StubRoutines::x86::pshuffle_byte_flip_mask_ymm_lo_addr_sha512())); // MASK_YMM_LO wrt rip movq(g, Address(CTX, 8 * 6)); diff --git a/src/hotspot/cpu/x86/stubDeclarations_x86.hpp b/src/hotspot/cpu/x86/stubDeclarations_x86.hpp index 971c8fd3c44..07a1ab622ed 100644 --- a/src/hotspot/cpu/x86/stubDeclarations_x86.hpp +++ b/src/hotspot/cpu/x86/stubDeclarations_x86.hpp @@ -161,6 +161,12 @@ do_arch_entry(x86, compiler, pshuffle_byte_flip_mask, \ pshuffle_byte_flip_mask_addr, \ pshuffle_byte_flip_mask_addr) \ + do_arch_entry(x86, compiler, pshuffle_byte_flip_mask, \ + pshuffle_byte_flip_mask_00ba_addr, \ + pshuffle_byte_flip_mask_00ba_addr) \ + do_arch_entry(x86, compiler, pshuffle_byte_flip_mask, \ + pshuffle_byte_flip_mask_dc00_addr, \ + pshuffle_byte_flip_mask_dc00_addr) \ /* x86_64 exposes these 3 stubs via a generic entry array */ \ /* other arches use arch-specific entries */ \ /* this really needs rationalising */ \ @@ -171,6 +177,9 @@ do_arch_entry(x86, compiler, pshuffle_byte_flip_mask_sha512, \ pshuffle_byte_flip_mask_addr_sha512, \ pshuffle_byte_flip_mask_addr_sha512) \ + do_arch_entry(x86, compiler, pshuffle_byte_flip_mask_sha512, \ + pshuffle_byte_flip_mask_ymm_lo_addr_sha512, \ + pshuffle_byte_flip_mask_ymm_lo_addr_sha512) \ do_stub(compiler, compress_perm_table32) \ do_arch_entry(x86, compiler, compress_perm_table32, \ compress_perm_table32, compress_perm_table32) \ diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index efb0411aa39..40be816fbf0 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -188,8 +188,18 @@ address StubGenerator::generate_call_stub(address& return_address) { (int)frame::entry_frame_call_wrapper_offset == (int)call_wrapper_off, "adjust this code"); StubId stub_id = StubId::stubgen_call_stub_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 2, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == 1, "expected 1 extra entry"); + return_address = entries.at(0); + return start; + } + StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // same as in generate_catch_exception()! const Address rsp_after_call(rbp, rsp_after_call_off * wordSize); @@ -298,6 +308,7 @@ address StubGenerator::generate_call_stub(address& return_address) { BLOCK_COMMENT("call_stub_return_address:"); return_address = __ pc(); + entries.append(return_address); // store result depending on type (everything that is not // T_OBJECT, T_LONG, T_FLOAT or T_DOUBLE is treated as T_INT) @@ -394,6 +405,9 @@ address StubGenerator::generate_call_stub(address& return_address) { __ movdbl(Address(c_rarg0, 0), xmm0); __ jmp(exit); + // record the stub entry and end plus the auxiliary entry + store_archive_data(stub_id, start, __ pc(), &entries); + return start; } @@ -411,8 +425,15 @@ address StubGenerator::generate_call_stub(address& return_address) { address StubGenerator::generate_catch_exception() { StubId stub_id = StubId::stubgen_catch_exception_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // same as in generate_call_stub(): const Address rsp_after_call(rbp, rsp_after_call_off * wordSize); @@ -442,7 +463,9 @@ address StubGenerator::generate_catch_exception() { __ verify_oop(rax); __ movptr(Address(r15_thread, Thread::pending_exception_offset()), rax); - __ lea(rscratch1, ExternalAddress((address)__FILE__)); + // special case -- add file name string to AOT address table + address file = (address)AOTCodeCache::add_C_string(__FILE__); + __ lea(rscratch1, ExternalAddress(file)); __ movptr(Address(r15_thread, Thread::exception_file_offset()), rscratch1); __ movl(Address(r15_thread, Thread::exception_line_offset()), (int) __LINE__); @@ -451,6 +474,9 @@ address StubGenerator::generate_catch_exception() { "_call_stub_return_address must have been generated before"); __ jump(RuntimeAddress(StubRoutines::_call_stub_return_address)); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -467,8 +493,14 @@ address StubGenerator::generate_catch_exception() { address StubGenerator::generate_forward_exception() { StubId stub_id = StubId::stubgen_forward_exception_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Upon entry, the sp points to the return address returning into // Java (interpreted or compiled) code; i.e., the return address @@ -521,6 +553,9 @@ address StubGenerator::generate_forward_exception() { __ verify_oop(rax); __ jmp(rbx); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -531,12 +566,21 @@ address StubGenerator::generate_forward_exception() { // Result: address StubGenerator::generate_orderaccess_fence() { StubId stub_id = StubId::stubgen_fence_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ membar(Assembler::StoreLoad); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -550,8 +594,14 @@ address StubGenerator::generate_orderaccess_fence() { address StubGenerator::generate_verify_mxcsr() { StubId stub_id = StubId::stubgen_verify_mxcsr_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Address mxcsr_save(rsp, 0); @@ -574,15 +624,24 @@ address StubGenerator::generate_verify_mxcsr() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_f2i_fixup() { StubId stub_id = StubId::stubgen_f2i_fixup_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); Address inout(rsp, 5 * wordSize); // return address + 4 saves - address start = __ pc(); + start = __ pc(); Label L; @@ -613,14 +672,23 @@ address StubGenerator::generate_f2i_fixup() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_f2l_fixup() { StubId stub_id = StubId::stubgen_f2l_fixup_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); Address inout(rsp, 5 * wordSize); // return address + 4 saves - address start = __ pc(); + start = __ pc(); Label L; @@ -651,15 +719,24 @@ address StubGenerator::generate_f2l_fixup() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_d2i_fixup() { StubId stub_id = StubId::stubgen_d2i_fixup_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); Address inout(rsp, 6 * wordSize); // return address + 5 saves - address start = __ pc(); + start = __ pc(); Label L; @@ -699,15 +776,24 @@ address StubGenerator::generate_d2i_fixup() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_d2l_fixup() { StubId stub_id = StubId::stubgen_d2l_fixup_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); Address inout(rsp, 6 * wordSize); // return address + 5 saves - address start = __ pc(); + start = __ pc(); Label L; @@ -747,14 +833,23 @@ address StubGenerator::generate_d2l_fixup() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_count_leading_zeros_lut() { - __ align64(); StubId stub_id = StubId::stubgen_vector_count_leading_zeros_lut_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0101010102020304, relocInfo::none); __ emit_data64(0x0000000000000000, relocInfo::none); @@ -765,14 +860,23 @@ address StubGenerator::generate_count_leading_zeros_lut() { __ emit_data64(0x0101010102020304, relocInfo::none); __ emit_data64(0x0000000000000000, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_popcount_avx_lut() { - __ align64(); StubId stub_id = StubId::stubgen_vector_popcount_lut_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0302020102010100, relocInfo::none); __ emit_data64(0x0403030203020201, relocInfo::none); @@ -783,14 +887,23 @@ address StubGenerator::generate_popcount_avx_lut() { __ emit_data64(0x0302020102010100, relocInfo::none); __ emit_data64(0x0403030203020201, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_iota_indices() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_iota_indices_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // B __ emit_data64(0x0706050403020100, relocInfo::none); __ emit_data64(0x0F0E0D0C0B0A0908, relocInfo::none); @@ -845,14 +958,24 @@ address StubGenerator::generate_iota_indices() { __ emit_data64(0x4014000000000000, relocInfo::none); // 5.0d __ emit_data64(0x4018000000000000, relocInfo::none); // 6.0d __ emit_data64(0x401c000000000000, relocInfo::none); // 7.0d + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_reverse_bit_lut() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_reverse_bit_lut_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0E060A020C040800, relocInfo::none); __ emit_data64(0x0F070B030D050901, relocInfo::none); @@ -863,14 +986,23 @@ address StubGenerator::generate_vector_reverse_bit_lut() { __ emit_data64(0x0E060A020C040800, relocInfo::none); __ emit_data64(0x0F070B030D050901, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_reverse_byte_perm_mask_long() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_reverse_byte_perm_mask_long_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0001020304050607, relocInfo::none); __ emit_data64(0x08090A0B0C0D0E0F, relocInfo::none); @@ -881,14 +1013,23 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_long() { __ emit_data64(0x0001020304050607, relocInfo::none); __ emit_data64(0x08090A0B0C0D0E0F, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_reverse_byte_perm_mask_int() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_reverse_byte_perm_mask_int_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0405060700010203, relocInfo::none); __ emit_data64(0x0C0D0E0F08090A0B, relocInfo::none); @@ -899,14 +1040,23 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_int() { __ emit_data64(0x0405060700010203, relocInfo::none); __ emit_data64(0x0C0D0E0F08090A0B, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_reverse_byte_perm_mask_short() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_reverse_byte_perm_mask_short_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0607040502030001, relocInfo::none); __ emit_data64(0x0E0F0C0D0A0B0809, relocInfo::none); @@ -917,31 +1067,52 @@ address StubGenerator::generate_vector_reverse_byte_perm_mask_short() { __ emit_data64(0x0607040502030001, relocInfo::none); __ emit_data64(0x0E0F0C0D0A0B0809, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_byte_shuffle_mask() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_byte_shuffle_mask_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x7070707070707070, relocInfo::none); __ emit_data64(0x7070707070707070, relocInfo::none); __ emit_data64(0xF0F0F0F0F0F0F0F0, relocInfo::none); __ emit_data64(0xF0F0F0F0F0F0F0F0, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_fp_mask(StubId stub_id, int64_t mask) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64( mask, relocInfo::none ); __ emit_data64( mask, relocInfo::none ); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -957,9 +1128,15 @@ address StubGenerator::generate_compress_perm_table(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); if (esize == 32) { // Loop to generate 256 x 8 int compression permute index table. A row is // accessed using 8 bit index computed using vector mask. An entry in @@ -997,6 +1174,9 @@ address StubGenerator::generate_compress_perm_table(StubId stub_id) { } } } + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1012,9 +1192,15 @@ address StubGenerator::generate_expand_perm_table(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); if (esize == 32) { // Loop to generate 256 x 8 int expand permute index table. A row is accessed // using 8 bit index computed using vector mask. An entry in a row holds either @@ -1050,13 +1236,22 @@ address StubGenerator::generate_expand_perm_table(StubId stub_id) { } } } + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_mask(StubId stub_id, int64_t mask) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(mask, relocInfo::none); __ emit_data64(mask, relocInfo::none); @@ -1067,14 +1262,23 @@ address StubGenerator::generate_vector_mask(StubId stub_id, int64_t mask) { __ emit_data64(mask, relocInfo::none); __ emit_data64(mask, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_byte_perm_mask() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vector_byte_perm_mask_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0000000000000001, relocInfo::none); __ emit_data64(0x0000000000000003, relocInfo::none); @@ -1085,13 +1289,22 @@ address StubGenerator::generate_vector_byte_perm_mask() { __ emit_data64(0x0000000000000004, relocInfo::none); __ emit_data64(0x0000000000000006, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_vector_fp_mask(StubId stub_id, int64_t mask) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(mask, relocInfo::none); __ emit_data64(mask, relocInfo::none); @@ -1102,6 +1315,9 @@ address StubGenerator::generate_vector_fp_mask(StubId stub_id, int64_t mask) { __ emit_data64(mask, relocInfo::none); __ emit_data64(mask, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1110,9 +1326,15 @@ address StubGenerator::generate_vector_custom_i32(StubId stub_id, Assembler::Avx int32_t val4, int32_t val5, int32_t val6, int32_t val7, int32_t val8, int32_t val9, int32_t val10, int32_t val11, int32_t val12, int32_t val13, int32_t val14, int32_t val15) { + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(len != Assembler::AVX_NoVec, "vector len must be specified"); __ emit_data(val0, relocInfo::none, 0); @@ -1135,6 +1357,9 @@ address StubGenerator::generate_vector_custom_i32(StubId stub_id, Assembler::Avx __ emit_data(val15, relocInfo::none, 0); } } + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1156,8 +1381,14 @@ address StubGenerator::generate_vector_custom_i32(StubId stub_id, Assembler::Avx // * = popped on exit address StubGenerator::generate_verify_oop() { StubId stub_id = StubId::stubgen_verify_oop_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label exit, error; @@ -1235,6 +1466,9 @@ address StubGenerator::generate_verify_oop() { __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64))); __ hlt(); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1350,35 +1584,46 @@ void StubGenerator::restore_argument_regs(BasicType type) { address StubGenerator::generate_data_cache_writeback() { const Register src = c_rarg0; // source address - - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_data_cache_writeback_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); __ cache_wb(Address(src, 0)); __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_data_cache_writeback_sync() { const Register is_pre = c_rarg0; // pre or post sync - - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_data_cache_writeback_sync_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); // pre wbsync is a no-op // post wbsync translates to an sfence Label skip; - address start = __ pc(); + start = __ pc(); __ enter(); __ cmpl(is_pre, 0); @@ -1388,6 +1633,9 @@ address StubGenerator::generate_data_cache_writeback_sync() { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1405,9 +1653,15 @@ address StubGenerator::generate_md5_implCompress(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register buf_param = r15; const Address state_param(rsp, 0 * wordSize); @@ -1437,30 +1691,51 @@ address StubGenerator::generate_md5_implCompress(StubId stub_id) { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_upper_word_mask() { - __ align64(); StubId stub_id = StubId::stubgen_upper_word_mask_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0000000000000000, relocInfo::none); __ emit_data64(0xFFFFFFFF00000000, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_shuffle_byte_flip_mask() { - __ align64(); StubId stub_id = StubId::stubgen_shuffle_byte_flip_mask_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none); __ emit_data64(0x0001020304050607, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1478,9 +1753,15 @@ address StubGenerator::generate_sha1_implCompress(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -1509,15 +1790,32 @@ address StubGenerator::generate_sha1_implCompress(StubId stub_id) { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } -address StubGenerator::generate_pshuffle_byte_flip_mask() { - __ align64(); +address StubGenerator::generate_pshuffle_byte_flip_mask(address& entry_00ba, address& entry_dc00) { StubId stub_id = StubId::stubgen_pshuffle_byte_flip_mask_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 3, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == entry_count - 1, + "unexpected extra entry count %d", entries.length()); + entry_00ba = entries.at(0); + entry_dc00 = entries.at(1); + assert(VM_Version::supports_avx2() == (entry_00ba != nullptr && entry_dc00 != nullptr), + "entries cannot be null when avx2 is enabled"); + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); - + start = __ pc(); + address entry2 = nullptr; + address entry3 = nullptr; __ emit_data64(0x0405060700010203, relocInfo::none); __ emit_data64(0x0c0d0e0f08090a0b, relocInfo::none); @@ -1525,37 +1823,66 @@ address StubGenerator::generate_pshuffle_byte_flip_mask() { __ emit_data64(0x0405060700010203, relocInfo::none); // second copy __ emit_data64(0x0c0d0e0f08090a0b, relocInfo::none); // _SHUF_00BA + entry2 = __ pc(); __ emit_data64(0x0b0a090803020100, relocInfo::none); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); __ emit_data64(0x0b0a090803020100, relocInfo::none); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); // _SHUF_DC00 + entry3 = __ pc(); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); __ emit_data64(0x0b0a090803020100, relocInfo::none); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); __ emit_data64(0x0b0a090803020100, relocInfo::none); } + // have to track the 2nd and 3rd entries even if they are null + entry_00ba = entry2; + entries.push(entry_00ba); + entry_dc00 = entry3; + entries.push(entry_dc00); + + // record the stub entry and end plus all the auxiliary entries + store_archive_data(stub_id, start, __ pc(), &entries); return start; } //Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. -address StubGenerator::generate_pshuffle_byte_flip_mask_sha512() { - __ align32(); +address StubGenerator::generate_pshuffle_byte_flip_mask_sha512(address& entry_ymm_lo) { StubId stub_id = StubId::stubgen_pshuffle_byte_flip_mask_sha512_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 2, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == entry_count - 1, + "unexpected extra entry count %d", entries.length()); + entry_ymm_lo = entries.at(0); + assert(VM_Version::supports_avx2() == (entry_ymm_lo != nullptr), + "entry cannot be null when avx2 is enabled"); + return start; + } + __ align32(); StubCodeMark mark(this, stub_id); - address start = __ pc(); - + start = __ pc(); + address entry2 = nullptr; if (VM_Version::supports_avx2()) { __ emit_data64(0x0001020304050607, relocInfo::none); // PSHUFFLE_BYTE_FLIP_MASK __ emit_data64(0x08090a0b0c0d0e0f, relocInfo::none); __ emit_data64(0x1011121314151617, relocInfo::none); __ emit_data64(0x18191a1b1c1d1e1f, relocInfo::none); + // capture 2nd entry + entry2 = __ pc(); __ emit_data64(0x0000000000000000, relocInfo::none); //MASK_YMM_LO __ emit_data64(0x0000000000000000, relocInfo::none); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); __ emit_data64(0xFFFFFFFFFFFFFFFF, relocInfo::none); } + // have to track the 2nd entry even if it is null + entry_ymm_lo = entry2; + entries.push(entry2); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc(), &entries); return start; } @@ -1575,9 +1902,15 @@ address StubGenerator::generate_sha256_implCompress(StubId stub_id) { ShouldNotReachHere(); } assert(VM_Version::supports_sha() || VM_Version::supports_avx2(), ""); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -1612,6 +1945,9 @@ address StubGenerator::generate_sha256_implCompress(StubId stub_id) { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1629,9 +1965,15 @@ address StubGenerator::generate_sha512_implCompress(StubId stub_id) { } assert(VM_Version::supports_avx2(), ""); assert(VM_Version::supports_bmi2() || VM_Version::supports_sha512(), ""); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Register buf = c_rarg0; Register state = c_rarg1; @@ -1660,14 +2002,23 @@ address StubGenerator::generate_sha512_implCompress(StubId stub_id) { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_shuffle_addr() { - __ align64(); StubId stub_id = StubId::stubgen_shuffle_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -1680,42 +2031,69 @@ address StubGenerator::base64_shuffle_addr() { __ emit_data64(0x2829272825262425, relocInfo::none); __ emit_data64(0x2e2f2d2e2b2c2a2b, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_avx2_shuffle_addr() { - __ align32(); StubId stub_id = StubId::stubgen_avx2_shuffle_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align32(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x0809070805060405, relocInfo::none); __ emit_data64(0x0e0f0d0e0b0c0a0b, relocInfo::none); __ emit_data64(0x0405030401020001, relocInfo::none); __ emit_data64(0x0a0b090a07080607, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_avx2_input_mask_addr() { - __ align32(); StubId stub_id = StubId::stubgen_avx2_input_mask_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align32(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0x8000000000000000, relocInfo::none); __ emit_data64(0x8000000080000000, relocInfo::none); __ emit_data64(0x8000000080000000, relocInfo::none); __ emit_data64(0x8000000080000000, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_avx2_lut_addr() { - __ align32(); StubId stub_id = StubId::stubgen_avx2_lut_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align32(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); __ emit_data64(0x0000f0edfcfcfcfc, relocInfo::none); @@ -1728,14 +2106,23 @@ address StubGenerator::base64_avx2_lut_addr() { __ emit_data64(0xfcfcfcfcfcfc4741, relocInfo::none); __ emit_data64(0x000020effcfcfcfc, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_encoding_table_addr() { - __ align64(); StubId stub_id = StubId::stubgen_encoding_table_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); __ emit_data64(0x4847464544434241, relocInfo::none); @@ -1757,6 +2144,9 @@ address StubGenerator::base64_encoding_table_addr() { __ emit_data64(0x333231307a797877, relocInfo::none); __ emit_data64(0x5f2d393837363534, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1766,10 +2156,16 @@ address StubGenerator::base64_encoding_table_addr() { // boolean isURL) { address StubGenerator::generate_base64_encodeBlock() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_base64_encodeBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); @@ -2144,15 +2540,24 @@ address StubGenerator::generate_base64_encodeBlock() __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // base64 AVX512vbmi tables address StubGenerator::base64_vbmi_lookup_lo_addr() { - __ align64(); StubId stub_id = StubId::stubgen_lookup_lo_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2165,14 +2570,23 @@ address StubGenerator::base64_vbmi_lookup_lo_addr() { __ emit_data64(0x3b3a393837363534, relocInfo::none); __ emit_data64(0x8080808080803d3c, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_lookup_hi_addr() { - __ align64(); StubId stub_id = StubId::stubgen_lookup_hi_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2185,13 +2599,22 @@ address StubGenerator::base64_vbmi_lookup_hi_addr() { __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); __ emit_data64(0x8080808080333231, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_lookup_lo_url_addr() { - __ align64(); StubId stub_id = StubId::stubgen_lookup_lo_base64url_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2204,14 +2627,23 @@ address StubGenerator::base64_vbmi_lookup_lo_url_addr() { __ emit_data64(0x3b3a393837363534, relocInfo::none); __ emit_data64(0x8080808080803d3c, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_lookup_hi_url_addr() { - __ align64(); StubId stub_id = StubId::stubgen_lookup_hi_base64url_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2224,14 +2656,23 @@ address StubGenerator::base64_vbmi_lookup_hi_url_addr() { __ emit_data64(0x302f2e2d2c2b2a29, relocInfo::none); __ emit_data64(0x8080808080333231, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_pack_vec_addr() { - __ align64(); StubId stub_id = StubId::stubgen_pack_vec_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2244,14 +2685,23 @@ address StubGenerator::base64_vbmi_pack_vec_addr() { __ emit_data64(0x0000000000000000, relocInfo::none); __ emit_data64(0x0000000000000000, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_join_0_1_addr() { - __ align64(); StubId stub_id = StubId::stubgen_join_0_1_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2264,14 +2714,23 @@ address StubGenerator::base64_vbmi_join_0_1_addr() { __ emit_data64(0x494a444546404142, relocInfo::none); __ emit_data64(0x565051524c4d4e48, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_join_1_2_addr() { - __ align64(); StubId stub_id = StubId::stubgen_join_1_2_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2284,14 +2743,23 @@ address StubGenerator::base64_vbmi_join_1_2_addr() { __ emit_data64(0x5c5d5e58595a5455, relocInfo::none); __ emit_data64(0x696a646566606162, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_vbmi_join_2_3_addr() { - __ align64(); StubId stub_id = StubId::stubgen_join_2_3_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2304,14 +2772,23 @@ address StubGenerator::base64_vbmi_join_2_3_addr() { __ emit_data64(0x767071726c6d6e68, relocInfo::none); __ emit_data64(0x7c7d7e78797a7475, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_AVX2_decode_tables_addr() { - __ align64(); StubId stub_id = StubId::stubgen_avx2_decode_tables_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2339,14 +2816,23 @@ address StubGenerator::base64_AVX2_decode_tables_addr() { // merge multiplier __ emit_data(0x00011000, relocInfo::none, 0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_AVX2_decode_LUT_tables_addr() { - __ align64(); StubId stub_id = StubId::stubgen_avx2_decode_lut_tables_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align64(); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); assert(((unsigned long long)start & 0x3f) == 0, "Alignment problem (0x%08llx)", (unsigned long long)start); @@ -2380,13 +2866,22 @@ address StubGenerator::base64_AVX2_decode_LUT_tables_addr() { __ emit_data64(0x0804080402011010, relocInfo::none); __ emit_data64(0x1010101010101010, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::base64_decoding_table_addr() { StubId stub_id = StubId::stubgen_decoding_table_base64_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ emit_data64(0xffffffffffffffff, relocInfo::none); __ emit_data64(0xffffffffffffffff, relocInfo::none); @@ -2455,6 +2950,9 @@ address StubGenerator::base64_decoding_table_addr() { __ emit_data64(0xffffffffffffffff, relocInfo::none); __ emit_data64(0xffffffffffffffff, relocInfo::none); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2466,10 +2964,16 @@ address StubGenerator::base64_decoding_table_addr() { // Intrinsic function prototype in Base64.java: // private void decodeBlock(byte[] src, int sp, int sl, byte[] dst, int dp, boolean isURL, isMIME) { address StubGenerator::generate_base64_decodeBlock() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_base64_decodeBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); @@ -2982,6 +3486,9 @@ address StubGenerator::generate_base64_decodeBlock() { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3000,11 +3507,17 @@ address StubGenerator::generate_base64_decodeBlock() { address StubGenerator::generate_updateBytesCRC32() { assert(UseCRC32Intrinsics, "need AVX and CLMUL instructions"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesCRC32_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3039,6 +3552,9 @@ address StubGenerator::generate_updateBytesCRC32() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3057,10 +3573,16 @@ address StubGenerator::generate_updateBytesCRC32() { */ address StubGenerator::generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { assert(UseCRC32CIntrinsics, "need SSE4_2"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesCRC32C_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); //reg.arg int#0 int#1 int#2 int#3 int#4 int#5 float regs //Windows RCX RDX R8 R9 none none XMM0..XMM3 @@ -3120,6 +3642,9 @@ address StubGenerator::generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3138,10 +3663,16 @@ address StubGenerator::generate_updateBytesCRC32C(bool is_pclmulqdq_supported) { * rsp+40 - z address */ address StubGenerator::generate_multiplyToLen() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_multiplyToLen_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3179,6 +3710,9 @@ address StubGenerator::generate_multiplyToLen() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3195,10 +3729,16 @@ address StubGenerator::generate_multiplyToLen() { * rax - int >= mismatched index, < 0 bitwise complement of tail */ address StubGenerator::generate_vectorizedMismatch() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_vectorizedMismatch_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); BLOCK_COMMENT("Entry:"); __ enter(); @@ -3232,6 +3772,9 @@ address StubGenerator::generate_vectorizedMismatch() { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3247,10 +3790,16 @@ address StubGenerator::generate_vectorizedMismatch() { */ address StubGenerator::generate_squareToLen() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_squareToLen_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) // Unix: rdi, rsi, rdx, rcx (c_rarg0, c_rarg1, ...) @@ -3279,14 +3828,23 @@ address StubGenerator::generate_squareToLen() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_method_entry_barrier() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_method_entry_barrier_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label deoptimize_label; @@ -3356,6 +3914,9 @@ address StubGenerator::generate_method_entry_barrier() { __ movptr(rsp, Address(rsp, 0)); // new rsp was written in the barrier __ jmp(Address(rsp, -1 * wordSize)); // jmp target should be callers verified_entry_point + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3373,10 +3934,16 @@ address StubGenerator::generate_method_entry_barrier() { * rsp+40 - k */ address StubGenerator::generate_mulAdd() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_mulAdd_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Win64: rcx, rdx, r8, r9 (c_rarg0, c_rarg1, ...) // Unix: rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...) @@ -3411,14 +3978,23 @@ address StubGenerator::generate_mulAdd() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_bigIntegerRightShift() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_bigIntegerRightShiftWorker_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label Shift512Loop, ShiftTwo, ShiftTwoLoop, ShiftOne, Exit; // For Unix, the arguments are as follows: rdi, rsi, rdx, rcx, r8. @@ -3534,6 +4110,9 @@ address StubGenerator::generate_bigIntegerRightShift() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3551,10 +4130,16 @@ address StubGenerator::generate_bigIntegerRightShift() { * rsp40 - numIter */ address StubGenerator::generate_bigIntegerLeftShift() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_bigIntegerLeftShiftWorker_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label Shift512Loop, ShiftTwo, ShiftTwoLoop, ShiftOne, Exit; // For Unix, the arguments are as follows: rdi, rsi, rdx, rcx, r8. @@ -3659,6 +4244,9 @@ address StubGenerator::generate_bigIntegerLeftShift() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3708,9 +4296,15 @@ void StubGenerator::generate_libm_stubs() { */ address StubGenerator::generate_float16ToFloat() { StubId stub_id = StubId::stubgen_hf2f_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); BLOCK_COMMENT("Entry:"); // No need for RuntimeStub frame since it is called only during JIT compilation @@ -3720,6 +4314,9 @@ address StubGenerator::generate_float16ToFloat() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3734,9 +4331,15 @@ address StubGenerator::generate_float16ToFloat() { */ address StubGenerator::generate_floatToFloat16() { StubId stub_id = StubId::stubgen_f2hf_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); BLOCK_COMMENT("Entry:"); // No need for RuntimeStub frame since it is called only during JIT compilation @@ -3746,6 +4349,9 @@ address StubGenerator::generate_floatToFloat16() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3775,8 +4381,14 @@ address StubGenerator::generate_cont_thaw(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // TODO: Handle Valhalla return types. May require generating different return barriers. @@ -3889,6 +4501,9 @@ address StubGenerator::generate_cont_thaw(StubId stub_id) { __ ret(0); } + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3909,8 +4524,14 @@ address StubGenerator::generate_cont_returnBarrier_exception() { address StubGenerator::generate_cont_preempt_stub() { if (!Continuations::enabled()) return nullptr; StubId stub_id = StubId::stubgen_cont_preempt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ reset_last_Java_frame(true); @@ -3934,14 +4555,23 @@ address StubGenerator::generate_cont_preempt_stub() { __ movptr(rscratch1, ExternalAddress(ContinuationEntry::thaw_call_pc_address())); __ jmp(rscratch1); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // exception handler for upcall stubs address StubGenerator::generate_upcall_stub_exception_handler() { StubId stub_id = StubId::stubgen_upcall_stub_exception_handler_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // native caller has no idea how to handle exceptions // we just crash here. Up to callee to catch exceptions. @@ -3953,6 +4583,9 @@ address StubGenerator::generate_upcall_stub_exception_handler() { __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception))); __ should_not_reach_here(); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -3961,8 +4594,14 @@ address StubGenerator::generate_upcall_stub_exception_handler() { // rbx = result address StubGenerator::generate_upcall_stub_load_target() { StubId stub_id = StubId::stubgen_upcall_stub_load_target_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ resolve_global_jobject(j_rarg0, rscratch1); // Load target method from receiver @@ -3976,11 +4615,27 @@ address StubGenerator::generate_upcall_stub_load_target() { __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } void StubGenerator::generate_lookup_secondary_supers_table_stub() { StubId stub_id = StubId::stubgen_lookup_secondary_supers_table_id; + GrowableArray entries; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == Klass::SECONDARY_SUPERS_TABLE_SIZE, "sanity check"); + address start = load_archive_data(stub_id, &entries); + if (start != nullptr) { + assert(entries.length() == Klass::SECONDARY_SUPERS_TABLE_SIZE - 1, + "unexpected extra entry count %d", entries.length()); + StubRoutines::_lookup_secondary_supers_table_stubs[0] = start; + for (int slot = 1; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = entries.at(slot - 1); + } + return; + } StubCodeMark mark(this, stub_id); const Register @@ -3989,21 +4644,35 @@ void StubGenerator::generate_lookup_secondary_supers_table_stub() { result = rdi; for (int slot = 0; slot < Klass::SECONDARY_SUPERS_TABLE_SIZE; slot++) { - StubRoutines::_lookup_secondary_supers_table_stubs[slot] = __ pc(); + address next_entry = __ pc(); + if (slot == 0) { + start = next_entry; + } else { + entries.append(next_entry); + } + StubRoutines::_lookup_secondary_supers_table_stubs[slot] = next_entry; __ lookup_secondary_supers_table_const(r_sub_klass, r_super_klass, rdx, rcx, rbx, r11, // temps result, slot); __ ret(0); } + + // record the stub entry and end plus all the auxiliary entries + store_archive_data(stub_id, start, __ pc(), &entries); } // Slow path implementation for UseSecondarySupersTable. address StubGenerator::generate_lookup_secondary_supers_table_slow_path_stub() { StubId stub_id = StubId::stubgen_lookup_secondary_supers_table_slow_path_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - - address start = __ pc(); + start = __ pc(); const Register r_super_klass = rax, @@ -4025,6 +4694,9 @@ address StubGenerator::generate_lookup_secondary_supers_table_slow_path_stub() { __ movl(result, 0); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4232,6 +4904,8 @@ void StubGenerator::generate_compiler_stubs() { } if (UseSHA256Intrinsics) { + address entry2 = nullptr; + address entry3 = nullptr; StubRoutines::x86::_k256_adr = (address)StubRoutines::x86::_k256; char* dst = (char*)StubRoutines::x86::_k256_W; char* src = (char*)StubRoutines::x86::_k256; @@ -4240,14 +4914,18 @@ void StubGenerator::generate_compiler_stubs() { memcpy(dst + 32 * ii + 16, src + 16 * ii, 16); } StubRoutines::x86::_k256_W_adr = (address)StubRoutines::x86::_k256_W; - StubRoutines::x86::_pshuffle_byte_flip_mask_addr = generate_pshuffle_byte_flip_mask(); + StubRoutines::x86::_pshuffle_byte_flip_mask_addr = generate_pshuffle_byte_flip_mask(entry2, entry3); + StubRoutines::x86::_pshuffle_byte_flip_mask_00ba_addr = entry2; + StubRoutines::x86::_pshuffle_byte_flip_mask_dc00_addr = entry3; StubRoutines::_sha256_implCompress = generate_sha256_implCompress(StubId::stubgen_sha256_implCompress_id); StubRoutines::_sha256_implCompressMB = generate_sha256_implCompress(StubId::stubgen_sha256_implCompressMB_id); } if (UseSHA512Intrinsics) { + address entry2 = nullptr; StubRoutines::x86::_k512_W_addr = (address)StubRoutines::x86::_k512_W; - StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = generate_pshuffle_byte_flip_mask_sha512(); + StubRoutines::x86::_pshuffle_byte_flip_mask_addr_sha512 = generate_pshuffle_byte_flip_mask_sha512(entry2); + StubRoutines::x86::_pshuffle_byte_flip_mask_ymm_lo_addr_sha512 = entry2; StubRoutines::_sha512_implCompress = generate_sha512_implCompress(StubId::stubgen_sha512_implCompress_id); StubRoutines::_sha512_implCompressMB = generate_sha512_implCompress(StubId::stubgen_sha512_implCompressMB_id); } @@ -4325,7 +5003,7 @@ void StubGenerator::generate_compiler_stubs() { #endif // COMPILER2_OR_JVMCI } -StubGenerator::StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { +StubGenerator::StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -4348,8 +5026,35 @@ StubGenerator::StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerat }; } -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +#if INCLUDE_CDS +// publish addresses of static data defined in this file and in other +// stubgen stub generator files +void StubGenerator::init_AOTAddressTable(GrowableArray& external_addresses) { + init_AOTAddressTable_adler(external_addresses); + init_AOTAddressTable_aes(external_addresses); + init_AOTAddressTable_cbrt(external_addresses); + init_AOTAddressTable_chacha(external_addresses); + // constants publishes for all of address use by cos and almost all of sin + init_AOTAddressTable_constants(external_addresses); + init_AOTAddressTable_dilithium(external_addresses); + init_AOTAddressTable_exp(external_addresses); + init_AOTAddressTable_fmod(external_addresses); + init_AOTAddressTable_ghash(external_addresses); + init_AOTAddressTable_kyber(external_addresses); + init_AOTAddressTable_log(external_addresses); + init_AOTAddressTable_poly1305(external_addresses); + init_AOTAddressTable_poly_mont(external_addresses); + init_AOTAddressTable_pow(external_addresses); + init_AOTAddressTable_sha3(external_addresses); + init_AOTAddressTable_sin(external_addresses); + init_AOTAddressTable_sinh(external_addresses); + init_AOTAddressTable_tan(external_addresses); + init_AOTAddressTable_tanh(external_addresses); +} +#endif // INCLUDE_CDS + +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data) { + StubGenerator g(code, blob_id, stub_data); } #undef __ diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp index 332add6dcd4..05e8384d636 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp @@ -303,11 +303,11 @@ class StubGenerator: public StubCodeGenerator { address generate_sha512_implCompress(StubId stub_id); // Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. - address generate_pshuffle_byte_flip_mask_sha512(); + address generate_pshuffle_byte_flip_mask_sha512(address& entry_ymm_lo); address generate_upper_word_mask(); address generate_shuffle_byte_flip_mask(); - address generate_pshuffle_byte_flip_mask(); + address generate_pshuffle_byte_flip_mask(address& entry_00ba, address& entry_dc0); // AES intrinsic stubs @@ -650,8 +650,33 @@ class StubGenerator: public StubCodeGenerator { void generate_compiler_stubs(); void generate_final_stubs(); +#if INCLUDE_CDS + static void init_AOTAddressTable_adler(GrowableArray& external_addresses); + static void init_AOTAddressTable_aes(GrowableArray& external_addresses); + static void init_AOTAddressTable_cbrt(GrowableArray& external_addresses); + static void init_AOTAddressTable_chacha(GrowableArray& external_addresses); + static void init_AOTAddressTable_constants(GrowableArray& external_addresses); + static void init_AOTAddressTable_dilithium(GrowableArray& external_addresses); + static void init_AOTAddressTable_exp(GrowableArray& external_addresses); + static void init_AOTAddressTable_fmod(GrowableArray& external_addresses); + static void init_AOTAddressTable_ghash(GrowableArray& external_addresses); + static void init_AOTAddressTable_kyber(GrowableArray& external_addresses); + static void init_AOTAddressTable_log(GrowableArray& external_addresses); + static void init_AOTAddressTable_poly1305(GrowableArray& external_addresses); + static void init_AOTAddressTable_poly_mont(GrowableArray& external_addresses); + static void init_AOTAddressTable_pow(GrowableArray& external_addresses); + static void init_AOTAddressTable_sha3(GrowableArray& external_addresses); + static void init_AOTAddressTable_sin(GrowableArray& external_addresses); + static void init_AOTAddressTable_sinh(GrowableArray& external_addresses); + static void init_AOTAddressTable_tan(GrowableArray& external_addresses); + static void init_AOTAddressTable_tanh(GrowableArray& external_addresses); +#endif // INCLUDE_CDS + public: - StubGenerator(CodeBuffer* code, BlobId blob_id); + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData* stub_data); +#if INCLUDE_CDS + static void init_AOTAddressTable(GrowableArray& external_addresses); +#endif // INCLUDE_CDS }; #endif // CPU_X86_STUBGENERATOR_X86_64_HPP diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp index 1d3e7afde1d..a9424978e0e 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_adler.cpp @@ -67,8 +67,14 @@ address StubGenerator::generate_updateBytesAdler32() { __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_updateBytesAdler32_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // Choose an appropriate LIMIT for inner loop based on the granularity // of intermediate results. For int, LIMIT of 5552 will ensure intermediate @@ -334,7 +340,19 @@ address StubGenerator::generate_updateBytesAdler32() { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_adler(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + ADD(ADLER32_ASCALE_TABLE); + ADD(ADLER32_SHUF0_TABLE); + ADD(ADLER32_SHUF1_TABLE); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp index 162c92d5190..b95aa5f8818 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_aes.cpp @@ -250,10 +250,16 @@ void StubGenerator::generate_aes_stubs() { // Output: // rax - number of processed bytes address StubGenerator::generate_galoisCounterMode_AESCrypt() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register in = c_rarg0; const Register len = c_rarg1; @@ -319,6 +325,9 @@ address StubGenerator::generate_galoisCounterMode_AESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -337,10 +346,16 @@ address StubGenerator::generate_galoisCounterMode_AESCrypt() { // Output: // rax - number of processed bytes address StubGenerator::generate_avx2_galoisCounterMode_AESCrypt() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_galoisCounterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register in = c_rarg0; const Register len = c_rarg1; @@ -404,15 +419,24 @@ address StubGenerator::generate_avx2_galoisCounterMode_AESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // Vector AES Counter implementation address StubGenerator::generate_counterMode_VectorAESCrypt() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -471,6 +495,9 @@ address StubGenerator::generate_counterMode_VectorAESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -498,10 +525,16 @@ address StubGenerator::generate_counterMode_VectorAESCrypt() { // address StubGenerator::generate_counterMode_AESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -781,15 +814,24 @@ address StubGenerator::generate_counterMode_AESCrypt_Parallel() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() { assert(VM_Version::supports_avx512_vaes(), "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1057,6 +1099,9 @@ address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1069,11 +1114,17 @@ address StubGenerator::generate_cipherBlockChaining_decryptVectorAESCrypt() { // address StubGenerator::generate_aescrypt_encryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_aescrypt_encryptBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label L_doLast; - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1152,6 +1203,9 @@ address StubGenerator::generate_aescrypt_encryptBlock() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1164,11 +1218,17 @@ address StubGenerator::generate_aescrypt_encryptBlock() { // address StubGenerator::generate_aescrypt_decryptBlock() { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_aescrypt_decryptBlock_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); Label L_doLast; - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1248,6 +1308,9 @@ address StubGenerator::generate_aescrypt_decryptBlock() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1266,10 +1329,16 @@ address StubGenerator::generate_aescrypt_decryptBlock() { // address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_encryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256; const Register from = c_rarg0; // source array address @@ -1398,6 +1467,9 @@ address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() { __ jcc(Assembler::notEqual, L_loopTop_256); __ jmp(L_exit); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1422,11 +1494,15 @@ address StubGenerator::generate_cipherBlockChaining_encryptAESCrypt() { // address StubGenerator::generate_electronicCodeBook_AESCrypt_Parallel(bool is_encrypt) { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = is_encrypt ? StubId::stubgen_electronicCodeBook_encryptAESCrypt_id : StubId::stubgen_electronicCodeBook_decryptAESCrypt_id; + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1581,6 +1657,9 @@ __ opc(xmm_result0, reg); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; #undef DoFour @@ -1612,10 +1691,16 @@ address StubGenerator::generate_electronicCodeBook_decryptAESCrypt_Parallel() { // address StubGenerator::generate_cipherBlockChaining_decryptAESCrypt_Parallel() { assert(UseAES, "need AES instructions and misaligned SSE support"); - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1851,14 +1936,23 @@ __ opc(xmm_result3, src_reg); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_electronicCodeBook_encryptAESCrypt() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_electronicCodeBook_encryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1872,14 +1966,23 @@ address StubGenerator::generate_electronicCodeBook_encryptAESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } address StubGenerator::generate_electronicCodeBook_decryptAESCrypt() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_electronicCodeBook_decryptAESCrypt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register from = c_rarg0; // source array address const Register to = c_rarg1; // destination array address @@ -1893,6 +1996,9 @@ address StubGenerator::generate_electronicCodeBook_decryptAESCrypt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -4292,3 +4398,27 @@ void StubGenerator::aesgcm_avx2(Register in, Register len, Register ct, Register } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_aes(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + ADD(key_shuffle_mask_addr()); + ADD(counter_shuffle_mask_addr()); + ADD(counter_mask_linc0_addr()); + ADD(counter_mask_linc1_addr()); + ADD(counter_mask_linc1f_addr()); + ADD(counter_mask_linc2_addr()); + ADD(counter_mask_linc2f_addr()); + ADD(counter_mask_linc4_addr()); + ADD(counter_mask_linc8_addr()); + ADD(counter_mask_linc16_addr()); + ADD(counter_mask_linc32_addr()); + ADD(counter_mask_ones_addr()); + ADD(ghash_polynomial_reduction_addr()); + ADD(ghash_polynomial_two_one_addr()); + ADD(counter_mask_addbe_4444_addr()); + ADD(counter_mask_addbe_1234_addr()); + ADD(counter_mask_add_1234_addr()); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp index 01e004b7b43..5530e5325de 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp @@ -570,10 +570,45 @@ address StubGenerator::generate_disjoint_copy_avx3_masked(StubId stub_id, addres default: ShouldNotReachHere(); } + GrowableArray entries; + GrowableArray extras; + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + // The stub employs one unsafe handler region by default but has two + // when MaxVectorSize == 64 So we may expect 0, 3 or 6 extras. + int handlers_count = (MaxVectorSize == 64 ? 2 : 1); + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_extra_count = (add_handlers ? handlers_count : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/1/2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_extra_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 1/2 x UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, handlers_count); + } +#if INCLUDE_ZGC + // register addresses at which ZGC does colour patching + if (add_relocs) { + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); bool use64byteVector = (MaxVectorSize > 32) && (CopyAVX3Threshold == 0); const int large_threshold = 2621440; // 2.5 MB @@ -595,6 +630,7 @@ address StubGenerator::generate_disjoint_copy_avx3_masked(StubId stub_id, addres if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -620,7 +656,7 @@ address StubGenerator::generate_disjoint_copy_avx3_masked(StubId stub_id, addres int threshold[] = { 4096, 2048, 1024, 512}; // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // 'from', 'to' and 'count' are now valid // temp1 holds remaining count and temp4 holds running count used to compute @@ -789,10 +825,28 @@ address StubGenerator::generate_disjoint_copy_avx3_masked(StubId stub_id, addres if (MaxVectorSize == 64) { __ BIND(L_copy_large); - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, false, ucme_exit_pc); + UnsafeMemoryAccessMark umam(this, add_handlers, false, ucme_exit_pc); arraycopy_avx3_large(to, from, temp1, temp2, temp3, temp4, count, xmm1, xmm2, xmm3, xmm4, shift); __ jmp(L_finish); } + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_extra_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (add_relocs) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -907,10 +961,41 @@ address StubGenerator::generate_conjoint_copy_avx3_masked(StubId stub_id, addres default: ShouldNotReachHere(); } - + GrowableArray entries; + GrowableArray extras; + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (add_handlers ? 1 : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/1 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 1 x UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 1); + } +#if INCLUDE_ZGC + if (add_relocs) { + // register addresses at which ZGC does colour patching + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); bool use64byteVector = (MaxVectorSize > 32) && (CopyAVX3Threshold == 0); @@ -931,6 +1016,7 @@ address StubGenerator::generate_conjoint_copy_avx3_masked(StubId stub_id, addres if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -957,7 +1043,7 @@ address StubGenerator::generate_conjoint_copy_avx3_masked(StubId stub_id, addres int threshold[] = { 4096, 2048, 1024, 512}; // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // 'from', 'to' and 'count' are now valid // temp1 holds remaining count. @@ -1071,6 +1157,23 @@ address StubGenerator::generate_conjoint_copy_avx3_masked(StubId stub_id, addres __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (add_relocs) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -1385,9 +1488,29 @@ address StubGenerator::generate_disjoint_byte_copy(address* entry) { return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (2 * UnsafeMemoryAccess::COLUMN_COUNT); // 2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + address start = load_archive_data(stub_id, entries_ptr, &extras); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; @@ -1407,6 +1530,7 @@ address StubGenerator::generate_disjoint_byte_copy(address* entry) { if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1476,6 +1600,17 @@ __ BIND(L_exit); copy_bytes_forward(end_from, end_to, qword_count, rax, r10, L_copy_bytes, L_copy_8_bytes, decorators, T_BYTE); __ jmp(L_copy_4_bytes); } + + // retrieve the registered handler addresses + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, &extras); + return start; } @@ -1503,9 +1638,29 @@ address StubGenerator::generate_conjoint_byte_copy(address nooverlap_target, add return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (2 * UnsafeMemoryAccess::COLUMN_COUNT); // 2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + address start = load_archive_data(stub_id, entries_ptr, &extras); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY; Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_copy_2_bytes; @@ -1520,6 +1675,7 @@ address StubGenerator::generate_conjoint_byte_copy(address nooverlap_target, add if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1586,6 +1742,16 @@ address StubGenerator::generate_conjoint_byte_copy(address nooverlap_target, add __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // retrieve the registered handler addresses + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, &extras); + return start; } @@ -1616,10 +1782,29 @@ address StubGenerator::generate_disjoint_short_copy(address *entry) { return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif - + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (2 * UnsafeMemoryAccess::COLUMN_COUNT); // 2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + address start = load_archive_data(stub_id, entries_ptr, &extras); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT; Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes,L_copy_2_bytes,L_exit; @@ -1638,6 +1823,7 @@ address StubGenerator::generate_disjoint_short_copy(address *entry) { if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1701,6 +1887,16 @@ __ BIND(L_exit); __ jmp(L_copy_4_bytes); } + // retrieve the registered handler addresses + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, &extras); + return start; } @@ -1708,7 +1904,6 @@ __ BIND(L_exit); address StubGenerator::generate_fill(StubId stub_id) { BasicType t; bool aligned; - switch (stub_id) { case StubId::stubgen_jbyte_fill_id: t = T_BYTE; @@ -1737,10 +1932,27 @@ address StubGenerator::generate_fill(StubId stub_id) { default: ShouldNotReachHere(); } + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + GrowableArray extras; + bool add_handlers = ((t == T_BYTE) && !aligned); + int handlers_count = (add_handlers ? 1 : 0); + int expected_extras_count = (handlers_count * UnsafeMemoryAccess::COLUMN_COUNT); // 0/1 x UMAM {start,end,handler} + GrowableArray* extras_ptr = (add_handlers ? &extras : nullptr); + address start = load_archive_data(stub_id, nullptr, extras_ptr); + if (start != nullptr) { + assert(extras.length() == expected_extras_count, + "unexpected handler addresses count %d", extras.length()); + if (add_handlers) { + // restore 1 x UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 1); + } + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); BLOCK_COMMENT("Entry:"); @@ -1753,7 +1965,7 @@ address StubGenerator::generate_fill(StubId stub_id) { { // Add set memory mark to protect against unsafe accesses faulting - UnsafeMemoryAccessMark umam(this, ((t == T_BYTE) && !aligned), true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); __ generate_fill(t, aligned, to, value, r11, rax, xmm0); } @@ -1761,6 +1973,15 @@ address StubGenerator::generate_fill(StubId stub_id) { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_extras_count, + "unexpected handler addresses count %d", extras.length()); + // record the stub entry and end + store_archive_data(stub_id, start, end, nullptr, extras_ptr); + return start; } @@ -1788,10 +2009,29 @@ address StubGenerator::generate_conjoint_short_copy(address nooverlap_target, ad return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif - + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (2 * UnsafeMemoryAccess::COLUMN_COUNT); // 2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + address start = load_archive_data(stub_id, entries_ptr, &extras); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); DecoratorSet decorators = IN_HEAP | IS_ARRAY; Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes; @@ -1806,6 +2046,7 @@ address StubGenerator::generate_conjoint_short_copy(address nooverlap_target, ad if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1864,6 +2105,16 @@ address StubGenerator::generate_conjoint_short_copy(address nooverlap_target, ad __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // retrieve the registered handler addresses + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, &extras); + return start; } @@ -1916,10 +2167,42 @@ address StubGenerator::generate_disjoint_int_oop_copy(StubId stub_id, address* e return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif + GrowableArray entries; + GrowableArray extras; + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (add_handlers ? 2 : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + } +#if INCLUDE_ZGC + // register addresses at which ZGC does colour patching + if (add_relocs) { + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_copy_4_bytes, L_exit; const Register from = rdi; // source array address @@ -1937,6 +2220,7 @@ address StubGenerator::generate_disjoint_int_oop_copy(StubId stub_id, address* e if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -1957,7 +2241,7 @@ address StubGenerator::generate_disjoint_int_oop_copy(StubId stub_id, address* e { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // 'from', 'to' and 'count' are now valid __ movptr(dword_count, count); __ shrptr(count, 1); // count => qword_count @@ -1969,20 +2253,20 @@ address StubGenerator::generate_disjoint_int_oop_copy(StubId stub_id, address* e __ jmp(L_copy_bytes); // Copy trailing qwords - __ BIND(L_copy_8_bytes); + __ BIND(L_copy_8_bytes); __ movq(rax, Address(end_from, qword_count, Address::times_8, 8)); __ movq(Address(end_to, qword_count, Address::times_8, 8), rax); __ increment(qword_count); __ jcc(Assembler::notZero, L_copy_8_bytes); // Check for and copy trailing dword - __ BIND(L_copy_4_bytes); + __ BIND(L_copy_4_bytes); __ testl(dword_count, 1); // Only byte test since the value is 0 or 1 __ jccb(Assembler::zero, L_exit); __ movl(rax, Address(end_from, 8)); __ movl(Address(end_to, 8), rax); } -__ BIND(L_exit); + __ BIND(L_exit); address ucme_exit_pc = __ pc(); bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count); restore_arg_regs_using_thread(); @@ -1993,12 +2277,30 @@ __ BIND(L_exit); __ ret(0); { - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, false, ucme_exit_pc); + UnsafeMemoryAccessMark umam(this, add_handlers, false, ucme_exit_pc); // Copy in multi-bytes chunks copy_bytes_forward(end_from, end_to, qword_count, rax, r10, L_copy_bytes, L_copy_8_bytes, decorators, is_oop ? T_OBJECT : T_INT); __ jmp(L_copy_4_bytes); } + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (add_relocs) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -2047,10 +2349,42 @@ address StubGenerator::generate_conjoint_int_oop_copy(StubId stub_id, address no return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (add_handlers ? 2 : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + } +#if INCLUDE_ZGC + // register addresses at which ZGC does colour patching + if (add_relocs) { + register_reloc_addresses(extras, 6, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address @@ -2064,7 +2398,8 @@ address StubGenerator::generate_conjoint_int_oop_copy(StubId stub_id, address no if (entry != nullptr) { *entry = __ pc(); - // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) + entries.append(*entry); + // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -2087,7 +2422,7 @@ address StubGenerator::generate_conjoint_int_oop_copy(StubId stub_id, address no assert_clean_int(count, rax); // Make sure 'count' is clean int. { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // 'from', 'to' and 'count' are now valid __ movptr(dword_count, count); __ shrptr(count, 1); // count => qword_count @@ -2102,7 +2437,7 @@ address StubGenerator::generate_conjoint_int_oop_copy(StubId stub_id, address no __ jmp(L_copy_bytes); // Copy trailing qwords - __ BIND(L_copy_8_bytes); + __ BIND(L_copy_8_bytes); __ movq(rax, Address(from, qword_count, Address::times_8, -8)); __ movq(Address(to, qword_count, Address::times_8, -8), rax); __ decrement(qword_count); @@ -2120,12 +2455,12 @@ address StubGenerator::generate_conjoint_int_oop_copy(StubId stub_id, address no { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // Copy in multi-bytes chunks copy_bytes_backward(from, to, qword_count, rax, r10, L_copy_bytes, L_copy_8_bytes, decorators, is_oop ? T_OBJECT : T_INT); } -__ BIND(L_exit); + __ BIND(L_exit); bs->arraycopy_epilogue(_masm, decorators, type, from, to, dword_count); restore_arg_regs_using_thread(); INC_COUNTER_NP(SharedRuntime::_jint_array_copy_ctr, rscratch1); // Update counter after rscratch1 is free @@ -2134,6 +2469,23 @@ __ BIND(L_exit); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (add_relocs) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -2180,10 +2532,42 @@ address StubGenerator::generate_disjoint_long_oop_copy(StubId stub_id, address * return generate_disjoint_copy_avx3_masked(stub_id, entry); } #endif + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (add_handlers ? 2 : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + } +#if INCLUDE_ZGC + // register addresses at which ZGC does colour patching + if (add_relocs) { + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address @@ -2201,6 +2585,7 @@ address StubGenerator::generate_disjoint_long_oop_copy(StubId stub_id, address * if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -2221,7 +2606,7 @@ address StubGenerator::generate_disjoint_long_oop_copy(StubId stub_id, address * bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count); { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // Copy from low to high addresses. Use 'to' as scratch. __ lea(end_from, Address(from, qword_count, Address::times_8, -8)); @@ -2253,7 +2638,7 @@ address StubGenerator::generate_disjoint_long_oop_copy(StubId stub_id, address * { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // Copy in multi-bytes chunks copy_bytes_forward(end_from, end_to, qword_count, rax, r10, L_copy_bytes, L_copy_8_bytes, decorators, is_oop ? T_OBJECT : T_LONG); } @@ -2269,6 +2654,23 @@ address StubGenerator::generate_disjoint_long_oop_copy(StubId stub_id, address * __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (add_relocs) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -2313,10 +2715,42 @@ address StubGenerator::generate_conjoint_long_oop_copy(StubId stub_id, address n return generate_conjoint_copy_avx3_masked(stub_id, entry, nooverlap_target); } #endif + bool add_handlers = !is_oop && !aligned; + bool add_relocs = UseZGC && is_oop; + bool add_extras = add_handlers || add_relocs; + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int expected_handler_count = (add_handlers ? 2 : 0) * UnsafeMemoryAccess::COLUMN_COUNT; // 0/2 x UMAM {start,end,handler} + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (add_extras ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected entry count %d", entries.length()); + assert(!add_handlers || extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } + if (add_handlers) { + // restore 2 UMAM {start,end,handler} addresses from extras + register_unsafe_access_handlers(extras, 0, 2); + } +#if INCLUDE_ZGC + // register addresses at which ZGC does colour patching + if (add_relocs) { + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_copy_bytes, L_copy_8_bytes, L_exit; const Register from = rdi; // source array address @@ -2329,6 +2763,7 @@ address StubGenerator::generate_conjoint_long_oop_copy(StubId stub_id, address n if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); // caller can pass a 64-bit byte count here (from Unsafe.copyMemory) BLOCK_COMMENT("Entry:"); } @@ -2350,7 +2785,7 @@ address StubGenerator::generate_conjoint_long_oop_copy(StubId stub_id, address n bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count); { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); __ jmp(L_copy_bytes); @@ -2377,7 +2812,7 @@ address StubGenerator::generate_conjoint_long_oop_copy(StubId stub_id, address n } { // UnsafeMemoryAccess page error: continue after unsafe access - UnsafeMemoryAccessMark umam(this, !is_oop && !aligned, true); + UnsafeMemoryAccessMark umam(this, add_handlers, true); // Copy in multi-bytes chunks copy_bytes_backward(from, to, qword_count, rax, r10, L_copy_bytes, L_copy_8_bytes, decorators, is_oop ? T_OBJECT : T_LONG); @@ -2393,6 +2828,24 @@ address StubGenerator::generate_conjoint_long_oop_copy(StubId stub_id, address n __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + + // retrieve the registered handler addresses + address end = __ pc(); + if (add_handlers) { + retrieve_unsafe_access_handlers(start, end, extras); + } + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if ((UseZGC && is_oop)) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -2448,6 +2901,28 @@ address StubGenerator::generate_checkcast_copy(StubId stub_id, address *entry) { ShouldNotReachHere(); } + GrowableArray entries; + GrowableArray extras; + int expected_entry_count = (entry != nullptr ? 2 : 1); + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == expected_entry_count, "sanity check"); + GrowableArray* entries_ptr = (entry_count == 1 ? nullptr : &entries); + GrowableArray* extras_ptr = (UseZGC ? &extras : nullptr); + address start = load_archive_data(stub_id, entries_ptr, extras_ptr); + if (start != nullptr) { + assert(entries.length() == expected_entry_count - 1, + "unexpected addresses count %d", entries.length()); + if (entry != nullptr) { + *entry = entries.at(0); + } +#if INCLUDE_ZGC + if (UseZGC) { + register_reloc_addresses(extras, 0, extras.length()); + } +#endif // INCLUDE_ZGC + return start; + } + Label L_load_element, L_store_element, L_do_card_marks, L_done; // Input registers (after setup_arg_regs) @@ -2477,7 +2952,7 @@ address StubGenerator::generate_checkcast_copy(StubId stub_id, address *entry) { __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2502,6 +2977,7 @@ address StubGenerator::generate_checkcast_copy(StubId stub_id, address *entry) { // Caller of this entry point must set up the argument registers. if (entry != nullptr) { *entry = __ pc(); + entries.append(*entry); BLOCK_COMMENT("Entry:"); } @@ -2636,6 +3112,16 @@ address StubGenerator::generate_checkcast_copy(StubId stub_id, address *entry) { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + address end = __ pc(); +#if INCLUDE_ZGC + // retrieve addresses at which ZGC does colour patching + if (UseZGC) { + retrieve_reloc_addresses(start, end, extras); + } +#endif // INCLUDE_ZGC + // record the stub entry and end plus the no_push entry + store_archive_data(stub_id, start, end, entries_ptr, extras_ptr); + return start; } @@ -2655,6 +3141,14 @@ address StubGenerator::generate_checkcast_copy(StubId stub_id, address *entry) { address StubGenerator::generate_unsafe_copy(address byte_copy_entry, address short_copy_entry, address int_copy_entry, address long_copy_entry) { + StubId stub_id = StubId::stubgen_unsafe_arraycopy_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + Label L_long_aligned, L_int_aligned, L_short_aligned; // Input registers (before setup_arg_regs) @@ -2666,9 +3160,8 @@ address StubGenerator::generate_unsafe_copy(address byte_copy_entry, address sho const Register bits = rax; // test copy of low bits __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_unsafe_arraycopy_id; StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -2700,6 +3193,9 @@ address StubGenerator::generate_unsafe_copy(address byte_copy_entry, address sho __ shrptr(size, LogBytesPerLong); // size => qword_count __ jump(RuntimeAddress(long_copy_entry)); + // record the stub entry and end plus + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -2801,10 +3297,23 @@ static void do_setmemory_atomic_loop(USM_TYPE type, Register dest, // to an int, short, or byte fill loop. // address StubGenerator::generate_unsafe_setmemory(address unsafe_byte_fill) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_unsafe_setmemory_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + // we expect three set of extra unsafememory access handler entries + GrowableArray extras; + int expected_handler_count = 3 * UnsafeMemoryAccess::COLUMN_COUNT; + address start = load_archive_data(stub_id, nullptr, &extras); + if (start != nullptr) { + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + register_unsafe_access_handlers(extras, 0, 3); + return start; + } + + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame assert(unsafe_byte_fill != nullptr, "Invalid call"); @@ -2894,6 +3403,16 @@ address StubGenerator::generate_unsafe_setmemory(address unsafe_byte_fill) { __ jump(RuntimeAddress(unsafe_byte_fill)); } + // retrieve the registered handler addresses + address end = __ pc(); + retrieve_unsafe_access_handlers(start, end, extras); + assert(extras.length() == expected_handler_count, + "unexpected handler addresses count %d", extras.length()); + + // record the stub entry and end plus the no_push entry and any + // extra handler addresses + store_archive_data(stub_id, start, end, nullptr, &extras); + return start; } @@ -2950,7 +3469,15 @@ address StubGenerator::generate_generic_copy(address byte_copy_entry, address sh address int_copy_entry, address oop_copy_entry, address long_copy_entry, address checkcast_copy_entry) { - Label L_failed, L_failed_0, L_objArray; + StubId stub_id = StubId::stubgen_generic_arraycopy_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + + Label L_failed, L_failed_0, L_skip_failed_0, L_objArray; Label L_copy_shorts, L_copy_ints, L_copy_longs; // Input registers @@ -2966,22 +3493,9 @@ address StubGenerator::generate_generic_copy(address byte_copy_entry, address sh const Register rklass_tmp = rdi; // load_klass #endif - { int modulus = CodeEntryAlignment; - int target = modulus - 5; // 5 = sizeof jmp(L_failed) - int advance = target - (__ offset() % modulus); - if (advance < 0) advance += modulus; - if (advance > 0) __ nop(advance); - } - StubId stub_id = StubId::stubgen_generic_arraycopy_id; StubCodeMark mark(this, stub_id); - - // Short-hop target to L_failed. Makes for denser prologue code. - __ BIND(L_failed_0); - __ jmp(L_failed); - assert(__ offset() % CodeEntryAlignment == 0, "no further alignment needed"); - __ align(CodeEntryAlignment); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame @@ -3022,7 +3536,8 @@ address StubGenerator::generate_generic_copy(address byte_copy_entry, address sh // if (dst_pos < 0) return -1; __ testl(dst_pos, dst_pos); // dst_pos (32-bits) size_t j4off = __ offset(); - __ jccb(Assembler::negative, L_failed_0); + // skip over the failure trampoline + __ jccb(Assembler::positive, L_skip_failed_0); // The first four tests are very dense code, // but not quite dense enough to put four @@ -3032,6 +3547,13 @@ address StubGenerator::generate_generic_copy(address byte_copy_entry, address sh // Make sure of this. guarantee(((j1off ^ j4off) & ~15) != 0, "I$ line of 1st & 4th jumps"); + // Short-hop target to L_failed. Makes for denser prologue code. + __ BIND(L_failed_0); + __ jmp(L_failed); + + // continue here if first 4 checks pass + __ bind(L_skip_failed_0); + // registers used as temp const Register r11_length = r11; // elements count to copy const Register r10_src_klass = r10; // array klass @@ -3254,6 +3776,9 @@ __ BIND(L_failed); __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp index 73330dedc0f..4c647b7d9dc 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp @@ -191,8 +191,14 @@ ATTRIBUTE_ALIGNED(4) static const juint _D_table[] = address StubGenerator::generate_libmCbrt() { StubId stub_id = StubId::stubgen_dcbrt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1; Label B1_1, B1_2, B1_4; @@ -335,7 +341,34 @@ address StubGenerator::generate_libmCbrt() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_cbrt(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + ADD(_ABS_MASK); + ADD(_SIG_MASK); + ADD(_EXP_MASK); + ADD(_EXP_MSK2); + ADD(_EXP_MSK3); + ADD(_SCALE63); + ADD(_ZERON); + ADD(_INF); + ADD(_NEG_INF); + address coeff_table = (address)_coeff_table; + ADD(coeff_table); + ADD(coeff_table + 16); + ADD(coeff_table + 32); + ADD(coeff_table + 48); + ADD(_rcp_table); + ADD(_cbrt_table); + ADD(_D_table); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp index 7afaf34e031..1fa51cd2f18 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_chacha.cpp @@ -111,10 +111,16 @@ void StubGenerator::generate_chacha_stubs() { /* The 2-block AVX/AVX2-enabled ChaCha20 block function implementation */ address StubGenerator::generate_chacha20Block_avx() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_chacha20Block_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_twoRounds; const Register state = c_rarg0; @@ -295,15 +301,25 @@ address StubGenerator::generate_chacha20Block_avx() { } __ leave(); __ ret(0); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } /* The 4-block AVX512-enabled ChaCha20 block function implementation */ address StubGenerator::generate_chacha20Block_avx512() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_chacha20Block_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_twoRounds; const Register state = c_rarg0; @@ -466,6 +482,10 @@ address StubGenerator::generate_chacha20Block_avx512() { __ vzeroupper(); __ leave(); __ ret(0); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -584,3 +604,13 @@ bVec, } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_chacha(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + ADD(CC20_COUNTER_ADD_AVX); + ADD(CC20_COUNTER_ADD_AVX512); + ADD(CC20_LROT_CONSTS); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp index 93fa7e650db..45c13b7b397 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_constants.cpp @@ -233,3 +233,29 @@ ATTRIBUTE_ALIGNED(16) static const juint _Ctable[] = { }; address StubGenerator::Ctable = (address)_Ctable; +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_constants(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + ADD(_ONE); + ADD(_ONEHALF); + ADD(_SIGN_MASK); + ADD(_TWO_POW_55); + ADD(_TWO_POW_M55); + ADD(_SHIFTER); + ADD(_ZERO); + ADD(_SC_1); + ADD(_SC_2); + ADD(_SC_3); + ADD(_SC_4); + ADD(_PI_4); + ADD(((address)_PI_4+8)); + ADD(_PI32INV); + ADD(_NEG_ZERO); + ADD(_P_1); + ADD(_P_2); + ADD(_P_3); + ADD(_PI_INV_TABLE); + ADD(_Ctable); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp index 8cb6ead21fd..8dedd50cd97 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_cos.cpp @@ -174,8 +174,14 @@ address StubGenerator::generate_libmCos() { StubId stub_id = StubId::stubgen_dcos_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; Label L_2TAG_PACKET_4_0_1, L_2TAG_PACKET_5_0_1, L_2TAG_PACKET_6_0_1, L_2TAG_PACKET_7_0_1; @@ -619,6 +625,9 @@ address StubGenerator::generate_libmCos() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_dilithium.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_dilithium.cpp index b9590939468..de8f52a3c05 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_dilithium.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_dilithium.cpp @@ -401,10 +401,16 @@ static void storeXmms(Register destination, int offset, const XMMRegister xmmReg // static address generate_dilithiumAlmostNtt_avx(StubGenerator *stubgen, int vector_len, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumAlmostNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -646,6 +652,9 @@ static address generate_dilithiumAlmostNtt_avx(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -657,10 +666,16 @@ static address generate_dilithiumAlmostNtt_avx(StubGenerator *stubgen, // zetas (int[128*8]) = c_rarg1 static address generate_dilithiumAlmostInverseNtt_avx(StubGenerator *stubgen, int vector_len, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumAlmostInverseNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -886,6 +901,9 @@ static address generate_dilithiumAlmostInverseNtt_avx(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -900,10 +918,16 @@ static address generate_dilithiumAlmostInverseNtt_avx(StubGenerator *stubgen, static address generate_dilithiumNttMult_avx(StubGenerator *stubgen, int vector_len, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumNttMult_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); Label L_loop; @@ -972,6 +996,9 @@ static address generate_dilithiumNttMult_avx(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -984,10 +1011,16 @@ static address generate_dilithiumNttMult_avx(StubGenerator *stubgen, static address generate_dilithiumMontMulByConstant_avx(StubGenerator *stubgen, int vector_len, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumMontMulByConstant_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); Label L_loop; @@ -1059,6 +1092,9 @@ static address generate_dilithiumMontMulByConstant_avx(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1073,10 +1109,16 @@ static address generate_dilithiumMontMulByConstant_avx(StubGenerator *stubgen, // multiplier (int) = c_rarg4 static address generate_dilithiumDecomposePoly_avx(StubGenerator *stubgen, int vector_len, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_dilithiumDecomposePoly_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); Label L_loop; @@ -1318,6 +1360,9 @@ static address generate_dilithiumDecomposePoly_avx(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1340,3 +1385,21 @@ void StubGenerator::generate_dilithium_stubs() { generate_dilithiumDecomposePoly_avx(this, vector_len, _masm); } } + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_dilithium(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + // use accessors to correctly identify the relevant addresses + ADD(unshufflePermsAddr(0)); + ADD(unshufflePermsAddr(1)); + ADD(unshufflePermsAddr(2)); + ADD(unshufflePermsAddr(3)); + ADD(unshufflePermsAddr(4)); + ADD(unshufflePermsAddr(5)); + ADD(dilithiumAvx512ConstsAddr(montQInvModRIdx)); + ADD(dilithiumAvx512ConstsAddr(dilithium_qIdx)); + ADD(dilithiumAvx512ConstsAddr(montRSquareModQIdx)); + ADD(dilithiumAvx512ConstsAddr(barrettAddendIdx)); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp index 5130fd2c9d2..2ed9858bf0c 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_exp.cpp @@ -166,8 +166,14 @@ ATTRIBUTE_ALIGNED(4) static const juint _INF[] = address StubGenerator::generate_libmExp() { StubId stub_id = StubId::stubgen_dexp_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2; @@ -381,7 +387,31 @@ address StubGenerator::generate_libmExp() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_exp(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_cv); + ADD(((address)_cv+16)); + ADD(((address)_cv+32)); + ADD(((address)_cv+48)); + ADD(((address)_cv+64)); + ADD(((address)_cv+80)); + ADD(_mmask); + ADD(_bias); + ADD(_Tbl_addr); + ADD(_ALLONES); + ADD(_ebias); + ADD(_XMAX); + ADD(_XMIN); + ADD(_INF); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp index a0962943556..f73c8ed459e 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_fmod.cpp @@ -72,10 +72,16 @@ ATTRIBUTE_ALIGNED(32) static const uint64_t CONST_e307[] = { }; address StubGenerator::generate_libmFmod() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_fmod_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // required for proper stackwalking of RuntimeStub frame if (VM_Version::supports_avx512vlbwdq() && VM_Version::supports_fma()) { // AVX512 version @@ -521,7 +527,22 @@ address StubGenerator::generate_libmFmod() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_fmod(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(CONST_NaN); + ADD(CONST_1p260); + ADD(CONST_MAX); + ADD(CONST_INF); + ADD(CONST_e307); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp index 6f05b1ab5e6..557fe623351 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_ghash.cpp @@ -80,11 +80,17 @@ void StubGenerator::generate_ghash_stubs() { // Single and multi-block ghash operations. address StubGenerator::generate_ghash_processBlocks() { - __ align(CodeEntryAlignment); - Label L_ghash_loop, L_exit; StubId stub_id = StubId::stubgen_ghash_processBlocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + Label L_ghash_loop, L_exit; + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); const Register state = c_rarg0; const Register subkeyH = c_rarg1; @@ -211,17 +217,25 @@ address StubGenerator::generate_ghash_processBlocks() { __ leave(); __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } // Ghash single and multi block operations using AVX instructions address StubGenerator::generate_avx_ghash_processBlocks() { - __ align(CodeEntryAlignment); - StubId stub_id = StubId::stubgen_ghash_processBlocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); // arguments const Register state = c_rarg0; @@ -237,6 +251,9 @@ address StubGenerator::generate_avx_ghash_processBlocks() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -538,3 +555,14 @@ void StubGenerator::generateHtbl_eight_blocks(Register htbl) { } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_ghash(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(GHASH_SHUFFLE_MASK); + ADD(GHASH_LONG_SWAP_MASK); + ADD(GHASH_BYTE_SWAP_MASK); + ADD(GHASH_POLYNOMIAL); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_kyber.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_kyber.cpp index 7d5dee6a5df..347a9b936a8 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_kyber.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_kyber.cpp @@ -400,10 +400,16 @@ static int xmm29_29[] = {29, 29, 29, 29}; // ntt_zetas (short[256]) = c_rarg1 address generate_kyberNtt_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -487,6 +493,9 @@ address generate_kyberNtt_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -496,11 +505,16 @@ address generate_kyberNtt_avx512(StubGenerator *stubgen, // ntt_zetas (short[256]) = c_rarg1 address generate_kyberInverseNtt_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberInverseNtt_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -610,6 +624,9 @@ address generate_kyberInverseNtt_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -621,11 +638,16 @@ address generate_kyberInverseNtt_avx512(StubGenerator *stubgen, // zetas (short[128]) = c_rarg3 address generate_kyberNttMult_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberNttMult_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -731,6 +753,9 @@ address generate_kyberNttMult_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -741,11 +766,16 @@ address generate_kyberNttMult_avx512(StubGenerator *stubgen, // b (short[256]) = c_rarg2 address generate_kyberAddPoly_2_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberAddPoly_2_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -776,6 +806,9 @@ address generate_kyberAddPoly_2_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -787,11 +820,16 @@ address generate_kyberAddPoly_2_avx512(StubGenerator *stubgen, // c (short[256]) = c_rarg3 address generate_kyberAddPoly_3_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberAddPoly_3_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register result = c_rarg0; @@ -830,6 +868,9 @@ address generate_kyberAddPoly_3_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -841,11 +882,16 @@ address generate_kyberAddPoly_3_avx512(StubGenerator *stubgen, // parsedLength (int) = c_rarg3 address generate_kyber12To16_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyber12To16_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register condensed = c_rarg0; @@ -984,6 +1030,9 @@ address generate_kyber12To16_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -993,11 +1042,16 @@ address generate_kyber12To16_avx512(StubGenerator *stubgen, // coeffs (short[256]) = c_rarg0 address generate_kyberBarrettReduce_avx512(StubGenerator *stubgen, MacroAssembler *_masm) { - - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_kyberBarrettReduce_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); const Register coeffs = c_rarg0; @@ -1021,6 +1075,9 @@ address generate_kyberBarrettReduce_avx512(StubGenerator *stubgen, __ mov64(rax, 0); // return 0 __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1038,3 +1095,24 @@ void StubGenerator::generate_kyber_stubs() { } } } + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_kyber(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)(addr)) + // use accessors to correctly identify the relevant addresses + ADD(kyberAvx512NttPermsAddr()); + ADD(kyberAvx512InverseNttPermsAddr()); + ADD(kyberAvx512_nttMultPermsAddr()); + ADD(kyberAvx512_12To16PermsAddr()); + ADD(kyberAvx512_12To16DupAddr()); + ADD(kyberAvx512_12To16ShiftAddr()); + ADD(kyberAvx512_12To16AndAddr()); + ADD(kyberAvx512ConstsAddr(qOffset)); + ADD(kyberAvx512ConstsAddr(qInvModROffset)); + ADD(kyberAvx512ConstsAddr(dimHalfInverseOffset)); + ADD(kyberAvx512ConstsAddr(barretMultiplierOffset)); + ADD(kyberAvx512ConstsAddr(montRSquareModqOffset)); + ADD(kyberAvx512ConstsAddr(f00Offset)); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp index 6b5b4d704e3..8849597c94b 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_log.cpp @@ -177,8 +177,14 @@ ATTRIBUTE_ALIGNED(16) static const juint _coeff[] = address StubGenerator::generate_libmLog() { StubId stub_id = StubId::stubgen_dlog_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2; @@ -359,6 +365,9 @@ address StubGenerator::generate_libmLog() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -516,8 +525,14 @@ ATTRIBUTE_ALIGNED(16) static const juint _coeff_log10[] = address StubGenerator::generate_libmLog10() { StubId stub_id = StubId::stubgen_dlog10_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2; @@ -704,7 +719,32 @@ address StubGenerator::generate_libmLog10() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_log(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_L_tbl); + ADD(_log2); + ADD(((address)_log2+8)); + ADD(_coeff); + ADD(((address)_coeff+16)); + ADD(((address)_coeff+32)); + ADD(_HIGHSIGMASK_log10); + ADD(_LOG10_E); + ADD(((address)_LOG10_E+8)); + ADD(_L_tbl_log10); + ADD(_log2_log10); + ADD(((address)_log2_log10+8)); + ADD(_coeff_log10); + ADD(((address)_coeff_log10+16)); + ADD(((address)_coeff_log10+32)); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp index c80b2d16181..1d0e961c82d 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly1305.cpp @@ -909,10 +909,16 @@ void StubGenerator::poly1305_process_blocks_avx512( // After execution, input and length will point at remaining (unprocessed) data // and accumulator will point to the current accumulator value address StubGenerator::generate_poly1305_processBlocks() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_poly1305_processBlocks_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // Save all 'SOE' registers @@ -1028,6 +1034,10 @@ address StubGenerator::generate_poly1305_processBlocks() { __ leave(); __ ret(0); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -1695,3 +1705,14 @@ void StubGenerator::poly1305_msg_mul_reduce_vec4_avx2( __ vpaddq(A1, A1, YTMP2, Assembler::AVX_256bit); //Add medium 42-bit bits from new blocks to accumulator __ vpaddq(A1, A1, YTMP5, Assembler::AVX_256bit); } +#undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_poly1305(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(POLY1305_PAD_MSG); + ADD(POLY1305_MASK42); + ADD(POLY1305_MASK44); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp index c439e0b370f..4648fe03aa0 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_poly_mont.cpp @@ -558,10 +558,16 @@ void montgomeryMultiplyAVX2(const Register aLimbs, const Register bLimbs, const } address StubGenerator::generate_intpoly_montgomeryMult_P256() { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_intpoly_montgomeryMult_P256_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); if (VM_Version::supports_avx512ifma() && VM_Version::supports_avx512vlbw()) { @@ -620,6 +626,10 @@ address StubGenerator::generate_intpoly_montgomeryMult_P256() { __ leave(); __ ret(0); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } @@ -680,10 +690,16 @@ address StubGenerator::generate_intpoly_assign() { // P521OrderField: 19 = 8 + 8 + 2 + 1 // Special Cases 5, 10, 14, 16, 19 - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_intpoly_assign_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); __ enter(); // Inputs @@ -762,5 +778,24 @@ address StubGenerator::generate_intpoly_assign() { __ bind(L_Done); __ leave(); __ ret(0); + + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } +#undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_poly_mont(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + // use accessors to retrieve all correct addresses + ADD(shift_1L()); + ADD(shift_1R()); + ADD(p256_mask52()); + ADD(mask_limb5()); + ADD(modulus_p256()); + ADD(modulus_p256(1)); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp index 3c3df7e6ac4..5ff09e2b377 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_pow.cpp @@ -760,8 +760,14 @@ ATTRIBUTE_ALIGNED(8) static const juint _DOUBLE0DOT5[] = { address StubGenerator::generate_libmPow() { StubId stub_id = StubId::stubgen_dpow_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_2_0_2, L_2TAG_PACKET_3_0_2; Label L_2TAG_PACKET_4_0_2, L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2, L_2TAG_PACKET_7_0_2; @@ -1859,7 +1865,40 @@ address StubGenerator::generate_libmPow() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_pow(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_HIGHSIGMASK); + ADD(_LOG2_E); + ADD(_HIGHMASK_Y); + ADD((address)_HIGHMASK_Y+8); + ADD(_T_exp); + ADD(_e_coeff); + ADD((address)_e_coeff+16); + ADD((address)_e_coeff+32); + ADD(_coeff_h); + ADD((address)_coeff_h+8); + ADD(_HIGHMASK_LOG_X); + ADD(_HALFMASK); + ADD(_coeff_pow); + ADD((address)_coeff_pow+16); + ADD((address)_coeff_pow+32); + ADD((address)_coeff_pow+48); + ADD((address)_coeff_pow+64); + ADD((address)_coeff_pow+80); + ADD(_L_tbl_pow); + ADD(_log2_pow); + ADD(_DOUBLE2); + ADD(_DOUBLE0); + ADD(_DOUBLE0DOT5); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp index f9d876f34f3..075d25dcac8 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_sha3.cpp @@ -104,10 +104,15 @@ static address generate_sha3_implCompress(StubId stub_id, default: ShouldNotReachHere(); } - + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); const Register buf = c_rarg0; const Register state = c_rarg1; @@ -316,6 +321,9 @@ static address generate_sha3_implCompress(StubId stub_id, __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -326,10 +334,16 @@ static address generate_sha3_implCompress(StubId stub_id, // Performs two keccak() computations in parallel. The steps of the // two computations are executed interleaved. static address generate_double_keccak(StubGenerator *stubgen, MacroAssembler *_masm) { - __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_double_keccak_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = stubgen->load_archive_data(stub_id); + if (start != nullptr) { + return start; + } + __ align(CodeEntryAlignment); StubCodeMark mark(stubgen, stub_id); - address start = __ pc(); + start = __ pc(); const Register state0 = c_rarg0; const Register state1 = c_rarg1; @@ -495,6 +509,9 @@ static address generate_double_keccak(StubGenerator *stubgen, MacroAssembler *_m __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + stubgen->store_archive_data(stub_id, start, __ pc()); + return start; } @@ -508,3 +525,14 @@ void StubGenerator::generate_sha3_stubs() { generate_sha3_implCompress(StubId::stubgen_sha3_implCompressMB_id, this, _masm); } } + +#undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_sha3(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(round_constsAddr()); + ADD(permsAndRotsAddr()); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp index 5290e737581..eaeaea2c566 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_sin.cpp @@ -181,8 +181,14 @@ ATTRIBUTE_ALIGNED(8) static const juint _ALL_ONES[] = address StubGenerator::generate_libmSin() { StubId stub_id = StubId::stubgen_dsin_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; Label L_2TAG_PACKET_4_0_1, L_2TAG_PACKET_5_0_1, L_2TAG_PACKET_6_0_1, L_2TAG_PACKET_7_0_1; @@ -645,7 +651,18 @@ address StubGenerator::generate_libmSin() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_sin(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_ALL_ONES); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp index 86e4ac20176..f6e1d241948 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_sinh.cpp @@ -290,8 +290,14 @@ ATTRIBUTE_ALIGNED(16) static const juint _T2_neg_f[] = address StubGenerator::generate_libmSinh() { StubId stub_id = StubId::stubgen_dsinh_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_2, L_2TAG_PACKET_1_0_2, L_2TAG_PACKET_3_0_2, L_2TAG_PACKET_4_0_2; Label L_2TAG_PACKET_5_0_2, L_2TAG_PACKET_6_0_2; @@ -519,7 +525,32 @@ address StubGenerator::generate_libmSinh() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_sinh(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_L2E); + ADD(_L2E + 8); + ADD(_HALFMASK); + ADD(_Shifter); + ADD(_cv); + ADD(_cv + 16); + ADD(_cv + 32); + ADD(_cv + 48); + ADD(_cv + 64); + ADD(_T2f); + ADD(_T2_neg_f); + ADD(_pv); + ADD(_pv + 16); + ADD(_pv + 32); + ADD(_MASK3); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp index 4f14414652c..3bfa5a7277f 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_tan.cpp @@ -456,8 +456,14 @@ ATTRIBUTE_ALIGNED(8) static const juint _QQ_2_tan[] = address StubGenerator::generate_libmTan() { StubId stub_id = StubId::stubgen_dtan_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; Label L_2TAG_PACKET_4_0_1, L_2TAG_PACKET_5_0_1, L_2TAG_PACKET_6_0_1, L_2TAG_PACKET_7_0_1; @@ -1025,7 +1031,33 @@ address StubGenerator::generate_libmTan() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_tan(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_MUL16); + ADD(_sign_mask_tan); + ADD(_PI32INV_tan); + ADD(_P_1_tan); + ADD(_P_2_tan); + ADD(_P_3_tan); + ADD(_Ctable_tan); + ADD(_MASK_35_tan); + ADD(_Q_11_tan); + ADD(_Q_9_tan); + ADD(_Q_7_tan); + ADD(_Q_5_tan); + ADD(_Q_3_tan); + ADD(_PI_4_tan); + ADD(((address)_PI_4_tan+8)); + ADD(_QQ_2_tan); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp index dce4fbfc455..dcf5f3eb824 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64_tanh.cpp @@ -303,8 +303,14 @@ ATTRIBUTE_ALIGNED(16) static const juint _T2_neg_f[] = address StubGenerator::generate_libmTanh() { StubId stub_id = StubId::stubgen_dtanh_id; + int entry_count = StubInfo::entry_count(stub_id); + assert(entry_count == 1, "sanity check"); + address start = load_archive_data(stub_id); + if (start != nullptr) { + return start; + } StubCodeMark mark(this, stub_id); - address start = __ pc(); + start = __ pc(); Label L_2TAG_PACKET_0_0_1, L_2TAG_PACKET_1_0_1, L_2TAG_PACKET_2_0_1, L_2TAG_PACKET_3_0_1; Label L_2TAG_PACKET_4_0_1, L_2TAG_PACKET_5_0_1; @@ -495,7 +501,32 @@ address StubGenerator::generate_libmTanh() { __ leave(); // required for proper stackwalking of RuntimeStub frame __ ret(0); + // record the stub entry and end + store_archive_data(stub_id, start, __ pc()); + return start; } #undef __ + +#if INCLUDE_CDS +void StubGenerator::init_AOTAddressTable_tanh(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(_L2E); + ADD(_L2E + 8); + ADD(_HALFMASK); + ADD(_ONEMASK); + ADD(_TWOMASK); + ADD(_Shifter); + ADD(_cv); + ADD(_cv + 16); + ADD(_cv + 32); + ADD(_T2_neg_f); + ADD(_pv); + ADD(_pv + 16); + ADD(_pv + 32); + ADD(_MASK3); + ADD(_RMASK); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubRoutines_x86.cpp b/src/hotspot/cpu/x86/stubRoutines_x86.cpp index ee9cea08e64..8696180c512 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86.cpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86.cpp @@ -28,6 +28,10 @@ #include "runtime/stubRoutines.hpp" #include "utilities/globalDefinitions.hpp" #include "crc32c.h" +#include "stubGenerator_x86_64.hpp" +#ifdef COMPILER1 +#include "c1/c1_LIRAssembler.hpp" +#endif // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. @@ -411,3 +415,46 @@ ATTRIBUTE_ALIGNED(64) const julong StubRoutines::x86::_k512_W[] = 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, }; + +#if INCLUDE_CDS + +void StubRoutines::init_AOTAddressTable() { + ResourceMark rm; + GrowableArray external_addresses; + // publish static addresses referred to by main x86 generator and + // auxiliary x86 generators + StubGenerator::init_AOTAddressTable(external_addresses); + // publish external data addresses defined in nested x86 class + StubRoutines::x86::init_AOTAddressTable(external_addresses); +#ifdef COMPILER1 + LIR_Assembler::init_AOTAddressTable(external_addresses); +#endif + AOTCodeCache::publish_external_addresses(external_addresses); +} + +// publish addresses of external data defined in this file which may +// be referenced from stub or code +void StubRoutines::x86::init_AOTAddressTable(GrowableArray& external_addresses) { +#define ADD(addr) external_addresses.append((address)addr); + ADD(&_mxcsr_std); + ADD(&_mxcsr_rz); + ADD(crc_by128_masks_addr()); + ADD(crc_by128_masks_addr() + 16); + ADD(crc_by128_masks_addr() + 32); + // this is added in generic code + // ADD(_crc_table); + ADD(crc_by128_masks_avx512_addr()); + ADD(crc_by128_masks_avx512_addr() + 16); + ADD(crc_by128_masks_avx512_addr() + 32); + ADD(_crc_table_avx512); + ADD(_crc32c_table_avx512); + ADD(_shuf_table_crc32_avx512); + // n.b. call accessor for this one to ensure the table is generated + ADD(crc32c_table_addr()); + ADD(_arrays_hashcode_powers_of_31); + ADD(_k256); + ADD(_k256_W); + ADD(_k512_W); +#undef ADD +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/cpu/x86/stubRoutines_x86.hpp b/src/hotspot/cpu/x86/stubRoutines_x86.hpp index 3654b644131..3c6d75c1d4e 100644 --- a/src/hotspot/cpu/x86/stubRoutines_x86.hpp +++ b/src/hotspot/cpu/x86/stubRoutines_x86.hpp @@ -112,6 +112,8 @@ public: static address arrays_hashcode_powers_of_31() { return (address)_arrays_hashcode_powers_of_31; } static void generate_CRC32C_table(bool is_pclmulqdq_supported); + + static void init_AOTAddressTable(GrowableArray& external_addresses); }; #endif // CPU_X86_STUBROUTINES_X86_HPP diff --git a/src/hotspot/cpu/zero/stubGenerator_zero.cpp b/src/hotspot/cpu/zero/stubGenerator_zero.cpp index 08cb173b507..569a2fa8ca9 100644 --- a/src/hotspot/cpu/zero/stubGenerator_zero.cpp +++ b/src/hotspot/cpu/zero/stubGenerator_zero.cpp @@ -213,7 +213,7 @@ class StubGenerator: public StubCodeGenerator { } public: - StubGenerator(CodeBuffer* code, BlobId blob_id) : StubCodeGenerator(code, blob_id) { + StubGenerator(CodeBuffer* code, BlobId blob_id, AOTStubData *stub_data) : StubCodeGenerator(code, blob_id, stub_data) { switch(blob_id) { case BlobId::stubgen_preuniverse_id: generate_preuniverse_stubs(); @@ -237,8 +237,8 @@ class StubGenerator: public StubCodeGenerator { } }; -void StubGenerator_generate(CodeBuffer* code, BlobId blob_id) { - StubGenerator g(code, blob_id); +void StubGenerator_generate(CodeBuffer* code, BlobId blob_id, AOTStubData *stub_data) { + StubGenerator g(code, blob_id, stub_data); } EntryFrame *EntryFrame::build(const intptr_t* parameters, diff --git a/src/hotspot/cpu/zero/stubRoutines_zero.cpp b/src/hotspot/cpu/zero/stubRoutines_zero.cpp index 9b53f09be5d..196907b061f 100644 --- a/src/hotspot/cpu/zero/stubRoutines_zero.cpp +++ b/src/hotspot/cpu/zero/stubRoutines_zero.cpp @@ -30,3 +30,9 @@ address StubRoutines::crc_table_addr() { ShouldNotCallThis(); return nullptr; } address StubRoutines::crc32c_table_addr() { ShouldNotCallThis(); return nullptr; } + +#if INCLUDE_CDS +// nothing to do for zero +void StubRoutines::init_AOTAddressTable() { +} +#endif // INCLUDE_CDS diff --git a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.cpp index 41cad5af325..11911a48e06 100644 --- a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.cpp +++ b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.cpp @@ -25,4 +25,4 @@ #include "runtime/icache.hpp" #include "utilities/globalDefinitions.hpp" -NOT_PRODUCT(THREAD_LOCAL AArch64ICacheInvalidationContext* AArch64ICacheInvalidationContext::_current_context = nullptr;) +DEBUG_ONLY(THREAD_LOCAL AArch64ICacheInvalidationContext* AArch64ICacheInvalidationContext::_current_context = nullptr;) diff --git a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp index 444b3c3ebd6..5121a875701 100644 --- a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp @@ -82,7 +82,7 @@ class AArch64ICacheInvalidationContext : StackObj { } ~AArch64ICacheInvalidationContext() { - NOT_PRODUCT(_current_context = nullptr); + DEBUG_ONLY(_current_context = nullptr); if (!_has_modified_code || !UseSingleICacheInvalidation) { return; diff --git a/src/hotspot/share/asm/codeBuffer.cpp b/src/hotspot/share/asm/codeBuffer.cpp index c6078c0ceee..6a288e0dad0 100644 --- a/src/hotspot/share/asm/codeBuffer.cpp +++ b/src/hotspot/share/asm/codeBuffer.cpp @@ -1136,7 +1136,7 @@ void AsmRemarks::clear() { uint AsmRemarks::print(uint offset, outputStream* strm) const { uint count = 0; const char* prefix = " ;; "; - const char* remstr = _remarks->lookup(offset); + const char* remstr = (_remarks ? _remarks->lookup(offset) : nullptr); while (remstr != nullptr) { strm->bol(); strm->print("%s", prefix); diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp index 63764dd113a..38f563935e0 100644 --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -278,11 +278,9 @@ bool Runtime1::initialize(BufferBlob* blob) { if (!generate_blob_for(blob, id)) { return false; } - if (id == StubId::c1_forward_exception_id) { - // publish early c1 stubs at this point so later stubs can refer to them - AOTCodeCache::init_early_c1_table(); - } } + // disallow any further c1 stub generation + AOTCodeCache::set_c1_stubs_complete(); // printing #ifndef PRODUCT if (PrintSimpleStubs) { diff --git a/src/hotspot/share/code/aotCodeCache.cpp b/src/hotspot/share/code/aotCodeCache.cpp index e3cbc3c3c8b..d3888d1b7eb 100644 --- a/src/hotspot/share/code/aotCodeCache.cpp +++ b/src/hotspot/share/code/aotCodeCache.cpp @@ -33,13 +33,18 @@ #include "classfile/javaAssertions.hpp" #include "code/aotCodeCache.hpp" #include "code/codeCache.hpp" +#include "gc/shared/barrierSetAssembler.hpp" +#include "gc/shared/barrierSetNMethod.hpp" #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/gcConfig.hpp" #include "logging/logStream.hpp" #include "memory/memoryReserver.hpp" +#include "prims/jvmtiThreadState.hpp" +#include "prims/upcallLinker.hpp" #include "runtime/deoptimization.hpp" #include "runtime/flags/flagSetting.hpp" #include "runtime/globals_extension.hpp" +#include "runtime/icache.hpp" #include "runtime/java.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.inline.hpp" @@ -168,10 +173,13 @@ static uint32_t encode_id(AOTCodeEntry::Kind kind, int id) { } else if (kind == AOTCodeEntry::C1Blob) { assert(StubInfo::is_c1(static_cast