< prev index next >

src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp

Print this page
@@ -24,45 +24,86 @@
  
  #include "precompiled.hpp"
  #include "classfile/classLoaderData.inline.hpp"
  #include "classfile/javaClasses.inline.hpp"
  #include "classfile/symbolTable.hpp"
+ #include "classfile/systemDictionary.hpp"
+ #include "jfr/jni/jfrJavaSupport.hpp"
  #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
  #include "jfr/utilities/jfrTypes.hpp"
+ #include "oops/access.inline.hpp"
  #include "oops/arrayKlass.inline.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/instanceKlass.inline.hpp"
  #include "oops/method.hpp"
  #include "oops/oop.inline.hpp"
  #include "runtime/atomic.hpp"
  #include "runtime/vm_version.hpp"
  #include "runtime/jniHandles.inline.hpp"
  #include "runtime/thread.inline.hpp"
  #include "utilities/debug.hpp"
+ #include "utilities/exceptions.hpp"
  
-  // returns updated value
- static traceid atomic_inc(traceid volatile* const dest) {
+ static int next_tid_offset = invalid_offset;
+ static jclass thread_identifiers = NULL;
+ 
+ static bool setup_thread_identifiers(TRAPS) {
+   const char class_name[] = "java/lang/Thread$ThreadIdentifiers";
+   Symbol * const k_sym = SymbolTable::new_symbol(class_name);
+   assert(k_sym != NULL, "invariant");
+   Klass * klass = SystemDictionary::resolve_or_fail(k_sym, true, CHECK_false);
+   assert(klass != NULL, "invariant");
+   assert(klass->is_instance_klass(), "invariant");
+   assert(InstanceKlass::cast(klass)->is_initialized(), "invariant");
+   const char next_tid_name[] = "nextTid";
+   Symbol * const next_tid_symbol = SymbolTable::new_symbol(next_tid_name);
+   assert(next_tid_symbol != NULL, "invariant");
+   assert(invalid_offset == next_tid_offset, "invariant");
+   if (!JfrJavaSupport::compute_field_offset(next_tid_offset, klass, next_tid_symbol, vmSymbols::long_signature(), true)) {
+     return false;
+   }
+   assert(invalid_offset != next_tid_offset, "invariant");
+   assert(thread_identifiers == NULL, "invariant");
+   thread_identifiers = (jclass)JfrJavaSupport::global_jni_handle(klass->java_mirror(), THREAD);
+   return thread_identifiers != NULL;
+ }
+ 
+ bool JfrTraceId::initialize() {
+   static bool initialized = false;
+   if (!initialized) {
+     initialized = setup_thread_identifiers(JavaThread::current());
+   }
+   return initialized;
+ }
+ 
+ static traceid next_thread_id() {
+   assert(thread_identifiers != NULL, "invariant");
+   const oop base = JfrJavaSupport::resolve_non_null(thread_identifiers);
+   traceid next;
+   do {
+     next = HeapAccess<>::load_at(base, (ptrdiff_t)next_tid_offset);
+   } while (HeapAccess<>::atomic_cmpxchg_at(base, (ptrdiff_t)next_tid_offset, next, next + 1) != next);
+   return next;
+ }
+ 
+ // returns updated value
+ static traceid atomic_inc(traceid volatile* const dest, traceid stride = 1) {
    assert(VM_Version::supports_cx8(), "invariant");
    traceid compare_value;
    traceid exchange_value;
    do {
      compare_value = *dest;
-     exchange_value = compare_value + 1;
+     exchange_value = compare_value + stride;
    } while (Atomic::cmpxchg(dest, compare_value, exchange_value) != compare_value);
    return exchange_value;
  }
  
  static traceid next_class_id() {
    static volatile traceid class_id_counter = LAST_TYPE_ID + 1; // + 1 is for the void.class primitive
    return atomic_inc(&class_id_counter) << TRACE_ID_SHIFT;
  }
  
- static traceid next_thread_id() {
-   static volatile traceid thread_id_counter = 0;
-   return atomic_inc(&thread_id_counter);
- }
- 
  static traceid next_module_id() {
    static volatile traceid module_id_counter = 0;
    return atomic_inc(&module_id_counter) << TRACE_ID_SHIFT;
  }
  
< prev index next >