better caching anonymous strings JEP-349-branch
authormgronlun
Tue, 03 Sep 2019 11:48:31 +0200
branchJEP-349-branch
changeset 57987 23e3cd901cb6
parent 57985 be121cbf3284
child 57988 6fa0074508ef
better caching anonymous strings
src/hotspot/share/jfr/jfr.cpp
src/hotspot/share/jfr/jfr.hpp
src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp
src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp
src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp
src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp
src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp
src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp
src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp
src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp
src/hotspot/share/jfr/support/jfrThreadLocal.cpp
src/hotspot/share/jfr/support/jfrThreadLocal.hpp
src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp
--- a/src/hotspot/share/jfr/jfr.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/jfr.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -71,15 +71,15 @@
   JfrThreadLocal::on_exit(t);
 }
 
-void Jfr::exclude_thread(Thread* t) {
+void Jfr::exclude_thread(const Thread* t) {
   JfrThreadLocal::exclude(t);
 }
 
-void Jfr::include_thread(Thread* t) {
+void Jfr::include_thread(const Thread* t) {
   JfrThreadLocal::include(t);
 }
 
-bool Jfr::is_excluded(Thread* t) {
+bool Jfr::is_excluded(const Thread* t) {
   return t != NULL && t->jfr_thread_local()->is_excluded();
 }
 
--- a/src/hotspot/share/jfr/jfr.hpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/jfr.hpp	Tue Sep 03 11:48:31 2019 +0200
@@ -48,9 +48,9 @@
   static void on_unloading_classes();
   static void on_thread_start(Thread* thread);
   static void on_thread_exit(Thread* thread);
-  static void exclude_thread(Thread* thread);
-  static bool is_excluded(Thread* thread);
-  static void include_thread(Thread* thread);
+  static void exclude_thread(const Thread* thread);
+  static bool is_excluded(const Thread* thread);
+  static void include_thread(const Thread* thread);
   static void on_java_thread_dismantle(JavaThread* jt);
   static void on_vm_shutdown(bool exception_handler = false);
   static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter);
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -190,7 +190,7 @@
 
   const int array_length = args->array_length();
 
-  if (array_length > 0) {
+  if (array_length >= 0) {
     array_construction(args, result, klass, array_length, CHECK);
   } else {
     object_construction(args, result, klass, THREAD);
--- a/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/leakprofiler/chains/bfsClosure.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -230,8 +230,6 @@
 
 void BFSClosure::do_root(const oop* ref) {
   assert(ref != NULL, "invariant");
-  assert(is_aligned(ref, HeapWordSize), "invariant");
-  assert(*ref != NULL, "invariant");
   if (!_edge_queue->is_full()) {
     _edge_queue->add(NULL, ref);
   }
--- a/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/leakprofiler/chains/dfsClosure.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -178,8 +178,7 @@
 
 void DFSClosure::do_root(const oop* ref) {
   assert(ref != NULL, "invariant");
-  assert(is_aligned(ref, HeapWordSize), "invariant");
-  const oop pointee = *ref;
+  const oop pointee = UnifiedOop::dereference(ref);
   assert(pointee != NULL, "invariant");
   closure_impl(ref, pointee);
 }
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -33,7 +33,6 @@
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
 #include "oops/klass.hpp"
-#include "oops/markOop.hpp"
 #include "oops/oop.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -194,11 +194,11 @@
 }
 
 /*
-* If the buffer was a "lease", release back.
-*
-* The buffer is effectively invalidated for the thread post-return,
-* and the caller should take means to ensure that it is not referenced.
-*/
+ * If the buffer was a lease, release back.
+ *
+ * The buffer is effectively invalidated for the thread post-return,
+ * and the caller should take means to ensure that it is not referenced.
+ */
 static void release(BufferPtr const buffer, Thread* thread) {
   DEBUG_ONLY(assert_release(buffer);)
   buffer->clear_lease();
@@ -335,20 +335,6 @@
   _checkpoint_epoch_state = JfrTraceIdEpoch::epoch();
 }
 
-void JfrCheckpointManager::shift_epoch() {
-  debug_only(const u1 current_epoch = JfrTraceIdEpoch::current();)
-  JfrTraceIdEpoch::shift_epoch();
-  assert(current_epoch != JfrTraceIdEpoch::current(), "invariant");
-}
-
-typedef DiscardOp<DefaultDiscarder<JfrBuffer> > DiscardOperation;
-size_t JfrCheckpointManager::clear() {
-  DiscardOperation discarder(mutexed); // mutexed discard mode
-  process_free_list(discarder, _free_list_mspace);
-  process_free_list(discarder, _epoch_transition_mspace);
-  synchronize_epoch();
-  return discarder.elements();
-}
 
 size_t JfrCheckpointManager::write() {
   const size_t processed = write_mspace<MutexedWriteOp, CompositeOperation>(_free_list_mspace, _chunkwriter);
@@ -356,6 +342,10 @@
   return processed;
 }
 
+size_t JfrCheckpointManager::write_epoch_transition_mspace() {
+  return write_mspace<ExclusiveOp, CompositeOperation>(_epoch_transition_mspace, _chunkwriter);
+}
+
 typedef MutexedWriteOp<WriteOperation> FlushOperation;
 
 size_t JfrCheckpointManager::flush() {
@@ -366,6 +356,15 @@
   return wo.processed();
 }
 
+typedef DiscardOp<DefaultDiscarder<JfrBuffer> > DiscardOperation;
+size_t JfrCheckpointManager::clear() {
+  DiscardOperation discarder(mutexed); // mutexed discard mode
+  process_free_list(discarder, _free_list_mspace);
+  process_free_list(discarder, _epoch_transition_mspace);
+  synchronize_epoch();
+  return discarder.elements();
+}
+
 // Optimization for write_types() and write_threads() is to write
 // directly into the epoch transition mspace because we will immediately
 // serialize and reset this mspace post-write.
@@ -396,11 +395,6 @@
   JfrTypeManager::write_threads(writer);
   return writer.used_size();
 }
-
-size_t JfrCheckpointManager::write_epoch_transition_mspace() {
-  return write_mspace<ExclusiveOp, CompositeOperation>(_epoch_transition_mspace, _chunkwriter);
-}
-
 size_t JfrCheckpointManager::write_constants() {
   write_types();
   write_threads();
@@ -464,3 +458,10 @@
 void JfrCheckpointManager::write_thread_checkpoint(Thread* t) {
   JfrTypeManager::write_thread_checkpoint(t);
 }
+
+void JfrCheckpointManager::shift_epoch() {
+  debug_only(const u1 current_epoch = JfrTraceIdEpoch::current();)
+  JfrTraceIdEpoch::shift_epoch();
+  assert(current_epoch != JfrTraceIdEpoch::current(), "invariant");
+}
+
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -161,7 +161,7 @@
   *size = this->used_size();
   assert(this->start_pos() + *size == this->current_pos(), "invariant");
   write_checkpoint_header(const_cast<u1*>(this->start_pos()), this->used_offset(), _time, (u4)_type, count());
-  _header = false; // the header is already written
+  _header = false; // the header was just written
   if (move) {
     this->seek(_offset);
   }
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -29,11 +29,21 @@
 #include "oops/klass.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/typeArrayOop.inline.hpp"
+#include "runtime/semaphore.hpp"
 #include "runtime/thread.inline.hpp"
 
 static jbyteArray _metadata_blob = NULL;
 static u8 metadata_id = 0;
 static u8 last_written_metadata_id = 0;
+static Semaphore metadata_mutex_semaphore(1);
+
+void JfrMetadataEvent::lock() {
+  metadata_mutex_semaphore.wait();
+}
+
+void JfrMetadataEvent::unlock() {
+  metadata_mutex_semaphore.signal();
+}
 
 static void write_metadata_blob(JfrChunkWriter& chunkwriter, jbyteArray metadata_blob) {
   if (metadata_blob != NULL) {
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.hpp	Tue Sep 03 11:48:31 2019 +0200
@@ -37,6 +37,8 @@
 //
 class JfrMetadataEvent : AllStatic {
  public:
+  static void lock();
+  static void unlock();
   static void write(JfrChunkWriter& writer);
   static void update(jbyteArray metadata);
 };
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -23,7 +23,6 @@
 */
 
 #include "precompiled.hpp"
-#include "classfile/javaClasses.hpp"
 #include "jfr/recorder/checkpoint/types/jfrThreadState.hpp"
 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
 #include "jfr/support/jfrThreadLocal.hpp"
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -88,22 +88,11 @@
   const_cast<Symbol*>(entry->literal())->decrement_refcount();
 }
 
-static const char* resource_str_to_c_heap_str(const char* resource_str) {
-  assert(resource_str != NULL, "invariant");
-  const size_t length = strlen(resource_str);
-  char* const c_string = JfrCHeapObj::new_array<char>(length + 1);
-  assert(c_string != NULL, "invariant");
-  strncpy(c_string, resource_str, length + 1);
-  return c_string;
-}
-
 void JfrSymbolId::link(const CStringEntry* entry) {
   assert(entry != NULL, "invariant");
   assert(entry->id() == 0, "invariant");
   entry->set_id(++_symbol_id_counter);
   entry->set_list_next(_cstring_list);
-  const char* const resource_str = entry->literal();
-  const_cast<CStringEntry*>(entry)->set_literal(resource_str_to_c_heap_str(resource_str));
   _cstring_list = entry;
 }
 
@@ -116,7 +105,7 @@
 void JfrSymbolId::unlink(const CStringEntry* entry) {
   assert(entry != NULL, "invariant");
   if (entry->id() != 1) {
-    JfrCHeapObj::free(const_cast<char*>(entry->literal()), 0);
+    JfrCHeapObj::free(const_cast<char*>(entry->literal()), strlen(entry->literal() + 1));
   }
 }
 
@@ -196,8 +185,7 @@
   sprintf(hash_buf, "/" UINTX_FORMAT, hash);
   const size_t hash_len = strlen(hash_buf);
   const size_t result_len = ik->name()->utf8_length();
-  anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-  assert(anonymous_symbol != NULL, "invariant");
+  anonymous_symbol = JfrCHeapObj::new_array<char>(result_len + hash_len + 1);
   ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
   assert(strlen(anonymous_symbol) == result_len, "invariant");
   strcpy(anonymous_symbol + result_len, hash_buf);
@@ -222,7 +210,8 @@
     return last_anonymous_id;
   }
   last_anonymous_hash = hash;
-  last_anonymous_id = mark(hash, create_unsafe_anonymous_klass_symbol(ik, hash), leakp);
+  const CStringEntry* const entry = _cstring_table->lookup_only(hash);
+  last_anonymous_id = entry != NULL ? entry->id() : mark(hash, create_unsafe_anonymous_klass_symbol(ik, hash), leakp);
   return last_anonymous_id;
 }
 
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -234,15 +234,15 @@
 
 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) {
   const int64_t last_cp_offset = cw.last_checkpoint_offset();
-  const int64_t last_cp_relative_offset = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset();
+  const int64_t delta_to_last_checkpoint = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset();
   cw.reserve(sizeof(u4));
   cw.write<u8>(EVENT_CHECKPOINT);
   cw.write(JfrTicks::now());
-  cw.write<int64_t>((int64_t)0);
-  cw.write(last_cp_relative_offset); // write last checkpoint offset delta
+  cw.write((int64_t)0); // duration
+  cw.write(delta_to_last_checkpoint);
   cw.write<bool>(false); // flushpoint
-  cw.write<u4>((u4)1); // nof types in this checkpoint
-  cw.write<u8>(type_id);
+  cw.write((u4)1); // nof types in this checkpoint
+  cw.write(type_id);
   const int64_t number_of_elements_offset = cw.current_offset();
   cw.reserve(sizeof(u4));
   return number_of_elements_offset;
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderThread.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -98,7 +98,7 @@
   instanceHandle h_thread_oop(THREAD, (instanceOop)result.get_jobject());
   assert(h_thread_oop.not_null(), "invariant");
   // attempt thread start
-  Thread* const t = start_thread(h_thread_oop, recorderthread_entry, THREAD);
+  const Thread* const t = start_thread(h_thread_oop, recorderthread_entry,THREAD);
   if (!HAS_PENDING_EXCEPTION) {
     Jfr::exclude_thread(t);
     cp_manager->register_service_thread(t);
--- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp	Tue Sep 03 11:48:31 2019 +0200
@@ -179,12 +179,12 @@
   return in_ByteSize(offset_of(JfrThreadLocal, _java_event_writer));
 }
 
-void JfrThreadLocal::exclude(Thread* t) {
+void JfrThreadLocal::exclude(const Thread* t) {
   assert(t != NULL, "invariant");
   t->jfr_thread_local()->_excluded = true;
 }
 
-void JfrThreadLocal::include(Thread* t) {
+void JfrThreadLocal::include(const Thread* t) {
   assert(t != NULL, "invariant");
   t->jfr_thread_local()->_excluded = false;
 }
--- a/src/hotspot/share/jfr/support/jfrThreadLocal.hpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/support/jfrThreadLocal.hpp	Tue Sep 03 11:48:31 2019 +0200
@@ -216,10 +216,11 @@
   void set_thread_blob(const JfrBlobHandle& handle);
   const JfrBlobHandle& thread_blob() const;
 
+  static void exclude(const Thread* t);
+  static void include(const Thread* t);
+
   static void on_start(Thread* t);
   static void on_exit(Thread* t);
-  static void exclude(Thread* t);
-  static void include(Thread* t);
 
   // Code generation
   static ByteSize trace_id_offset();
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp	Mon Sep 02 21:08:41 2019 +0200
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.hpp	Tue Sep 03 11:48:31 2019 +0200
@@ -35,11 +35,12 @@
   friend class JfrNotifyClosure;
   friend class JfrJavaEventWriterNotifyOperation;
   friend class JfrJavaEventWriterNotificationClosure;
+  friend class JfrRecorder;
  private:
+  static bool initialize();
   static void notify(JavaThread* jt);
 
  public:
-  static bool initialize();
   static void notify();
   static jobject event_writer(Thread* t);
   static jobject new_event_writer(TRAPS);