Compatibility with gcc-14

Jan Kratochvil (Azul) jkratochvil at azul.com
Wed May 22 15:53:41 UTC 2024


Hello,

jdk8 does not build with gcc-14 (gcc-14.1.1-1.fc40.x86_64):

/home/azul/azul/jdk8u-git/hotspot/src/share/vm/adlc/main.cpp: In function ‘int main(int, char**)’:
/home/azul/azul/jdk8u-git/hotspot/src/share/vm/adlc/main.cpp:61:20: error: ISO C++17 does not allow ‘register’ storage class specifier [-Werror=register]
   61 |     register char *s = argv[i]; // Get option/filename
      |                    ^
/home/azul/azul/jdk8u-git/jdk/src/share/bin/splashscreen_stubs.c: In function ‘DoSplashLoadMemory’:
/home/azul/azul/jdk8u-git/jdk/src/share/bin/splashscreen_stubs.c:64:5: error: returning ‘void *’ from a function with return type ‘int’ makes integer from pointer without a cast [-Wint-conversion]
   64 |     INVOKE(SplashLoadMemory, NULL)(pdata, size);
      |     ^~~~~~
etc.

There are still some warnings present:

/home/azul/azul/jdk8u-git/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c: In function ‘Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImageHeader’:
/home/azul/azul/jdk8u-git/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c:1633:14: warning: variable ‘retval’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
 1633 |     jboolean retval = JNI_FALSE;
      |              ^~~~~~
Those could or do not have to be fixed afterwards.

Should I submit it as 8 backports of various JDK Bugs fixing it in JDK trunk?
I was submitting similar ones for jdk 17/21/22 and those got accepted.


Jan Kratochvil
-------------- next part --------------
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index cecaf5202df..6cabeb501ab 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -280,11 +280,11 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
 address os::current_stack_pointer() {
 #if defined(__clang__) || defined(__llvm__)
-  register void *esp;
+  void *esp;
   __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
   return (address) esp;
 #elif defined(SPARC_WORKS)
-  register void *esp;
+  void *esp;
   __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
   return (address) ((char*)esp + sizeof(long)*2);
 #else
@@ -367,7 +367,7 @@ frame os::get_sender_for_C_frame(frame* fr) {
 
 intptr_t* _get_previous_fp() {
 #if defined(SPARC_WORKS) || defined(__clang__) || defined(__llvm__)
-  register intptr_t **ebp;
+  intptr_t **ebp;
   __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
 #else
   register intptr_t **ebp __asm__ (SPELL_REG_FP);
diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index 12b5ca0acd6..24cb3acf0c7 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -92,16 +92,11 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
 address os::current_stack_pointer() {
 #ifdef SPARC_WORKS
-  register void *esp;
+  void *esp;
   __asm__("mov %%"SPELL_REG_SP", %0":"=r"(esp));
   return (address) ((char*)esp + sizeof(long)*2);
-#elif defined(__clang__)
-  intptr_t* esp;
-  __asm__ __volatile__ ("mov %%"SPELL_REG_SP", %0":"=r"(esp):);
-  return (address) esp;
 #else
-  register void *esp __asm__ (SPELL_REG_SP);
-  return (address) esp;
+  return (address)__builtin_frame_address(0);
 #endif
 }
 
@@ -179,13 +174,13 @@ frame os::get_sender_for_C_frame(frame* fr) {
 
 intptr_t* _get_previous_fp() {
 #ifdef SPARC_WORKS
-  register intptr_t **ebp;
+  intptr_t **ebp;
   __asm__("mov %%"SPELL_REG_FP", %0":"=r"(ebp));
 #elif defined(__clang__)
   intptr_t **ebp;
   __asm__ __volatile__ ("mov %%"SPELL_REG_FP", %0":"=r"(ebp):);
 #else
-  register intptr_t **ebp __asm__ (SPELL_REG_FP);
+  intptr_t **ebp __asm__ (SPELL_REG_FP);
 #endif
   return (intptr_t*) *ebp;   // we want what it points to.
 }
diff --git a/hotspot/src/share/vm/adlc/adlparse.cpp b/hotspot/src/share/vm/adlc/adlparse.cpp
index 31955ff7d3a..de66eb4148b 100644
--- a/hotspot/src/share/vm/adlc/adlparse.cpp
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp
@@ -4564,7 +4564,7 @@ char *ADLParser::get_paren_expr(const char *description, bool include_location)
 // string(still inside the file buffer).  Returns a pointer to the string or
 // NULL if some other token is found instead.
 char *ADLParser::get_ident_common(bool do_preproc) {
-  register char c;
+  char c;
   char *start;                    // Pointer to start of token
   char *end;                      // Pointer to end of token
 
@@ -4762,7 +4762,7 @@ char *ADLParser::get_unique_ident(FormDict& dict, const char* nameDescription){
 // invokes a parse_err if the next token is not an integer.
 // This routine does not leave the integer null-terminated.
 int ADLParser::get_int(void) {
-  register char c;
+  char          c;
   char         *start;            // Pointer to start of token
   char         *end;              // Pointer to end of token
   int           result;           // Storage for integer result
diff --git a/hotspot/src/share/vm/adlc/arena.cpp b/hotspot/src/share/vm/adlc/arena.cpp
index d7e4fc6eb44..8ec3584d1d6 100644
--- a/hotspot/src/share/vm/adlc/arena.cpp
+++ b/hotspot/src/share/vm/adlc/arena.cpp
@@ -79,7 +79,7 @@ Arena::Arena( Arena *a )
 // Total of all Chunks in arena
 size_t Arena::used() const {
   size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this Chunk
-  register Chunk *k = _first;
+  Chunk *k = _first;
   while( k != _chunk) {         // Whilst have Chunks in a row
     sum += k->_len;             // Total size of this Chunk
     k = k->_next;               // Bump along to next Chunk
@@ -93,7 +93,7 @@ void* Arena::grow( size_t x ) {
   // Get minimal required size.  Either real big, or even bigger for giant objs
   size_t len = max(x, Chunk::size);
 
-  register Chunk *k = _chunk;   // Get filled-up chunk address
+  Chunk *k = _chunk;            // Get filled-up chunk address
   _chunk = new (len) Chunk(len);
 
   if( k ) k->_next = _chunk;    // Append new chunk to end of linked list
diff --git a/hotspot/src/share/vm/adlc/dict2.cpp b/hotspot/src/share/vm/adlc/dict2.cpp
index f341a2b67b0..2dc60b250bf 100644
--- a/hotspot/src/share/vm/adlc/dict2.cpp
+++ b/hotspot/src/share/vm/adlc/dict2.cpp
@@ -283,9 +283,9 @@ void Dict::print(PrintKeyOrValue print_key, PrintKeyOrValue print_value) {
 // limited to MAXID characters in length.  Experimental evidence on 150K of
 // C text shows excellent spreading of values for any size hash table.
 int hashstr(const void *t) {
-  register char c, k = 0;
-  register int sum = 0;
-  register const char *s = (const char *)t;
+  char c, k = 0;
+  int sum = 0;
+  const char *s = (const char *)t;
 
   while (((c = s[k]) != '\0') && (k < MAXID-1)) { // Get characters till nul
     c = (char) ((c << 1) + 1);    // Characters are always odd!
diff --git a/hotspot/src/share/vm/adlc/main.cpp b/hotspot/src/share/vm/adlc/main.cpp
index 52044f12d40..bcb3855632c 100644
--- a/hotspot/src/share/vm/adlc/main.cpp
+++ b/hotspot/src/share/vm/adlc/main.cpp
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
 
   // Read command line arguments and file names
   for( int i = 1; i < argc; i++ ) { // For all arguments
-    register char *s = argv[i]; // Get option/filename
+    char *s = argv[i];          // Get option/filename
 
     if( *s++ == '-' ) {         // It's a flag? (not a filename)
       if( !*s ) {               // Stand-alone `-' means stdin
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 14b5749f9a5..393edc93343 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -2929,14 +2929,13 @@ void ConcurrentMark::print_reachable(const char* str,
     return;
   }
 
-  if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) >
-      (JVM_MAXPATHLEN - 1)) {
+  char file_name[JVM_MAXPATHLEN];
+  int snprintf_result = snprintf(file_name, sizeof(file_name),
+                                 "%s.%s", G1PrintReachableBaseFile, str);
+  if (snprintf_result < 0 || snprintf_result >= (int)sizeof(file_name)) {
     gclog_or_tty->print_cr("  #### error: file name too long");
     return;
   }
-
-  char file_name[JVM_MAXPATHLEN];
-  sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str);
   gclog_or_tty->print_cr("  dumping to file %s", file_name);
 
   fileStream fout(file_name);
diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
index 3a5f31ae732..1d78295923c 100644
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
@@ -508,13 +508,13 @@ BytecodeInterpreter::run(interpreterState istate) {
   interpreterState orig = istate;
 #endif
 
-  register intptr_t*        topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */
-  register address          pc = istate->bcp();
-  register jubyte opcode;
-  register intptr_t*        locals = istate->locals();
-  register ConstantPoolCache*    cp = istate->constants(); // method()->constants()->cache()
+  intptr_t*        topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */
+  address          pc = istate->bcp();
+  jubyte opcode;
+  intptr_t*        locals = istate->locals();
+  ConstantPoolCache*    cp = istate->constants(); // method()->constants()->cache()
 #ifdef LOTS_OF_REGS
-  register JavaThread*      THREAD = istate->thread();
+  JavaThread*      THREAD = istate->thread();
 #else
 #undef THREAD
 #define THREAD istate->thread()
@@ -603,7 +603,7 @@ BytecodeInterpreter::run(interpreterState istate) {
 /* 0xF8 */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default,
 /* 0xFC */ &&opc_default,     &&opc_default,        &&opc_default,      &&opc_default
   };
-  register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0];
+  uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0];
 #endif /* USELABELS */
 
 #ifdef ASSERT
diff --git a/hotspot/src/share/vm/libadt/dict.cpp b/hotspot/src/share/vm/libadt/dict.cpp
index 37559a097df..8bef7d6ac49 100644
--- a/hotspot/src/share/vm/libadt/dict.cpp
+++ b/hotspot/src/share/vm/libadt/dict.cpp
@@ -319,9 +319,9 @@ void Dict::print() {
 // limited to MAXID characters in length.  Experimental evidence on 150K of
 // C text shows excellent spreading of values for any size hash table.
 int hashstr(const void *t) {
-  register char c, k = 0;
-  register int32 sum = 0;
-  register const char *s = (const char *)t;
+  char c, k = 0;
+  int32 sum = 0;
+  const char *s = (const char *)t;
 
   while( ((c = *s++) != '\0') && (k < MAXID-1) ) { // Get characters till null or MAXID-1
     c = (c<<1)+1;               // Characters are always odd!
diff --git a/hotspot/src/share/vm/libadt/set.cpp b/hotspot/src/share/vm/libadt/set.cpp
index 9fab2b64b8d..8b511d2e729 100644
--- a/hotspot/src/share/vm/libadt/set.cpp
+++ b/hotspot/src/share/vm/libadt/set.cpp
@@ -73,7 +73,7 @@ char *Set::setstr() const
   uint len = 128;               // Total string space
   char *buf = NEW_C_HEAP_ARRAY(char,len, mtCompiler);// Some initial string space
 
-  register char *s = buf;       // Current working string pointer
+  char *s = buf;                // Current working string pointer
   *s++ = '{';
   *s = '\0';
 
@@ -125,8 +125,8 @@ void Set::print() const
 // Set.  Return the amount of text parsed in "len", or zero in "len".
 int Set::parse(const char *s)
 {
-  register char c;              // Parse character
-  register const char *t = s;   // Save the starting position of s.
+  char c;                       // Parse character
+  const char *t = s;            // Save the starting position of s.
   do c = *s++;                  // Skip characters
   while( c && (c <= ' ') );     // Till no more whitespace or EOS
   if( c != '{' ) return 0;      // Oops, not a Set openner
diff --git a/hotspot/src/share/vm/libadt/vectset.cpp b/hotspot/src/share/vm/libadt/vectset.cpp
index ab80afef681..9f8e7f6cad6 100644
--- a/hotspot/src/share/vm/libadt/vectset.cpp
+++ b/hotspot/src/share/vm/libadt/vectset.cpp
@@ -105,8 +105,8 @@ void VectorSet::grow( uint newsize )
 // Insert a member into an existing Set.
 Set &VectorSet::operator <<= (uint elem)
 {
-  register uint word = elem >> 5;            // Get the longword offset
-  register uint32 mask = 1L << (elem & 31);  // Get bit mask
+  uint word = elem >> 5;            // Get the longword offset
+  uint32 mask = 1L << (elem & 31);  // Get bit mask
 
   if( word >= size )            // Need to grow set?
     grow(elem+1);               // Then grow it
@@ -118,10 +118,10 @@ Set &VectorSet::operator <<= (uint elem)
 // Delete a member from an existing Set.
 Set &VectorSet::operator >>= (uint elem)
 {
-  register uint word = elem >> 5; // Get the longword offset
+  uint word = elem >> 5;          // Get the longword offset
   if( word >= size )              // Beyond the last?
     return *this;                 // Then it's clear & return clear
-  register uint32 mask = 1L << (elem & 31);     // Get bit mask
+  uint32 mask = 1L << (elem & 31);     // Get bit mask
   data[word] &= ~mask;            // Clear bit
   return *this;
 }
@@ -132,8 +132,8 @@ VectorSet &VectorSet::operator &= (const VectorSet &s)
 {
   // NOTE: The intersection is never any larger than the smallest set.
   if( s.size < size ) size = s.size; // Get smaller size
-  register uint32 *u1 = data;   // Pointer to the destination data
-  register uint32 *u2 = s.data; // Pointer to the source data
+  uint32 *u1 = data;   // Pointer to the destination data
+  uint32 *u2 = s.data; // Pointer to the source data
   for( uint i=0; i<size; i++)   // For data in set
     *u1++ &= *u2++;             // Copy and AND longwords
   return *this;                 // Return set
@@ -151,9 +151,9 @@ Set &VectorSet::operator &= (const Set &set)
 VectorSet &VectorSet::operator |= (const VectorSet &s)
 {
   // This many words must be unioned
-  register uint cnt = ((size<s.size)?size:s.size);
-  register uint32 *u1 = data;   // Pointer to the destination data
-  register uint32 *u2 = s.data; // Pointer to the source data
+  uint cnt = ((size<s.size)?size:s.size);
+  uint32 *u1 = data;   // Pointer to the destination data
+  uint32 *u2 = s.data; // Pointer to the source data
   for( uint i=0; i<cnt; i++)    // Copy and OR the two sets
     *u1++ |= *u2++;
   if( size < s.size ) {         // Is set 2 larger than set 1?
@@ -176,9 +176,9 @@ Set &VectorSet::operator |= (const Set &set)
 VectorSet &VectorSet::operator -= (const VectorSet &s)
 {
   // This many words must be unioned
-  register uint cnt = ((size<s.size)?size:s.size);
-  register uint32 *u1 = data;   // Pointer to the destination data
-  register uint32 *u2 = s.data; // Pointer to the source data
+  uint cnt = ((size<s.size)?size:s.size);
+  uint32 *u1 = data;   // Pointer to the destination data
+  uint32 *u2 = s.data; // Pointer to the source data
   for( uint i=0; i<cnt; i++ )   // For data in set
     *u1++ &= ~(*u2++);          // A <-- A & ~B  with longwords
   return *this;                 // Return new set
@@ -199,17 +199,17 @@ Set &VectorSet::operator -= (const Set &set)
 //        1X --  B is a subset of A
 int VectorSet::compare (const VectorSet &s) const
 {
-  register uint32 *u1 = data;   // Pointer to the destination data
-  register uint32 *u2 = s.data; // Pointer to the source data
-  register uint32 AnotB = 0, BnotA = 0;
+  uint32 *u1 = data;   // Pointer to the destination data
+  uint32 *u2 = s.data; // Pointer to the source data
+  uint32 AnotB = 0, BnotA = 0;
   // This many words must be unioned
-  register uint cnt = ((size<s.size)?size:s.size);
+  uint cnt = ((size<s.size)?size:s.size);
 
   // Get bits for both sets
   uint i;                       // Exit value of loop
   for( i=0; i<cnt; i++ ) {      // For data in BOTH sets
-    register uint32 A = *u1++;  // Data from one guy
-    register uint32 B = *u2++;  // Data from other guy
+    uint32 A = *u1++;  // Data from one guy
+    uint32 B = *u2++;  // Data from other guy
     AnotB |= (A & ~B);          // Compute bits in A not B
     BnotA |= (B & ~A);          // Compute bits in B not A
   }
@@ -249,9 +249,9 @@ int VectorSet::disjoint(const Set &set) const
   const VectorSet &s = *(set.asVectorSet());
 
   // NOTE: The intersection is never any larger than the smallest set.
-  register uint small_size = ((size<s.size)?size:s.size);
-  register uint32 *u1 = data;        // Pointer to the destination data
-  register uint32 *u2 = s.data;      // Pointer to the source data
+  uint small_size = ((size<s.size)?size:s.size);
+  uint32 *u1 = data;        // Pointer to the destination data
+  uint32 *u2 = s.data;      // Pointer to the source data
   for( uint i=0; i<small_size; i++)  // For data in set
     if( *u1++ & *u2++ )              // If any elements in common
       return 0;                      // Then not disjoint
@@ -290,10 +290,10 @@ int VectorSet::operator <= (const Set &set) const
 // Test for membership.  A Zero/Non-Zero value is returned!
 int VectorSet::operator[](uint elem) const
 {
-  register uint word = elem >> 5; // Get the longword offset
+  uint word = elem >> 5; // Get the longword offset
   if( word >= size )              // Beyond the last?
     return 0;                     // Then it's clear
-  register uint32 mask = 1L << (elem & 31);  // Get bit mask
+  uint32 mask = 1L << (elem & 31);  // Get bit mask
   return ((data[word] & mask))!=0;           // Return the sense of the bit
 }
 
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index 3cd30a686d5..2692b856f11 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -538,7 +538,7 @@ void Arena::set_size_in_bytes(size_t size) {
 // Total of all Chunks in arena
 size_t Arena::used() const {
   size_t sum = _chunk->length() - (_max-_hwm); // Size leftover in this Chunk
-  register Chunk *k = _first;
+  Chunk *k = _first;
   while( k != _chunk) {         // Whilst have Chunks in a row
     sum += k->length();         // Total size of this Chunk
     k = k->next();              // Bump along to next Chunk
diff --git a/hotspot/src/share/vm/memory/guardedMemory.cpp b/hotspot/src/share/vm/memory/guardedMemory.cpp
index f92c27f089f..26d926dfe4f 100644
--- a/hotspot/src/share/vm/memory/guardedMemory.cpp
+++ b/hotspot/src/share/vm/memory/guardedMemory.cpp
@@ -79,85 +79,3 @@ void GuardedMemory::print_on(outputStream* st) const {
     break;
   }
 }
-
-// test code...
-
-#ifndef PRODUCT
-
-#define GEN_PURPOSE_TAG ((void *) ((uintptr_t)0xf000f000))
-
-static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
-  assert(p != NULL, "NULL pointer given to check");
-  u_char* c = (u_char*) p;
-  GuardedMemory guarded(c);
-  assert(guarded.get_tag() == tag, "Tag is not the same as supplied");
-  assert(guarded.get_user_ptr() == c, "User pointer is not the same as supplied");
-  assert(guarded.get_user_size() == sz, "User size is not the same as supplied");
-  assert(guarded.verify_guards(), "Guard broken");
-}
-
-void GuardedMemory::test_guarded_memory() {
-  // Test the basic characteristics...
-  size_t total_sz = GuardedMemory::get_total_size(1);
-  assert(total_sz > 1 && total_sz >= (sizeof(GuardHeader) + 1 + sizeof(Guard)), "Unexpected size");
-  u_char* basep = (u_char*) os::malloc(total_sz, mtInternal);
-
-  GuardedMemory guarded(basep, 1, GEN_PURPOSE_TAG);
-
-  assert(*basep == badResourceValue, "Expected guard in the form of badResourceValue");
-  u_char* userp = guarded.get_user_ptr();
-  assert(*userp == uninitBlockPad, "Expected uninitialized data in the form of uninitBlockPad");
-  guarded_memory_test_check(userp, 1, GEN_PURPOSE_TAG);
-
-  void* freep = guarded.release_for_freeing();
-  assert((u_char*)freep == basep, "Expected the same pointer guard was ");
-  assert(*userp == freeBlockPad, "Expected user data to be free block padded");
-  assert(!guarded.verify_guards(), "Expected failed");
-  os::free(freep);
-
-  // Test a number of odd sizes...
-  size_t sz = 0;
-  do {
-    void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
-    void* up = guarded.wrap_with_guards(p, sz, (void*)1);
-    memset(up, 0, sz);
-    guarded_memory_test_check(up, sz, (void*)1);
-    os::free(guarded.release_for_freeing());
-    sz = (sz << 4) + 1;
-  } while (sz < (256 * 1024));
-
-  // Test buffer overrun into head...
-  basep = (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
-  guarded.wrap_with_guards(basep, 1);
-  *basep = 0;
-  assert(!guarded.verify_guards(), "Expected failure");
-  os::free(basep);
-
-  // Test buffer overrun into tail with a number of odd sizes...
-  sz = 1;
-  do {
-    void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
-    void* up = guarded.wrap_with_guards(p, sz, (void*)1);
-    memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
-    assert(!guarded.verify_guards(), "Guard was not broken as expected");
-    os::free(guarded.release_for_freeing());
-    sz = (sz << 4) + 1;
-  } while (sz < (256 * 1024));
-
-  // Test wrap_copy/wrap_free...
-  assert(GuardedMemory::free_copy(NULL), "Expected free NULL to be OK");
-
-  const char* str = "Check my bounds out";
-  size_t str_sz = strlen(str) + 1;
-  char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
-  guarded_memory_test_check(str_copy, str_sz, NULL);
-  assert(strcmp(str, str_copy) == 0, "Not identical copy");
-  assert(GuardedMemory::free_copy(str_copy), "Free copy failed to verify");
-
-  void* no_data = NULL;
-  void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
-  assert(GuardedMemory::free_copy(no_data_copy), "Expected valid guards even for no data copy");
-}
-
-#endif // !PRODUCT
-
diff --git a/hotspot/src/share/vm/memory/guardedMemory.hpp b/hotspot/src/share/vm/memory/guardedMemory.hpp
index 66b163c2a73..87339abfac0 100644
--- a/hotspot/src/share/vm/memory/guardedMemory.hpp
+++ b/hotspot/src/share/vm/memory/guardedMemory.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,6 +82,7 @@
  */
 class GuardedMemory : StackObj { // Wrapper on stack
 
+  friend class GuardedMemoryTest;
   // Private inner classes for memory layout...
 
 protected:
@@ -317,10 +318,6 @@ protected:
    */
   static bool free_copy(void* p);
 
-  // Testing...
-#ifndef PRODUCT
-  static void test_guarded_memory(void);
-#endif
 }; // GuardedMemory
 
 #endif // SHARE_VM_MEMORY_GUARDED_MEMORY_HPP
diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp
index 9f2a134f1e6..5796af3a0d6 100644
--- a/hotspot/src/share/vm/opto/mulnode.cpp
+++ b/hotspot/src/share/vm/opto/mulnode.cpp
@@ -46,7 +46,7 @@ uint MulNode::hash() const {
 //------------------------------Identity---------------------------------------
 // Multiplying a one preserves the other argument
 Node *MulNode::Identity( PhaseTransform *phase ) {
-  register const Type *one = mul_id();  // The multiplicative identity
+  const Type *one = mul_id();  // The multiplicative identity
   if( phase->type( in(1) )->higher_equal( one ) ) return in(2);
   if( phase->type( in(2) )->higher_equal( one ) ) return in(1);
 
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index ac29c82934e..88a6a19b09c 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -5148,7 +5148,6 @@ void execute_internal_vm_tests() {
     run_unit_test(arrayOopDesc::test_max_array_length());
     run_unit_test(CollectedHeap::test_is_in());
     run_unit_test(QuickSort::test_quick_sort());
-    run_unit_test(GuardedMemory::test_guarded_memory());
     run_unit_test(AltHashing::test_alt_hash());
     run_unit_test(test_loggc_filename());
     run_unit_test(test_snprintf());
diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp
index 920b8750179..f706954b4db 100644
--- a/hotspot/src/share/vm/utilities/array.hpp
+++ b/hotspot/src/share/vm/utilities/array.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -359,7 +359,7 @@ protected:
   Array(int length, T init) : _length(length) {
     assert(length >= 0, "illegal length");
     for (int i = 0; i < length; i++) {
-      _data[i] = init;
+      data()[i] = init;
     }
   }
 
@@ -367,12 +367,22 @@ protected:
 
   // standard operations
   int  length() const                 { return _length; }
-  T* data()                           { return _data; }
+
+  T* data() {
+    return reinterpret_cast<T*>(
+      reinterpret_cast<char*>(this) + base_offset_in_bytes());
+  }
+
+  const T* data() const {
+    return reinterpret_cast<const T*>(
+      reinterpret_cast<const char*>(this) + base_offset_in_bytes());
+  }
+
   bool is_empty() const               { return length() == 0; }
 
   int index_of(const T& x) const {
     int i = length();
-    while (i-- > 0 && _data[i] != x) ;
+    while (i-- > 0 && data()[i] != x) ;
 
     return i;
   }
@@ -380,9 +390,9 @@ protected:
   // sort the array.
   bool contains(const T& x) const      { return index_of(x) >= 0; }
 
-  T    at(int i) const                 { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return _data[i]; }
-  void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); _data[i] = x; }
-  T*   adr_at(const int i)             { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return &_data[i]; }
+  T    at(int i) const                 { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return data()[i]; }
+  void at_put(const int i, const T& x) { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); data()[i] = x; }
+  T*   adr_at(const int i)             { assert(i >= 0 && i< _length, err_msg("oob: 0 <= %d < %d", i, _length)); return &data()[i]; }
   int  find(const T& x)                { return index_of(x); }
 
   T at_acquire(const int which)              { return OrderAccess::load_acquire(adr_at(which)); }
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index 81866b84099..e0b46f487ab 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -690,10 +690,20 @@ inline BasicType char2type(char c) {
 extern char type2char_tab[T_CONFLICT+1];     // Map a BasicType to a jchar
 inline char type2char(BasicType t) { return (uint)t < T_CONFLICT+1 ? type2char_tab[t] : 0; }
 extern int type2size[T_CONFLICT+1];         // Map BasicType to result stack elements
-extern const char* type2name_tab[T_CONFLICT+1];     // Map a BasicType to a jchar
-inline const char* type2name(BasicType t) { return (uint)t < T_CONFLICT+1 ? type2name_tab[t] : NULL; }
+extern const char* type2name_tab[T_CONFLICT+1];     // Map a BasicType to a char*
 extern BasicType name2type(const char* name);
 
+// Basic support for errors (general debug facilities not defined at this point fo the include phase)
+
+extern void basic_fatal(const char* msg);
+
+inline const char* type2name(BasicType t) {
+  #ifdef ASSERT
+    if ((uint)t >= T_CONFLICT + 1) basic_fatal("invalid type");
+  #endif
+  return type2name_tab[t];
+}
+
 // Auxilary math routines
 // least common multiple
 extern size_t lcm(size_t a, size_t b);
@@ -1059,10 +1069,6 @@ class JavaValue;
 class methodHandle;
 class JavaCallArguments;
 
-// Basic support for errors (general debug facilities not defined at this point fo the include phase)
-
-extern void basic_fatal(const char* msg);
-
 
 //----------------------------------------------------------------------------------------------------
 // Special constants for debugging
diff --git a/hotspot/test/native/memory/test_guardedMemory.cpp b/hotspot/test/native/memory/test_guardedMemory.cpp
new file mode 100644
index 00000000000..3d1c9643876
--- /dev/null
+++ b/hotspot/test/native/memory/test_guardedMemory.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "memory/allocation.hpp"
+#include "memory/allocation.inline.hpp"
+#include "memory/guardedMemory.hpp"
+#include "runtime/os.hpp"
+#include "unittest.hpp"
+
+#define GEN_PURPOSE_TAG ((void *) ((uintptr_t)0xf000f000))
+
+static void guarded_memory_test_check(void* p, size_t sz, void* tag) {
+  ASSERT_TRUE(p != NULL) << "NULL pointer given to check";
+  u_char* c = (u_char*) p;
+  GuardedMemory guarded(c);
+  EXPECT_EQ(guarded.get_tag(), tag) << "Tag is not the same as supplied";
+  EXPECT_EQ(guarded.get_user_ptr(), c) << "User pointer is not the same as supplied";
+  EXPECT_EQ(guarded.get_user_size(), sz) << "User size is not the same as supplied";
+  EXPECT_TRUE(guarded.verify_guards()) << "Guard broken";
+}
+
+class GuardedMemoryTest {
+ public:
+  static size_t get_guard_header_size() {
+    return sizeof (GuardedMemory::GuardHeader);
+  }
+  static size_t get_guard_size() {
+    return sizeof (GuardedMemory::Guard);
+  }
+};
+
+// Test GuardedMemory size
+TEST(GuardedMemory, size) {
+  size_t total_sz = GuardedMemory::get_total_size(1);
+  ASSERT_GT(total_sz, (size_t) 1) << "Unexpected size";
+  ASSERT_GE(total_sz, GuardedMemoryTest::get_guard_header_size() + 1
+          + GuardedMemoryTest::get_guard_size()) << "Unexpected size";
+}
+
+// Test the basic characteristics
+TEST(GuardedMemory, basic) {
+  u_char* basep =
+          (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+  GuardedMemory guarded(basep, 1, GEN_PURPOSE_TAG);
+
+  EXPECT_EQ(badResourceValue, *basep)
+          << "Expected guard in the form of badResourceValue";
+
+  u_char* userp = guarded.get_user_ptr();
+  EXPECT_EQ(uninitBlockPad, *userp)
+          << "Expected uninitialized data in the form of uninitBlockPad";
+  guarded_memory_test_check(userp, 1, GEN_PURPOSE_TAG);
+
+  void* freep = guarded.release_for_freeing();
+  EXPECT_EQ((u_char*) freep, basep) << "Expected the same pointer guard was ";
+  EXPECT_EQ(freeBlockPad, *userp) << "Expected user data to be free block padded";
+  EXPECT_FALSE(guarded.verify_guards());
+  os::free(freep);
+}
+
+// Test a number of odd sizes
+TEST(GuardedMemory, odd_sizes) {
+  u_char* basep =
+          (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+  GuardedMemory guarded(basep, 1, GEN_PURPOSE_TAG);
+
+  size_t sz = 0;
+  do {
+    void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+    void* up = guarded.wrap_with_guards(p, sz, (void*) 1);
+    memset(up, 0, sz);
+    guarded_memory_test_check(up, sz, (void*) 1);
+    if (HasFatalFailure()) {
+      return;
+    }
+
+    os::free(guarded.release_for_freeing());
+    sz = (sz << 4) + 1;
+  } while (sz < (256 * 1024));
+}
+
+// Test buffer overrun into head...
+TEST(GuardedMemory, buffer_overrun_head) {
+  u_char* basep =
+          (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+  GuardedMemory guarded(basep, 1, GEN_PURPOSE_TAG);
+
+  guarded.wrap_with_guards(basep, 1);
+  *basep = 0;
+  EXPECT_FALSE(guarded.verify_guards());
+  os::free(basep);
+}
+
+// Test buffer overrun into tail with a number of odd sizes
+TEST(GuardedMemory, buffer_overrun_tail) {
+  u_char* basep =
+          (u_char*) os::malloc(GuardedMemory::get_total_size(1), mtInternal);
+  GuardedMemory guarded(basep, 1, GEN_PURPOSE_TAG);
+
+  size_t sz = 1;
+  do {
+    void* p = os::malloc(GuardedMemory::get_total_size(sz), mtInternal);
+    void* up = guarded.wrap_with_guards(p, sz, (void*) 1);
+    memset(up, 0, sz + 1); // Buffer-overwrite (within guard)
+    EXPECT_FALSE(guarded.verify_guards()) << "Guard was not broken as expected";
+    os::free(guarded.release_for_freeing());
+    sz = (sz << 4) + 1;
+  } while (sz < (256 * 1024));
+}
+
+// Test wrap_copy/wrap_free
+TEST(GuardedMemory, wrap) {
+  EXPECT_TRUE(GuardedMemory::free_copy(NULL)) << "Expected free NULL to be OK";
+
+  const char* str = "Check my bounds out";
+  size_t str_sz = strlen(str) + 1;
+  char* str_copy = (char*) GuardedMemory::wrap_copy(str, str_sz);
+  guarded_memory_test_check(str_copy, str_sz, NULL);
+  if (HasFatalFailure()) {
+    return;
+  }
+  EXPECT_EQ(0, strcmp(str, str_copy)) << "Not identical copy";
+  EXPECT_TRUE(GuardedMemory::free_copy(str_copy)) << "Free copy failed to verify";
+
+  void* no_data = NULL;
+  void* no_data_copy = GuardedMemory::wrap_copy(no_data, 0);
+  EXPECT_TRUE(GuardedMemory::free_copy(no_data_copy))
+          << "Expected valid guards even for no data copy";
+}
diff --git a/jdk/src/share/bin/splashscreen.h b/jdk/src/share/bin/splashscreen.h
index 3afd68c71e2..2c12e095633 100644
--- a/jdk/src/share/bin/splashscreen.h
+++ b/jdk/src/share/bin/splashscreen.h
@@ -26,7 +26,7 @@
 
 int     DoSplashLoadMemory(void* pdata, int size); /* requires preloading the file */
 int     DoSplashLoadFile(const char* filename);
-void    DoSplashInit(void);
+int     DoSplashInit(void);
 void    DoSplashClose(void);
 void    DoSplashSetFileJarName(const char* fileName, const char* jarName);
 void    DoSplashSetScaleFactor(float scaleFactor);
diff --git a/jdk/src/share/bin/splashscreen_stubs.c b/jdk/src/share/bin/splashscreen_stubs.c
index 9c1f5148c45..fe491b5c2e1 100644
--- a/jdk/src/share/bin/splashscreen_stubs.c
+++ b/jdk/src/share/bin/splashscreen_stubs.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@ extern void* SplashProcAddress(const char* name); /* in java_md.c */
  */
 typedef int (*SplashLoadMemory_t)(void* pdata, int size);
 typedef int (*SplashLoadFile_t)(const char* filename);
-typedef void (*SplashInit_t)(void);
+typedef int (*SplashInit_t)(void);
 typedef void (*SplashClose_t)(void);
 typedef void (*SplashSetFileJarName_t)(const char* fileName,
                                        const char* jarName);
@@ -61,15 +61,15 @@ typedef char* (*SplashGetScaledImageName_t)(const char* fileName,
 #define INVOKEV(name) _INVOKE(name, ,;)
 
 int     DoSplashLoadMemory(void* pdata, int size) {
-    INVOKE(SplashLoadMemory, NULL)(pdata, size);
+    INVOKE(SplashLoadMemory, 0)(pdata, size);
 }
 
 int     DoSplashLoadFile(const char* filename) {
-    INVOKE(SplashLoadFile, NULL)(filename);
+    INVOKE(SplashLoadFile, 0)(filename);
 }
 
-void    DoSplashInit(void) {
-    INVOKEV(SplashInit)();
+int     DoSplashInit(void) {
+    INVOKE(SplashInit, 0)();
 }
 
 void    DoSplashClose(void) {
@@ -87,4 +87,4 @@ void    DoSplashSetScaleFactor(float scaleFactor) {
 char*    DoSplashGetScaledImageName(const char* fileName, const char* jarName,
                                     float* scaleFactor) {
     INVOKE(SplashGetScaledImageName, NULL)(fileName, jarName, scaleFactor);
-}
\ No newline at end of file
+}
diff --git a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
index 7e1d8c99d79..163003c0fb5 100644
--- a/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
+++ b/jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
@@ -2686,7 +2686,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_writeTables
     RELEASE_ARRAYS(env, data, NULL);
 }
 
-static void freeArray(void** arr, jint size) {
+static void freeArray(UINT8** arr, jint size) {
     int i;
     if (arr != NULL) {
         for (i = 0; i < size; i++) {
diff --git a/jdk/src/solaris/bin/java_md_common.c b/jdk/src/solaris/bin/java_md_common.c
index fb446db739a..8f9d199272f 100644
--- a/jdk/src/solaris/bin/java_md_common.c
+++ b/jdk/src/solaris/bin/java_md_common.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,10 +76,13 @@ ProgramExists(char *name)
 static char *
 Resolve(char *indir, char *cmd)
 {
-    char name[PATH_MAX + 2], *real;
+    char name[PATH_MAX + 1], *real;
+    int snprintf_result;
 
-    if ((JLI_StrLen(indir) + JLI_StrLen(cmd) + 1)  > PATH_MAX) return 0;
-    JLI_Snprintf(name, sizeof(name), "%s%c%s", indir, FILE_SEPARATOR, cmd);
+    snprintf_result = JLI_Snprintf(name, sizeof(name), "%s%c%s", indir, FILE_SEPARATOR, cmd);
+    if ((snprintf_result < 0) || (snprintf_result >= (int)sizeof(name))) {
+      return NULL;
+    }
     if (!ProgramExists(name)) return 0;
     real = JLI_MemAlloc(PATH_MAX + 2);
     if (!realpath(name, real))


More information about the jdk8u-dev mailing list