changeset 9434:2d0ba7271ce2

Merge
author andrew
date Tue, 20 Apr 2021 19:34:44 +0100
parents d21a3fc77eca (current diff) 7ab0ec535776 (diff)
children a72255eaef65
files
diffstat 22 files changed, 140 insertions(+), 133 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Tue Apr 20 19:34:44 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/x86/vm/templateTable_x86_64.cpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/os_cpu/linux_ppc/vm/thread_linux_ppc.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/adlc/formssel.cpp	Tue Apr 20 19:34:44 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/classfile/classFileParser.hpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/classfile/classFileParser.hpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Apr 20 19:34:44 2021 +0100
@@ -3466,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, "
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp	Tue Apr 20 19:34:44 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/g1HeapRegionEventSender.cpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1HeapRegionEventSender.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegionSet.hpp	Tue Apr 20 19:34:44 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/jfr/recorder/checkpoint/types/jfrType.cpp	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrType.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/libadt/set.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/memory/filemap.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/memory/filemap.hpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/opto/chaitin.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/opto/compile.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/opto/compile.hpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/opto/output.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/prims/jvmtiTagMap.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/runtime/mutex.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/runtime/synchronizer.cpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/runtime/synchronizer.hpp	Tue Apr 20 19:34:44 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	Wed Mar 17 20:41:55 2021 +0000
+++ b/src/share/vm/utilities/debug.cpp	Tue Apr 20 19:34:44 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()");