changeset 9442:be4334c66da8

Merge
author andrew
date Fri, 23 Apr 2021 01:47:39 +0100
parents a72255eaef65 (diff) b6054610c065 (current diff)
children a020263526c9
files
diffstat 41 files changed, 427 insertions(+), 246 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/aarch64/vm/c1_Runtime1_aarch64.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -143,9 +143,9 @@
 int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) {
   // if there is any conflict use the stack
   if (arg1 == c_rarg2 || arg1 == c_rarg3 ||
-      arg2 == c_rarg1 || arg1 == c_rarg3 ||
-      arg3 == c_rarg1 || arg1 == c_rarg2) {
-    stp(arg3, arg2, Address(pre(sp, 2 * wordSize)));
+      arg2 == c_rarg1 || arg2 == c_rarg3 ||
+      arg3 == c_rarg1 || arg3 == c_rarg2) {
+    stp(arg3, arg2, Address(pre(sp, -2 * wordSize)));
     stp(arg1, zr, Address(pre(sp, -2 * wordSize)));
     ldp(c_rarg1, zr, Address(post(sp, 2 * wordSize)));
     ldp(c_rarg3, c_rarg2, Address(post(sp, 2 * wordSize)));
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1262,7 +1262,7 @@
   stp(rscratch2, lr, Address(pre(sp, -2 * wordSize)));
 
   mov(r0, reg);
-  mov(rscratch1, (address)b);
+  movptr(rscratch1, (uintptr_t)(address)b);
 
   // call indirectly to solve generation ordering problem
   lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
@@ -1298,7 +1298,7 @@
   } else {
     ldr(r0, addr);
   }
-  mov(rscratch1, (address)b);
+  movptr(rscratch1, (uintptr_t)(address)b);
 
   // call indirectly to solve generation ordering problem
   lea(rscratch2, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
@@ -1993,8 +1993,8 @@
 void MacroAssembler::stop(const char* msg) {
   address ip = pc();
   pusha();
-  mov(c_rarg0, (address)msg);
-  mov(c_rarg1, (address)ip);
+  movptr(c_rarg0, (uintptr_t)(address)msg);
+  movptr(c_rarg1, (uintptr_t)(address)ip);
   mov(c_rarg2, sp);
   mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
   blr(c_rarg3);
--- a/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/aarch64/vm/stubGenerator_aarch64.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1367,10 +1367,10 @@
       __ ldr(temp, Address(a, rscratch2, Address::lsl(exact_log2(size))));
       __ verify_oop(temp);
     } else {
-      __ ldrw(r16, Address(a, rscratch2, Address::lsl(exact_log2(size))));
+      __ ldrw(temp, Address(a, rscratch2, Address::lsl(exact_log2(size))));
       __ decode_heap_oop(temp); // calls verify_oop
     }
-    __ add(rscratch2, rscratch2, size);
+    __ add(rscratch2, rscratch2, 1);
     __ b(loop);
     __ bind(end);
   }
--- a/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/aarch64/vm/vm_version_aarch64.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -138,6 +138,17 @@
     if (PrefetchCopyIntervalInBytes >= 32768)
       PrefetchCopyIntervalInBytes = 32760;
   }
+
+  if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) {
+    warning("AllocatePrefetchDistance must be multiple of 8");
+    AllocatePrefetchDistance &= ~7;
+  }
+
+  if (AllocatePrefetchStepSize & 7) {
+    warning("AllocatePrefetchStepSize must be multiple of 8");
+    AllocatePrefetchStepSize &= ~7;
+  }
+
   FLAG_SET_DEFAULT(UseSSE42Intrinsics, true);
 
   unsigned long auxv = getauxval(AT_HWCAP);
--- a/src/cpu/ppc/vm/frame_ppc.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/ppc/vm/frame_ppc.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -67,8 +67,8 @@
     return false;
   }
 
-  // Unextended sp must be within the stack and above or equal sp
-  bool unextended_sp_safe = (unextended_sp < thread->stack_base()) && (unextended_sp >= sp);
+  // Unextended sp must be within the stack
+  bool unextended_sp_safe = (unextended_sp < thread->stack_base());
 
   if (!unextended_sp_safe) {
     return false;
@@ -76,9 +76,10 @@
 
   // An fp must be within the stack and above (but not equal) sp.
   bool fp_safe = (fp <= thread->stack_base()) &&  (fp > sp);
-  // an interpreter fp must be within the stack and above (but not equal) sp
-  bool fp_interp_safe = (fp <= thread->stack_base()) &&  (fp > sp) &&
-    ((fp - sp) >= (ijava_state_size + top_ijava_frame_abi_size));
+  // An interpreter fp must be within the stack and above (but not equal) sp.
+  // Moreover, it must be at least the size of the ijava_state structure.
+  bool fp_interp_safe = (fp <= thread->stack_base()) && (fp > sp) &&
+    ((fp - sp) >= ijava_state_size);
 
   // We know sp/unextended_sp are safe, only fp is questionable here
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -172,8 +172,8 @@
 #ifdef _LP64
   // if there is any conflict use the stack
   if (arg1 == c_rarg2 || arg1 == c_rarg3 ||
-      arg2 == c_rarg1 || arg1 == c_rarg3 ||
-      arg3 == c_rarg1 || arg1 == c_rarg2) {
+      arg2 == c_rarg1 || arg2 == c_rarg3 ||
+      arg3 == c_rarg1 || arg3 == c_rarg2) {
     push(arg3);
     push(arg2);
     push(arg1);
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -107,10 +107,6 @@
   return Address(rsp,  Interpreter::expr_offset_in_bytes(2));
 }
 
-static inline Address at_tos_p3() {
-  return Address(rsp,  Interpreter::expr_offset_in_bytes(3));
-}
-
 // Condition conversion
 static Assembler::Condition j_not(TemplateTable::Condition cc) {
   switch (cc) {
--- a/src/os_cpu/linux_ppc/vm/thread_linux_ppc.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/os_cpu/linux_ppc/vm/thread_linux_ppc.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -51,21 +51,22 @@
     }
 
     if (ret_frame.is_interpreted_frame()) {
-       frame::ijava_state* istate = ret_frame.get_ijava_state();
-       if (!((Method*)(istate->method))->is_metaspace_object()) {
-         return false;
-       }
-       uint64_t reg_bcp = uc->uc_mcontext.regs->gpr[14/*R14_bcp*/];
-       uint64_t istate_bcp = istate->bcp;
-       uint64_t code_start = (uint64_t)(((Method*)(istate->method))->code_base());
-       uint64_t code_end = (uint64_t)(((Method*)istate->method)->code_base() + ((Method*)istate->method)->code_size());
-       if (istate_bcp >= code_start && istate_bcp < code_end) {
-         // we have a valid bcp, don't touch it, do nothing
-       } else if (reg_bcp >= code_start && reg_bcp < code_end) {
-         istate->bcp = reg_bcp;
+      frame::ijava_state *istate = ret_frame.get_ijava_state();
+      const Method *m = (const Method*)(istate->method);
+      if (m == NULL || !m->is_valid_method()) return false;
+      if (!Metaspace::contains((const void*)m)) return false;
+
+      uint64_t reg_bcp = uc->uc_mcontext.regs->gpr[14/*R14_bcp*/];
+      uint64_t istate_bcp = istate->bcp;
+      uint64_t code_start = (uint64_t)(m->code_base());
+      uint64_t code_end = (uint64_t)(m->code_base() + m->code_size());
+      if (istate_bcp >= code_start && istate_bcp < code_end) {
+        // we have a valid bcp, don't touch it, do nothing
+      } else if (reg_bcp >= code_start && reg_bcp < code_end) {
+        istate->bcp = reg_bcp;
       } else {
-         return false;
-       }
+        return false;
+      }
     }
     if (!ret_frame.safe_for_sender(this)) {
       // nothing else to try if the frame isn't good
--- a/src/share/vm/adlc/formssel.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/adlc/formssel.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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
@@ -3396,7 +3396,7 @@
 // Count occurrences of operands names in the leaves of the instruction
 // match rule.
 void MatchNode::count_instr_names( Dict &names ) {
-  if( !this ) return;
+  if( this == NULL ) return;
   if( _lChild ) _lChild->count_instr_names(names);
   if( _rChild ) _rChild->count_instr_names(names);
   if( !_lChild && !_rChild ) {
@@ -3969,40 +3969,13 @@
 }
 
 int MatchRule::is_ideal_copy() const {
-  if( _rChild ) {
-    const char  *opType = _rChild->_opType;
-#if 1
-    if( strcmp(opType,"CastIP")==0 )
-      return 1;
-#else
-    if( strcmp(opType,"CastII")==0 )
-      return 1;
-    // Do not treat *CastPP this way, because it
-    // may transfer a raw pointer to an oop.
-    // If the register allocator were to coalesce this
-    // into a single LRG, the GC maps would be incorrect.
-    //if( strcmp(opType,"CastPP")==0 )
-    //  return 1;
-    //if( strcmp(opType,"CheckCastPP")==0 )
-    //  return 1;
-    //
-    // Do not treat CastX2P or CastP2X this way, because
-    // raw pointers and int types are treated differently
-    // when saving local & stack info for safepoints in
-    // Output().
-    //if( strcmp(opType,"CastX2P")==0 )
-    //  return 1;
-    //if( strcmp(opType,"CastP2X")==0 )
-    //  return 1;
-#endif
+  if (is_chain_rule(_AD.globalNames()) &&
+      _lChild && strncmp(_lChild->_opType, "stackSlot", 9) == 0) {
+    return 1;
   }
-  if( is_chain_rule(_AD.globalNames()) &&
-      _lChild && strncmp(_lChild->_opType,"stackSlot",9)==0 )
-    return 1;
   return 0;
 }
 
-
 int MatchRule::is_expensive() const {
   if( _rChild ) {
     const char  *opType = _rChild->_opType;
--- a/src/share/vm/adlc/output_h.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/adlc/output_h.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2162,7 +2162,9 @@
 public:
   OutputMachOpcodes(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
     : OutputMap(hpp, cpp, globals, AD, "MachOpcodes"),
-      begin_inst_chain_rule(-1), end_inst_chain_rule(-1), end_instructions(-1)
+      begin_inst_chain_rule(-1), end_inst_chain_rule(-1),
+      begin_rematerialize(-1), end_rematerialize(-1),
+      end_instructions(-1)
   {};
 
   void declaration() { }
--- a/src/share/vm/c1/c1_IR.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/c1/c1_IR.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -578,11 +578,8 @@
     assert(is_visited(cur), "block must be visisted when block is active");
     assert(parent != NULL, "must have parent");
 
-    cur->set(BlockBegin::linear_scan_loop_header_flag);
     cur->set(BlockBegin::backward_branch_target_flag);
 
-    parent->set(BlockBegin::linear_scan_loop_end_flag);
-
     // When a loop header is also the start of an exception handler, then the backward branch is
     // an exception edge. Because such edges are usually critical edges which cannot be split, the
     // loop must be excluded here from processing.
@@ -591,6 +588,10 @@
       _iterative_dominators = true;
       return;
     }
+
+    cur->set(BlockBegin::linear_scan_loop_header_flag);
+    parent->set(BlockBegin::linear_scan_loop_end_flag);
+
     assert(parent->number_of_sux() == 1 && parent->sux_at(0) == cur,
            "loop end blocks must have one successor (critical edges are split)");
 
--- a/src/share/vm/c1/c1_Instruction.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/c1/c1_Instruction.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2124,11 +2124,11 @@
   // creation
   TableSwitch(Value tag, BlockList* sux, int lo_key, ValueStack* state_before, bool is_safepoint)
     : Switch(tag, sux, state_before, is_safepoint)
-  , _lo_key(lo_key) {}
+  , _lo_key(lo_key) { assert(_lo_key <= hi_key(), "integer overflow"); }
 
   // accessors
   int lo_key() const                             { return _lo_key; }
-  int hi_key() const                             { return _lo_key + length() - 1; }
+  int hi_key() const                             { return _lo_key + (length() - 1); }
 };
 
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2520,8 +2520,8 @@
   move_to_phi(x->state());
 
   int lo_key = x->lo_key();
-  int hi_key = x->hi_key();
   int len = x->length();
+  assert(lo_key <= (lo_key + (len - 1)), "integer overflow");
   LIR_Opr value = tag.result();
   if (UseTableRanges) {
     do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
--- a/src/share/vm/classfile/classFileParser.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/classfile/classFileParser.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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
@@ -139,7 +139,7 @@
     u2 _contended_group;
 
     AnnotationCollector(Location location)
-    : _location(location), _annotations_present(0)
+    : _location(location), _annotations_present(0), _contended_group(0)
     {
       assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
     }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -22,10 +22,6 @@
  *
  */
 
-#if !defined(__clang_major__) && defined(__GNUC__)
-#define ATTRIBUTE_PRINTF(x,y) // FIXME, formats are a mess.
-#endif
-
 #include "precompiled.hpp"
 #include "classfile/metadataOnStackMark.hpp"
 #include "code/codeCache.hpp"
@@ -232,7 +228,7 @@
     if (!curr->is_young()) {
       gclog_or_tty->print_cr("### YOUNG REGION " PTR_FORMAT "-" PTR_FORMAT " "
                              "incorrectly tagged (y: %d, surv: %d)",
-                             curr->bottom(), curr->end(),
+                             p2i(curr->bottom()), p2i(curr->end()),
                              curr->is_young(), curr->is_survivor());
       ret = false;
     }
@@ -361,8 +357,8 @@
     while (curr != NULL) {
       gclog_or_tty->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT ", N: " PTR_FORMAT ", age: %4d",
                              HR_FORMAT_PARAMS(curr),
-                             curr->prev_top_at_mark_start(),
-                             curr->next_top_at_mark_start(),
+                             p2i(curr->prev_top_at_mark_start()),
+                             p2i(curr->next_top_at_mark_start()),
                              curr->age_in_surv_rate_group_cond());
       curr = curr->get_next_young_region();
     }
@@ -487,7 +483,7 @@
   RedirtyLoggedCardTableEntryClosure redirty;
   dcqs.apply_closure_to_all_completed_buffers(&redirty);
   dcqs.iterate_closure_all_threads(&redirty, false);
-  gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
+  gclog_or_tty->print_cr("Log entries = " SIZE_FORMAT ", dirty cards = %d.",
                          clear.num_processed(), orig_count);
   guarantee(redirty.num_processed() == clear.num_processed(),
             err_msg("Redirtied " SIZE_FORMAT " cards, bug cleared " SIZE_FORMAT,
@@ -2690,8 +2686,8 @@
         gclog_or_tty->print_cr("Region " HR_FORMAT ", "
                                "HS = " PTR_FORMAT ", should be " PTR_FORMAT,
                                HR_FORMAT_PARAMS(r),
-                               r->humongous_start_region(),
-                               _sh_region);
+                               p2i(r->humongous_start_region()),
+                               p2i(_sh_region));
         ++_failures;
       }
     }
@@ -3002,9 +2998,9 @@
       oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
       if (_g1h->is_obj_dead_cond(obj, _vo)) {
         gclog_or_tty->print_cr("Root location " PTR_FORMAT " "
-                              "points to dead obj " PTR_FORMAT, p, (void*) obj);
+                               "points to dead obj " PTR_FORMAT, p2i(p), p2i(obj));
         if (_vo == VerifyOption_G1UseMarkWord) {
-          gclog_or_tty->print_cr("  Mark word: " PTR_FORMAT, (void*)(obj->mark()));
+          gclog_or_tty->print_cr("  Mark word: " INTPTR_FORMAT, (intptr_t)obj->mark());
         }
         obj->print_on(gclog_or_tty);
         _failures = true;
@@ -3052,9 +3048,9 @@
       // contains the nmethod
       if (!hrrs->strong_code_roots_list_contains(_nm)) {
         gclog_or_tty->print_cr("Code root location " PTR_FORMAT " "
-                              "from nmethod " PTR_FORMAT " not in strong "
-                              "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
-                              p, _nm, hr->bottom(), hr->end());
+                               "from nmethod " PTR_FORMAT " not in strong "
+                               "code roots for region [" PTR_FORMAT "," PTR_FORMAT ")",
+                               p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
         _failures = true;
       }
     }
@@ -3110,7 +3106,7 @@
     _young_ref_counter_closure.reset_count();
     k->oops_do(&_young_ref_counter_closure);
     if (_young_ref_counter_closure.count() > 0) {
-      guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k));
+      guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k)));
     }
   }
 };
@@ -3185,7 +3181,7 @@
       size_t word_sz = o->size();
       gclog_or_tty->print("\nPrinting obj " PTR_FORMAT " of size " SIZE_FORMAT
                           " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n",
-                          (void*) o, word_sz,
+                          p2i(o), word_sz,
                           _g1->isMarkedPrev(o),
                           _g1->isMarkedNext(o),
                           _hr->obj_allocated_since_prev_marking(o));
@@ -3194,7 +3190,7 @@
       int *val;
       for (cur = start; cur < end; cur++) {
         val = (int *) cur;
-        gclog_or_tty->print("\t " PTR_FORMAT ":" PTR_FORMAT "\n", val, *val);
+        gclog_or_tty->print("\t " PTR_FORMAT ": %d\n", p2i(val), *val);
       }
     }
   }
@@ -3232,7 +3228,7 @@
             gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "
                                    "max_live_bytes " SIZE_FORMAT " "
                                    "< calculated " SIZE_FORMAT,
-                                   r->bottom(), r->end(),
+                                   p2i(r->bottom()), p2i(r->end()),
                                    r->max_live_bytes(),
                                  not_dead_yet_cl.live_bytes());
             _failures = true;
@@ -3449,10 +3445,10 @@
   st->print(" %-20s", "garbage-first heap");
   st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
             capacity()/K, used_unlocked()/K);
-  st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
-            _hrm.reserved().start(),
-            _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
-            _hrm.reserved().end());
+  st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
+            p2i(_hrm.reserved().start()),
+            p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords),
+            p2i(_hrm.reserved().end()));
   st->cr();
   st->print("  region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
   uint young_regions = _young_list->length();
@@ -3470,7 +3466,7 @@
 
   // Print the per-region information.
   st->cr();
-  st->print_cr("Heap Regions: (Y=young(eden), SU=young(survivor), "
+  st->print_cr("Heap Regions: (E=young(eden), S=young(survivor), O=old, "
                "HS=humongous(starts), HC=humongous(continues), "
                "CS=collection set, F=free, TS=gc time stamp, "
                "PTAMS=previous top-at-mark-start, "
@@ -4450,7 +4446,7 @@
                                                oop old) {
   assert(obj_in_cs(old),
          err_msg("obj: " PTR_FORMAT " should still be in the CSet",
-                 (HeapWord*) old));
+                 p2i(old)));
   markOop m = old->mark();
   oop forward_ptr = old->forward_to_atomic(old);
   if (forward_ptr == NULL) {
@@ -4485,7 +4481,7 @@
     assert(old == forward_ptr || !obj_in_cs(forward_ptr),
            err_msg("obj: " PTR_FORMAT " forwarded to: " PTR_FORMAT " "
                    "should not be in the CSet",
-                   (HeapWord*) old, (HeapWord*) forward_ptr));
+                   p2i(old), p2i(forward_ptr)));
     return forward_ptr;
   }
 }
@@ -5379,8 +5375,7 @@
         _par_scan_state->push_on_queue(p);
       } else {
         assert(!Metaspace::contains((const void*)p),
-               err_msg("Unexpectedly found a pointer from metadata: "
-                              PTR_FORMAT, p));
+               err_msg("Unexpectedly found a pointer from metadata: " PTR_FORMAT, p2i(p)));
         _copy_non_heap_obj_cl->do_oop(p);
       }
     }
@@ -6062,14 +6057,14 @@
 bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
                                                HeapWord* tams, HeapWord* end) {
   guarantee(tams <= end,
-            err_msg("tams: " PTR_FORMAT " end: " PTR_FORMAT, tams, end));
+            err_msg("tams: " PTR_FORMAT " end: " PTR_FORMAT, p2i(tams), p2i(end)));
   HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
   if (result < end) {
     gclog_or_tty->cr();
     gclog_or_tty->print_cr("## wrong marked address on %s bitmap: " PTR_FORMAT,
-                           bitmap_name, result);
+                           bitmap_name, p2i(result));
     gclog_or_tty->print_cr("## %s tams: " PTR_FORMAT " end: " PTR_FORMAT,
-                           bitmap_name, tams, end);
+                           bitmap_name, p2i(tams), p2i(end));
     return false;
   }
   return true;
@@ -6406,10 +6401,10 @@
         !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length " UINT32_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+        gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                                region_idx,
-                               obj->size()*HeapWordSize,
-                               r->bottom(),
+                               (size_t)obj->size()*HeapWordSize,
+                               p2i(r->bottom()),
                                r->region_num(),
                                r->rem_set()->occupied(),
                                r->rem_set()->strong_code_roots_list_length(),
@@ -6425,13 +6420,13 @@
     guarantee(obj->is_typeArray(),
               err_msg("Only eagerly reclaiming type arrays is supported, but the object "
                       PTR_FORMAT " is not.",
-                      r->bottom()));
+                      p2i(r->bottom())));
 
     if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length " UINT32_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+      gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                              region_idx,
-                             obj->size()*HeapWordSize,
-                             r->bottom(),
+                             (size_t)obj->size()*HeapWordSize,
+                             p2i(r->bottom()),
                              r->region_num(),
                              r->rem_set()->occupied(),
                              r->rem_set()->strong_code_roots_list_length(),
@@ -6585,7 +6580,7 @@
   bool doHeapRegion(HeapRegion* r) {
     if (r->is_young()) {
       gclog_or_tty->print_cr("Region [" PTR_FORMAT ", " PTR_FORMAT ") tagged as young",
-                             r->bottom(), r->end());
+                             p2i(r->bottom()), p2i(r->end()));
       _success = false;
     }
     return false;
@@ -6936,7 +6931,7 @@
       assert(!hr->continuesHumongous(),
              err_msg("trying to add code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
                      " starting at " HR_FORMAT,
-                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
 
       // HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
       hr->add_strong_code_root_locked(_nm);
@@ -6963,7 +6958,7 @@
       assert(!hr->continuesHumongous(),
              err_msg("trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
                      " starting at " HR_FORMAT,
-                     _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+                     p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
 
       hr->remove_strong_code_root(_nm);
     }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -44,6 +44,7 @@
 #include "memory/barrierSet.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/sharedHeap.hpp"
+#include "utilities/macros.hpp"
 #include "utilities/stack.hpp"
 
 // A "G1CollectedHeap" is an implementation of a java heap for HotSpot.
@@ -1150,21 +1151,11 @@
   // Do sanity check on the contents of the in-cset fast test table.
   bool check_cset_fast_test() PRODUCT_RETURN_( return true; );
 
-  // verify_region_sets() performs verification over the region
-  // lists. It will be compiled in the product code to be used when
-  // necessary (i.e., during heap verification).
   void verify_region_sets();
 
   // verify_region_sets_optional() is planted in the code for
-  // list verification in non-product builds (and it can be enabled in
-  // product builds by defining HEAP_REGION_SET_FORCE_VERIFY to be 1).
-#if HEAP_REGION_SET_FORCE_VERIFY
-  void verify_region_sets_optional() {
-    verify_region_sets();
-  }
-#else // HEAP_REGION_SET_FORCE_VERIFY
-  void verify_region_sets_optional() { }
-#endif // HEAP_REGION_SET_FORCE_VERIFY
+  // list verification in debug builds.
+  void verify_region_sets_optional() { DEBUG_ONLY(verify_region_sets();) }
 
 #ifdef ASSERT
   bool is_on_master_free_list(HeapRegion* hr) {
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -22,10 +22,6 @@
  *
  */
 
-#ifndef __clang_major__
-#define ATTRIBUTE_PRINTF(x,y) // FIXME, formats are a mess.
-#endif
-
 #include "precompiled.hpp"
 #include "gc_implementation/g1/concurrentG1Refine.hpp"
 #include "gc_implementation/g1/concurrentMark.hpp"
@@ -288,7 +284,7 @@
   if (confidence_perc > 100) {
     confidence_perc = 100;
     warning("G1ConfidencePercent is set to a value that is too large, "
-            "it's been updated to %u", confidence_perc);
+            "it's been updated to " UINTX_FORMAT, confidence_perc);
   }
   _sigma = (double) confidence_perc / 100.0;
 
@@ -310,7 +306,7 @@
   if (reserve_perc > 50) {
     reserve_perc = 50;
     warning("G1ReservePercent is set to a value that is too large, "
-            "it's been updated to %u", reserve_perc);
+            "it's been updated to " UINTX_FORMAT, reserve_perc);
   }
   _reserve_factor = (double) reserve_perc / 100.0;
   // This will be set when the heap is expanded
@@ -1853,7 +1849,7 @@
     assert(csr->in_collection_set(), "bad CS");
     st->print_cr("  " HR_FORMAT ", P: " PTR_FORMAT "N: " PTR_FORMAT ", age: %4d",
                  HR_FORMAT_PARAMS(csr),
-                 csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(),
+                 p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
                  csr->age_in_surv_rate_group_cond());
     csr = next;
   }
@@ -2219,7 +2215,7 @@
 void TraceGen0TimeData::print_summary_sd(const char* str,
                                          const NumberSeq* seq) const {
   print_summary(str, seq);
-  gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+  gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
                 "(num", seq->num(), seq->sd(), seq->maximum());
 }
 
--- a/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -160,40 +160,43 @@
   } while (0)
 
 
-#define ergo_verbose(_tag_, _action_)                                   \
-  ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
-  ergo_verbose_common(_tag_, _action_, _extra_format_, 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
-                      _arg0_)                                           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, 0, 0, 0, 0, 0)
-
-#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_)                                   \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, 0, 0, 0, 0)
-
-#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_)                           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, 0, 0, 0)
-
-#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, 0, 0)
-
-#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
-  ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
-                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, 0)
-
 #define ergo_verbose6(_tag_, _action_, _extra_format_,                  \
                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)   \
   ergo_verbose_common(_tag_, _action_, _extra_format_,                  \
                       _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
 
+#define ergo_verbose5(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_, _arg3_, _arg4_)           \
+  ergo_verbose6(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
+
+#define ergo_verbose4(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_, _arg3_)                   \
+  ergo_verbose5(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, _arg3_, "")
+
+#define ergo_verbose3(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_, _arg2_)                           \
+  ergo_verbose4(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, _arg2_, "")
+
+#define ergo_verbose2(_tag_, _action_, _extra_format_,                  \
+                      _arg0_, _arg1_)                                   \
+  ergo_verbose3(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, _arg1_, "")
+
+#define ergo_verbose1(_tag_, _action_, _extra_format_,                  \
+                      _arg0_)                                           \
+  ergo_verbose2(_tag_, _action_, _extra_format_ "%s",                   \
+                _arg0_, "")
+
+
+#define ergo_verbose0(_tag_, _action_, _extra_format_)                  \
+  ergo_verbose1(_tag_, _action_, _extra_format_ "%s",                   \
+                "")
+
+#define ergo_verbose(_tag_, _action_)                                   \
+  ergo_verbose0(_tag_, _action_, "")
+
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
--- a/src/share/vm/gc_implementation/g1/g1HeapRegionEventSender.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/g1HeapRegionEventSender.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -33,7 +33,7 @@
   bool doHeapRegion(HeapRegion* r) {
     EventG1HeapRegionInformation evt;
     evt.set_index(r->hrm_index());
-    // XXX TODO evt.set_type(r->get_trace_type());
+    evt.set_type(r->get_trace_type());
     evt.set_start((uintptr_t)r->bottom());
     evt.set_used(r->used());
     evt.commit();
--- a/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -26,18 +26,12 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP
 
 #include "gc_implementation/g1/heapRegion.hpp"
+#include "utilities/macros.hpp"
 
 // Large buffer for some cases where the output might be larger than normal.
 #define HRS_ERR_MSG_BUFSZ 512
 typedef FormatBuffer<HRS_ERR_MSG_BUFSZ> hrs_err_msg;
 
-// Set verification will be forced either if someone defines
-// HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which
-// asserts are compiled in.
-#ifndef HEAP_REGION_SET_FORCE_VERIFY
-#define HEAP_REGION_SET_FORCE_VERIFY defined(ASSERT)
-#endif // HEAP_REGION_SET_FORCE_VERIFY
-
 class hrs_ext_msg;
 
 class HRSMtSafeChecker : public CHeapObj<mtGC> {
@@ -145,13 +139,7 @@
   void verify_next_region(HeapRegion* hr);
   void verify_end();
 
-#if HEAP_REGION_SET_FORCE_VERIFY
-  void verify_optional() {
-    verify();
-  }
-#else // HEAP_REGION_SET_FORCE_VERIFY
-  void verify_optional() { }
-#endif // HEAP_REGION_SET_FORCE_VERIFY
+  void verify_optional() { DEBUG_ONLY(verify();) }
 
   virtual void print_on(outputStream* out, bool print_contents = false);
 };
--- a/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2021, 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
@@ -401,7 +401,9 @@
   start_array()->set_covered_region(new_memregion);
   Universe::heap()->barrier_set()->resize_covered_region(new_memregion);
 
-  // ALWAYS do this last!!
+  // The update of the space's end is done by this call.  As that
+  // makes the new space available for concurrent allocation, this
+  // must be the last step when expanding.
   object_space()->initialize(new_memregion,
                              SpaceDecorator::DontClear,
                              SpaceDecorator::DontMangle);
--- a/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/gc_implementation/shared/mutableSpace.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2021, 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
@@ -28,6 +28,7 @@
 #include "gc_implementation/shared/mutableSpace.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/orderAccess.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
 #endif // INCLUDE_ALL_GCS
@@ -124,7 +125,11 @@
   }
 
   set_bottom(mr.start());
-  set_end(mr.end());
+  // When expanding concurrently with callers of cas_allocate, setting end
+  // makes the new space available for allocation by other threads.  So this
+  // assignment must follow all other configuration and initialization that
+  // might be done for expansion.
+  OrderAccess::release_store_ptr(end_addr(), mr.end());
 
   if (clear_space) {
     clear(mangle_space);
@@ -192,7 +197,11 @@
 // This version is lock-free.
 HeapWord* MutableSpace::cas_allocate(size_t size) {
   do {
-    HeapWord* obj = top();
+    // Read top before end, else the range check may pass when it shouldn't.
+    // If end is read first, other threads may advance end and top such that
+    // current top > old end and current top + size > current end.  Then
+    // pointer_delta underflows, allowing installation of top > current end.
+    HeapWord* obj = (HeapWord*)OrderAccess::load_ptr_acquire(top_addr());
     if (pointer_delta(end(), obj) >= size) {
       HeapWord* new_top = obj + size;
       HeapWord* result = (HeapWord*)Atomic::cmpxchg_ptr(new_top, top_addr(), obj);
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -151,13 +151,12 @@
 }
 
 void MonitorInflateCauseConstant::serialize(JfrCheckpointWriter& writer) {
-  // XXX no such counters. implement?
-//  static const u4 nof_entries = ObjectSynchronizer::inflate_cause_nof;
-//  writer.write_count(nof_entries);
-//  for (u4 i = 0; i < nof_entries; ++i) {
-//    writer.write_key(i);
-//    writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i));
-//  }
+  static const u4 nof_entries = ObjectSynchronizer::inflate_cause_nof;
+  writer.write_count(nof_entries);
+  for (u4 i = 0; i < nof_entries; ++i) {
+    writer.write_key(i);
+    writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i));
+  }
 }
 
 void GCCauseConstant::serialize(JfrCheckpointWriter& writer) {
--- a/src/share/vm/libadt/set.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/libadt/set.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -66,7 +66,7 @@
 // The caller must deallocate the string.
 char *Set::setstr() const
 {
-  if( !this ) return os::strdup("{no set}");
+  if( this == NULL ) return os::strdup("{no set}");
   Set &set = clone();           // Virtually copy the basic set.
   set.Sort();                   // Sort elements for in-order retrieval
 
--- a/src/share/vm/memory/filemap.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/memory/filemap.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -452,7 +452,7 @@
       // close and remove the file. See bug 6372906.
       close();
       remove(_full_path);
-      fail_stop("Unable to write to shared archive file.", NULL);
+      fail_stop("Unable to write to shared archive file.");
     }
   }
   _file_offset += nbytes;
@@ -471,7 +471,7 @@
       // that the written file is the correct length.
       _file_offset -= 1;
       if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) {
-        fail_stop("Unable to seek.", NULL);
+        fail_stop("Unable to seek.");
       }
       char zero = 0;
       write_bytes(&zero, 1);
@@ -542,7 +542,7 @@
   // other reserved memory (like the code cache).
   ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
   if (!rs.is_reserved()) {
-    fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr));
+    fail_continue("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr);
     return rs;
   }
   // the reserved virtual memory is for mapping class data sharing archive
@@ -566,7 +566,7 @@
                               requested_addr, size, si->_read_only,
                               si->_allow_exec);
   if (base == NULL || base != si->_base) {
-    fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i]));
+    fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
     return NULL;
   }
 #ifdef _WINDOWS
@@ -605,7 +605,7 @@
 
 void FileMapInfo::assert_mark(bool check) {
   if (!check) {
-    fail_stop("Mark mismatch while restoring from shared file.", NULL);
+    fail_stop("Mark mismatch while restoring from shared file.");
   }
 }
 
@@ -748,7 +748,7 @@
 void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
   FileMapInfo *map_info = FileMapInfo::current_info();
   if (map_info) {
-    map_info->fail_continue(msg);
+    map_info->fail_continue("%s", msg);
     for (int i = 0; i < MetaspaceShared::n_regions; i++) {
       if (map_info->_header->_space[i]._base != NULL) {
         map_info->unmap_region(i);
@@ -756,6 +756,6 @@
       }
     }
   } else if (DumpSharedSpaces) {
-    fail_stop(msg, NULL);
+    fail_stop("%s", msg);
   }
 }
--- a/src/share/vm/memory/filemap.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/memory/filemap.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -196,8 +196,8 @@
   bool  remap_shared_readonly_as_readwrite();
 
   // Errors.
-  static void fail_stop(const char *msg, ...);
-  static void fail_continue(const char *msg, ...);
+  static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
+  static void fail_continue(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
 
   // Return true if given address is in the mapped shared space.
   bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);
--- a/src/share/vm/opto/chaitin.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/opto/chaitin.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2084,7 +2084,7 @@
 // Dump a register name into a buffer.  Be intelligent if we get called
 // before allocation is complete.
 char *PhaseChaitin::dump_register( const Node *n, char *buf  ) const {
-  if( !this ) {                 // Not got anything?
+  if( this == NULL ) {          // Not got anything?
     sprintf(buf,"N%d",n->_idx); // Then use Node index
   } else if( _node_regs ) {
     // Post allocation, use direct mappings, no LRG info available
--- a/src/share/vm/opto/compile.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/opto/compile.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2084,13 +2084,16 @@
 // They were inserted during parsing (see add_safepoint()) to make
 // infinite loops without calls or exceptions visible to root, i.e.,
 // useful.
-void Compile::remove_root_to_sfpts_edges() {
+void Compile::remove_root_to_sfpts_edges(PhaseIterGVN& igvn) {
   Node *r = root();
   if (r != NULL) {
     for (uint i = r->req(); i < r->len(); ++i) {
       Node *n = r->in(i);
       if (n != NULL && n->is_SafePoint()) {
         r->rm_prec(i);
+        if (n->outcnt() == 0) {
+          igvn.remove_dead_node(n);
+        }
         --i;
       }
     }
@@ -2154,7 +2157,7 @@
 
   // Now that all inlining is over, cut edge from root to loop
   // safepoints
-  remove_root_to_sfpts_edges();
+  remove_root_to_sfpts_edges(igvn);
 
   // Remove the speculative part of types and clean up the graph from
   // the extra CastPP nodes whose only purpose is to carry them. Do
--- a/src/share/vm/opto/compile.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/opto/compile.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -959,7 +959,7 @@
   void inline_incrementally(PhaseIterGVN& igvn);
   void inline_string_calls(bool parse_time);
   void inline_boxing_calls(PhaseIterGVN& igvn);
-  void remove_root_to_sfpts_edges();
+  void remove_root_to_sfpts_edges(PhaseIterGVN& igvn);
 
   // Matching, CFG layout, allocation, code generation
   PhaseCFG*         cfg()                       { return _cfg; }
--- a/src/share/vm/opto/output.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/opto/output.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -28,6 +28,7 @@
 #include "code/debugInfo.hpp"
 #include "code/debugInfoRec.hpp"
 #include "compiler/compileBroker.hpp"
+#include "compiler/disassembler.hpp"
 #include "compiler/oopMap.hpp"
 #include "memory/allocation.inline.hpp"
 #include "opto/callnode.hpp"
@@ -1510,8 +1511,17 @@
       }
 
 #ifdef ASSERT
-      if (n->size(_regalloc) < (current_offset-instr_offset)) {
+      uint n_size = n->size(_regalloc);
+      if (n_size < (current_offset-instr_offset)) {
+        MachNode* mach = n->as_Mach();
         n->dump();
+        mach->dump_format(_regalloc, tty);
+        tty->print_cr(" n_size (%d), current_offset (%d), instr_offset (%d)", n_size, current_offset, instr_offset);
+        Disassembler::decode(cb->insts_begin() + instr_offset, cb->insts_begin() + current_offset + 1, tty);
+        tty->print_cr(" ------------------- ");
+        BufferBlob* blob = this->scratch_buffer_blob();
+        address blob_begin = blob->content_begin();
+        Disassembler::decode(blob_begin, blob_begin + n_size + 1, tty);
         assert(false, "wrong size of mach node");
       }
 #endif
--- a/src/share/vm/prims/jvmtiTagMap.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/prims/jvmtiTagMap.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -2805,6 +2805,7 @@
   return true;
 }
 
+#ifdef ASSERT
 // verify that a static oop field is in range
 static inline bool verify_static_oop(InstanceKlass* ik,
                                      oop mirror, int offset) {
@@ -2819,6 +2820,7 @@
     return false;
   }
 }
+#endif // #ifdef ASSERT
 
 // a class references its super class, interfaces, class loader, ...
 // and finally its static fields
--- a/src/share/vm/runtime/mutex.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/runtime/mutex.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -283,16 +283,6 @@
   return x & 0x7FFFFFFF ;
 }
 
-static inline jint MarsagliaXOR (jint * const a) {
-  jint x = *a ;
-  if (x == 0) x = UNS(a)|1 ;
-  x ^= x << 6;
-  x ^= ((unsigned)x) >> 21;
-  x ^= x << 7 ;
-  *a = x ;
-  return x & 0x7FFFFFFF ;
-}
-
 static int Stall (int its) {
   static volatile jint rv = 1 ;
   volatile int OnFrame = 0 ;
--- a/src/share/vm/runtime/synchronizer.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/runtime/synchronizer.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -216,7 +216,9 @@
      }
   }
 
-  ObjectSynchronizer::inflate(THREAD, object)->exit (true, THREAD) ;
+  ObjectSynchronizer::inflate(THREAD,
+                              object,
+                              inflate_cause_vm_internal)->exit(true, THREAD);
 }
 
 // -----------------------------------------------------------------------------
@@ -258,7 +260,9 @@
   // must be non-zero to avoid looking like a re-entrant lock,
   // and must not look locked either.
   lock->set_displaced_header(markOopDesc::unused_mark());
-  ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);
+  ObjectSynchronizer::inflate(THREAD,
+                              obj(),
+                              inflate_cause_monitor_enter)->enter(THREAD);
 }
 
 // This routine is used to handle interpreter/compiler slow case
@@ -288,7 +292,9 @@
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
 
-  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
+  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
+                                                       obj(),
+                                                       inflate_cause_vm_internal);
 
   return monitor->complete_exit(THREAD);
 }
@@ -301,7 +307,9 @@
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
 
-  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
+  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
+                                                       obj(),
+                                                       inflate_cause_vm_internal);
 
   monitor->reenter(recursion, THREAD);
 }
@@ -316,7 +324,7 @@
     assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
   }
   THREAD->set_current_pending_monitor_is_from_java(false);
-  ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);
+  ObjectSynchronizer::inflate(THREAD, obj(), inflate_cause_jni_enter)->enter(THREAD);
   THREAD->set_current_pending_monitor_is_from_java(true);
 }
 
@@ -342,7 +350,9 @@
   }
   assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
 
-  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj);
+  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
+                                                       obj,
+                                                       inflate_cause_jni_exit);
   // If this thread has locked the object, exit the monitor.  Note:  can't use
   // monitor->check(CHECK); must exit even if an exception is pending.
   if (monitor->check(THREAD)) {
@@ -385,7 +395,10 @@
     TEVENT (wait - throw IAX) ;
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
   }
-  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
+  ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD,
+                                                       obj(),
+                                                       inflate_cause_wait);
+
   DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis);
   monitor->wait(millis, true, THREAD);
 
@@ -404,7 +417,9 @@
     TEVENT (wait - throw IAX) ;
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative");
   }
-  ObjectSynchronizer::inflate(THREAD, obj()) -> wait(millis, false, THREAD) ;
+  ObjectSynchronizer::inflate(THREAD,
+                              obj(),
+                              inflate_cause_wait)->wait(millis, false, THREAD) ;
 }
 
 void ObjectSynchronizer::notify(Handle obj, TRAPS) {
@@ -417,7 +432,9 @@
   if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
     return;
   }
-  ObjectSynchronizer::inflate(THREAD, obj())->notify(THREAD);
+  ObjectSynchronizer::inflate(THREAD,
+                              obj(),
+                              inflate_cause_notify)->notify(THREAD);
 }
 
 // NOTE: see comment of notify()
@@ -431,7 +448,9 @@
   if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
     return;
   }
-  ObjectSynchronizer::inflate(THREAD, obj())->notifyAll(THREAD);
+  ObjectSynchronizer::inflate(THREAD,
+                              obj(),
+                              inflate_cause_notify)->notifyAll(THREAD);
 }
 
 // -----------------------------------------------------------------------------
@@ -686,7 +705,7 @@
   }
 
   // Inflate the monitor to set hash code
-  monitor = ObjectSynchronizer::inflate(Self, obj);
+  monitor = ObjectSynchronizer::inflate(Self, obj, inflate_cause_hash_code);
   // Load displaced header and check it has hash code
   mark = monitor->header();
   assert (mark->is_neutral(), "invariant") ;
@@ -1183,12 +1202,29 @@
     TEVENT (omFlush) ;
 }
 
+const char* ObjectSynchronizer::inflate_cause_name(const InflateCause cause) {
+  switch (cause) {
+    case inflate_cause_vm_internal:    return "VM Internal";
+    case inflate_cause_monitor_enter:  return "Monitor Enter";
+    case inflate_cause_wait:           return "Monitor Wait";
+    case inflate_cause_notify:         return "Monitor Notify";
+    case inflate_cause_hash_code:      return "Monitor Hash Code";
+    case inflate_cause_jni_enter:      return "JNI Monitor Enter";
+    case inflate_cause_jni_exit:       return "JNI Monitor Exit";
+    default:
+      ShouldNotReachHere();
+  }
+  return "Unknown";
+}
+
 static void post_monitor_inflate_event(EventJavaMonitorInflate* event,
-                                       const oop obj) {
+                                       const oop obj,
+                                       const ObjectSynchronizer::InflateCause cause) {
   assert(event != NULL, "invariant");
   assert(event->should_commit(), "invariant");
   event->set_monitorClass(obj->klass());
   event->set_address((uintptr_t)(void*)obj);
+  event->set_cause((u1)cause);
   event->commit();
 }
 
@@ -1200,7 +1236,9 @@
     assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header");
     return mark->monitor();
   }
-  return ObjectSynchronizer::inflate(Thread::current(), obj);
+  return ObjectSynchronizer::inflate(Thread::current(),
+                                     obj,
+                                     inflate_cause_vm_internal);
 }
 
 
@@ -1208,7 +1246,9 @@
 // multiple locks occupy the same $ line.  Padding might be appropriate.
 
 
-ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self, oop object) {
+ObjectMonitor * ATTR ObjectSynchronizer::inflate (Thread * Self,
+                                                  oop object,
+                                                  const InflateCause cause) {
   // Inflate mutates the heap ...
   // Relaxing assertion for bug 6320749.
   assert (Universe::verify_in_progress() ||
@@ -1347,7 +1387,7 @@
             }
           }
           if (event.should_commit()) {
-            post_monitor_inflate_event(&event, object);
+            post_monitor_inflate_event(&event, object, cause);
           }
           return m ;
       }
@@ -1400,7 +1440,7 @@
         }
       }
       if (event.should_commit()) {
-        post_monitor_inflate_event(&event, object);
+        post_monitor_inflate_event(&event, object, cause);
       }
       return m ;
   }
--- a/src/share/vm/runtime/synchronizer.hpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/runtime/synchronizer.hpp	Fri Apr 23 01:47:39 2021 +0100
@@ -42,6 +42,18 @@
     owner_none,
     owner_other
   } LockOwnership;
+
+  typedef enum {
+    inflate_cause_vm_internal = 0,
+    inflate_cause_monitor_enter = 1,
+    inflate_cause_wait = 2,
+    inflate_cause_notify = 3,
+    inflate_cause_hash_code = 4,
+    inflate_cause_jni_enter = 5,
+    inflate_cause_jni_exit = 6,
+    inflate_cause_nof = 7 // Number of causes
+  } InflateCause;
+
   // exit must be implemented non-blocking, since the compiler cannot easily handle
   // deoptimization at monitor exit. Hence, it does not take a Handle argument.
 
@@ -90,9 +102,10 @@
   static void omFlush   (Thread * Self) ;
 
   // Inflate light weight monitor to heavy weight monitor
-  static ObjectMonitor* inflate(Thread * Self, oop obj);
+  static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause);
   // This version is only for internal use
   static ObjectMonitor* inflate_helper(oop obj);
+  static const char* inflate_cause_name(const InflateCause cause);
 
   // Returns the identity hash value for an oop
   // NOTE: It may cause monitor inflation
--- a/src/share/vm/utilities/debug.cpp	Tue Apr 20 19:19:11 2021 +0100
+++ b/src/share/vm/utilities/debug.cpp	Fri Apr 23 01:47:39 2021 +0100
@@ -687,6 +687,7 @@
   tty->print_cr("  pns(void* sp, void* fp, void* pc)  - print native (i.e. mixed) stack trace. E.g.");
   tty->print_cr("                   pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or");
   tty->print_cr("                   pns($sp, $ebp, $pc) on Linux/x86 or");
+  tty->print_cr("                   pns($sp, $fp, $pc)  on Linux/AArch64 or");
   tty->print_cr("                   pns($sp, 0, $pc)    on Linux/ppc64 or");
   tty->print_cr("                   pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC");
   tty->print_cr("                 - in gdb do 'set overload-resolution off' before calling pns()");
--- a/test/Makefile	Tue Apr 20 19:19:11 2021 +0100
+++ b/test/Makefile	Fri Apr 23 01:47:39 2021 +0100
@@ -288,6 +288,9 @@
 # Ignore tests are not run and completely silent about it
 JTREG_IGNORE_OPTION = -ignore:quiet
 JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION)
+# Multiply by 4 the timeout factor
+JTREG_TIMEOUT_OPTION =  -timeoutFactor:4
+JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION)
 # Add any extra options
 JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
 # Set other vm and test options
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoop.jasm	Fri Apr 23 01:47:39 2021 +0100
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ *
+ */
+
+super public class TestRangeCheckExceptionHandlerLoop
+	version 51:0
+{
+
+
+public Method "<init>":"()V"
+	stack 1 locals 1
+{
+		aload_0;
+		invokespecial	Method java/lang/Object."<init>":"()V";
+		return;
+}
+
+/* This method has an irreducible loop, with 2 entries, one is the exception handler
+
+    static void test(boolean flag, int[] array, Exception exception) throws Exception {
+        int i = 0;
+        if (flag) {
+            try {
+                throw exception;
+            } catch(Exception e) {
+                array[i] = 0;
+                i++;
+            }
+        }
+        if (i < 10) {
+            throw exception; // caught by exception handler above as well
+        }
+    }
+*/
+public static Method test:"(Z[ILjava/lang/Exception;)V"
+	throws java/lang/Exception
+	stack 3 locals 5
+{
+		iconst_0;
+		istore_3;
+		iload_0;
+		ifeq	L17;
+		try t0;
+		aload_2;
+		athrow;
+		endtry t0;
+		catch t0 java/lang/Exception;
+		catch t1 java/lang/Exception;
+		stack_frame_type full;
+		locals_map int, class "[I", class java/lang/Exception, int;
+		stack_map class java/lang/Exception;
+		astore	4;
+		aload_1;
+		iload_3;
+		iconst_0;
+		iastore;
+		iinc	3, 1;
+	L17:	stack_frame_type same;
+		iload_3;
+		bipush	10;
+		if_icmpge	L25;
+		try t1;
+		aload_2;
+		athrow;
+		endtry t1;
+	L25:	stack_frame_type same;
+		return;
+}
+} // end Class TestRangeCheckExceptionHandlerLoop
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/rangechecks/TestRangeCheckExceptionHandlerLoopMain.java	Fri Apr 23 01:47:39 2021 +0100
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8134883
+ * @summary C1's range check elimination breaks with a non-natural loop that an exception handler as one entry
+ * @compile TestRangeCheckExceptionHandlerLoop.jasm
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckExceptionHandlerLoopMain
+ */
+
+public class TestRangeCheckExceptionHandlerLoopMain {
+    public static void main(String[] args) throws Exception {
+        Exception exception = new Exception();
+        int[] array = new int[10];
+        for (int i = 0; i < 20000; i++) {
+            TestRangeCheckExceptionHandlerLoop.test(false, array, exception);
+        }
+    }
+}
--- a/test/gc/arguments/TestAggressiveHeap.java	Tue Apr 20 19:19:11 2021 +0100
+++ b/test/gc/arguments/TestAggressiveHeap.java	Fri Apr 23 01:47:39 2021 +0100
@@ -51,13 +51,18 @@
     // Option requires at least 256M, else error during option processing.
     private static final long minMemory = 256 * 1024 * 1024;
 
+    // Setting the heap to half of the physical memory is not suitable for
+    // a test environment with many tests running concurrently, setting to
+    // half of the required size instead.
+    private static final String heapSizeOption = "-Xmx128M";
+
     // bool UseParallelGC := true {product}
     private static final String parallelGCPattern =
         " *bool +UseParallelGC *:= *true +\\{product\\}";
 
     private static void testFlag() throws Exception {
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            option, "-XX:+PrintFlagsFinal", "-version");
+            option, heapSizeOption, "-XX:+PrintFlagsFinal", "-version");
 
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
--- a/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Tue Apr 20 19:19:11 2021 +0100
+++ b/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java	Fri Apr 23 01:47:39 2021 +0100
@@ -96,11 +96,18 @@
                 .getActualMemoryUsage();
 
         test.allocate();
-        for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD;
-             i++) {
+        for (int i = 0; i <= SurvivorAlignmentTestMain.MAX_TENURING_THRESHOLD; i++) {
             SurvivorAlignmentTestMain.WHITE_BOX.youngGC();
         }
 
+        // Sometimes we see that data unrelated to the test has been allocated during
+        // the loop. This data is included in the expectedMemoryUsage since we look
+        // through all threads to see what they allocated. If this data is still in
+        // the survivor area however, it should not be included in expectedMemoryUsage
+        // since the verification below only look at what's in tenured space.
+        expectedMemoryUsage -= SurvivorAlignmentTestMain.getAlignmentHelper(
+                                   SurvivorAlignmentTestMain.HeapSpace.SURVIVOR)
+                                   .getActualMemoryUsage();
         test.verifyMemoryUsage(expectedMemoryUsage);
     }
 }
--- a/test/runtime/Metaspace/FragmentMetaspace.java	Tue Apr 20 19:19:11 2021 +0100
+++ b/test/runtime/Metaspace/FragmentMetaspace.java	Fri Apr 23 01:47:39 2021 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, 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
@@ -25,7 +25,7 @@
  * @test
  * @library /runtime/testlibrary
  * @build GeneratedClassLoader
- * @run main/othervm/timeout=200 FragmentMetaspace
+ * @run main/othervm/timeout=200 -Xmx300m FragmentMetaspace
  */
 
 import java.io.IOException;
@@ -38,25 +38,34 @@
  */
 public class FragmentMetaspace {
 
+    public static Class<?> c;
+
     public static void main(String... args) {
-        runGrowing(Long.valueOf(System.getProperty("time", "80000")));
+        runGrowing(Long.valueOf(System.getProperty("time", "80000")),
+            Integer.valueOf(System.getProperty("iterations", "200")));
         // try to clean up and unload classes to decrease
         // class verification time in debug vm
         System.gc();
     }
 
-    private static void runGrowing(long time) {
+    private static void runGrowing(long time, int iterations) {
         long startTime = System.currentTimeMillis();
-        for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+        for (int i = 0; System.currentTimeMillis() < startTime + time && i < iterations; ++i) {
             try {
                 GeneratedClassLoader gcl = new GeneratedClassLoader();
 
-                Class<?> c = gcl.getGeneratedClasses(i, 100)[0];
+                // getGeneratedClasses throws a RuntimeException in cases where
+                // the javac exit code is not 0. If the original reason for the exception is
+                // a "java.lang.OutOfMemoryError: Java heap space",
+                // increase the heap size in the @run tag and rerun the test.
+                // The heap can be exhausted by this test, but heap exhaustion
+                // is not a failure mode of this test and should be ignored.
+                c = gcl.getGeneratedClasses(i, 100)[0];
                 c.newInstance();
                 c = null;
 
                 gcl = null;
-            } catch (IOException|InstantiationException|IllegalAccessException ex) {
+            } catch (IOException | InstantiationException | IllegalAccessException ex) {
                 throw new RuntimeException(ex);
             }
         }