Skip to content
Permalink
Browse files
8233705: Let artifact iteration running time be a function of increme…
…ntally tagged artifacts

Reviewed-by: egahlin
  • Loading branch information
Markus Grönlund committed Jun 5, 2020
1 parent 45fa5aa commit c66bef028963393077b7df7afb3ec2c8fdbe54aa
Showing 60 changed files with 2,460 additions and 1,004 deletions.
@@ -37,7 +37,8 @@
#include "jfr/jfr.hpp"
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/jni/jfrUpcalls.hpp"
#include "jfr/support/jfrEventClass.hpp"
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "jfr/support/jfrJdkJfrEvent.hpp"
#include "jfr/utilities/jfrBigEndian.hpp"
#include "jfr/writers/jfrBigEndianWriter.hpp"
#include "logging/log.hpp"
@@ -1408,7 +1409,7 @@ static ClassFileStream* create_new_bytes_for_subklass(const InstanceKlass* ik, c
jint size_instrumented_data = 0;
unsigned char* instrumented_data = NULL;
const jclass super = (jclass)JNIHandles::make_local(ik->super()->java_mirror());
JfrUpcalls::new_bytes_eager_instrumentation(TRACE_ID(ik),
JfrUpcalls::new_bytes_eager_instrumentation(JfrTraceId::load_raw(ik),
force_instrumentation,
super,
size_of_new_bytes,
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@@ -29,7 +29,7 @@
#include "jfr/jni/jfrUpcalls.hpp"
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/support/jfrEventClass.hpp"
#include "jfr/support/jfrJdkJfrEvent.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "prims/jvmtiEnvBase.hpp"
@@ -91,7 +91,7 @@ extern "C" void JNICALL jfr_on_class_file_load_hook(jvmtiEnv *jvmti_env,
JavaThread* jt = JavaThread::thread_from_jni_environment(jni_env);
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));;
ThreadInVMfromNative tvmfn(jt);
JfrUpcalls::on_retransform(JfrTraceId::get(class_being_redefined),
JfrUpcalls::on_retransform(JfrTraceId::load_raw(class_being_redefined),
class_being_redefined,
class_data_len,
class_data,
@@ -66,7 +66,7 @@ void Jfr::on_create_vm_3() {

void Jfr::on_unloading_classes() {
if (JfrRecorder::is_created()) {
JfrCheckpointManager::write_type_set_for_unloaded_classes();
JfrCheckpointManager::on_unloading_classes();
}
}

@@ -38,12 +38,13 @@
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/recorder/stringpool/jfrStringPool.hpp"
#include "jfr/jni/jfrGetAllEventClasses.hpp"
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/jni/jfrJniMethodRegistration.hpp"
#include "jfr/instrumentation/jfrEventClassTransformer.hpp"
#include "jfr/instrumentation/jfrJvmtiAgent.hpp"
#include "jfr/leakprofiler/leakProfiler.hpp"
#include "jfr/support/jfrJdkJfrEvent.hpp"
#include "jfr/support/jfrKlassUnloading.hpp"
#include "jfr/utilities/jfrJavaLog.hpp"
#include "jfr/utilities/jfrTimeConverter.hpp"
#include "jfr/utilities/jfrTime.hpp"
@@ -163,7 +164,7 @@ NO_TRANSITION(jlong, jfr_get_epoch_address(JNIEnv* env, jobject jvm))
NO_TRANSITION_END

NO_TRANSITION(jlong, jfr_get_unloaded_event_classes_count(JNIEnv* env, jobject jvm))
return JfrEventClasses::unloaded_event_classes_count();
return JfrKlassUnloading::event_class_count();
NO_TRANSITION_END

NO_TRANSITION(jdouble, jfr_time_conv_factor(JNIEnv* env, jobject jvm))
@@ -234,11 +235,11 @@ JVM_ENTRY_NO_ENV(jboolean, jfr_emit_event(JNIEnv* env, jobject jvm, jlong eventT
JVM_END

JVM_ENTRY_NO_ENV(jobject, jfr_get_all_event_classes(JNIEnv* env, jobject jvm))
return JfrEventClasses::get_all_event_classes(thread);
return JdkJfrEvent::get_all_klasses(thread);
JVM_END

JVM_ENTRY_NO_ENV(jlong, jfr_class_id(JNIEnv* env, jclass jvm, jclass jc))
return JfrTraceId::use(jc);
return JfrTraceId::load(jc);
JVM_END

JVM_ENTRY_NO_ENV(jlong, jfr_stacktrace_id(JNIEnv* env, jobject jvm, jint skip))
@@ -311,7 +312,7 @@ JVM_ENTRY_NO_ENV(void, jfr_abort(JNIEnv* env, jobject jvm, jstring errorMsg))
JVM_END

JVM_ENTRY_NO_ENV(jlong, jfr_type_id(JNIEnv* env, jobject jvm, jclass jc))
return JfrTraceId::get(jc);
return JfrTraceId::load_raw(jc);
JVM_END

JVM_ENTRY_NO_ENV(jboolean, jfr_add_string_constant(JNIEnv* env, jclass jvm, jboolean epoch, jlong id, jstring string))
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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,7 +28,7 @@
#include "classfile/systemDictionary.hpp"
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/jni/jfrUpcalls.hpp"
#include "jfr/support/jfrEventClass.hpp"
#include "jfr/support/jfrJdkJfrEvent.hpp"
#include "logging/log.hpp"
#include "memory/oopFactory.hpp"
#include "oops/oop.inline.hpp"
@@ -35,36 +35,15 @@
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
#include "jfr/support/jfrKlassUnloading.hpp"
#include "jfr/support/jfrMethodLookup.hpp"
#include "jfr/utilities/jfrHashtable.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "jfr/utilities/jfrPredicate.hpp"
#include "jfr/utilities/jfrRelation.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.hpp"
#include "utilities/growableArray.hpp"

static bool predicate(GrowableArray<traceid>* set, traceid id) {
assert(set != NULL, "invariant");
bool found = false;
set->find_sorted<traceid, compare_traceid>(id, found);
return found;
}

static bool mutable_predicate(GrowableArray<traceid>* set, traceid id) {
assert(set != NULL, "invariant");
bool found = false;
const int location = set->find_sorted<traceid, compare_traceid>(id, found);
if (!found) {
set->insert_before(location, id);
}
return found;
}

static bool add(GrowableArray<traceid>* set, traceid id) {
assert(set != NULL, "invariant");
return mutable_predicate(set, id);
}

const int initial_array_size = 64;

@@ -87,7 +66,12 @@ Semaphore ThreadIdExclusiveAccess::_mutex_semaphore(1);

static bool has_thread_exited(traceid tid) {
assert(tid != 0, "invariant");
return unloaded_thread_id_set != NULL && predicate(unloaded_thread_id_set, tid);
return unloaded_thread_id_set != NULL && JfrPredicate<traceid, compare_traceid>::test(unloaded_thread_id_set, tid);
}

static bool add(GrowableArray<traceid>* set, traceid id) {
assert(set != NULL, "invariant");
return JfrMutablePredicate<traceid, compare_traceid>::test(set, id);
}

static void add_to_unloaded_thread_set(traceid tid) {
@@ -105,31 +89,6 @@ void ObjectSampleCheckpoint::on_thread_exit(JavaThread* jt) {
}
}

// Track the set of unloaded klasses during a chunk / epoch.
// Methods in stacktraces belonging to unloaded klasses must not be accessed.
static GrowableArray<traceid>* unloaded_klass_set = NULL;

static void add_to_unloaded_klass_set(traceid klass_id) {
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
if (unloaded_klass_set == NULL) {
unloaded_klass_set = c_heap_allocate_array<traceid>();
}
unloaded_klass_set->append(klass_id);
}

static void sort_unloaded_klass_set() {
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
if (unloaded_klass_set != NULL && unloaded_klass_set->length() > 1) {
unloaded_klass_set->sort(sort_traceid);
}
}

void ObjectSampleCheckpoint::on_klass_unload(const Klass* k) {
assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
assert(k != NULL, "invariant");
add_to_unloaded_klass_set(JfrTraceId::get(k));
}

template <typename Processor>
static void do_samples(ObjectSample* sample, const ObjectSample* end, Processor& processor) {
assert(sample != NULL, "invariant");
@@ -228,7 +187,6 @@ static GrowableArray<traceid>* id_set = NULL;

static void prepare_for_resolution() {
id_set = new GrowableArray<traceid>(JfrOptionSet::old_object_queue_size());
sort_unloaded_klass_set();
}

static bool stack_trace_precondition(const ObjectSample* sample) {
@@ -290,6 +248,7 @@ static void install_stack_traces(const ObjectSampler* sampler, JfrStackTraceRepo
assert(sampler != NULL, "invariant");
const ObjectSample* const last = sampler->last();
if (last != sampler->last_resolved()) {
JfrKlassUnloading::sort();
StackTraceBlobInstaller installer(stack_trace_repo);
iterate_samples(installer);
}
@@ -307,13 +266,13 @@ void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler, JfrStackT

static bool is_klass_unloaded(traceid klass_id) {
assert(ClassLoaderDataGraph_lock->owned_by_self(), "invariant");
return unloaded_klass_set != NULL && predicate(unloaded_klass_set, klass_id);
return JfrKlassUnloading::is_unloaded(klass_id);
}

static bool is_processed(traceid method_id) {
assert(method_id != 0, "invariant");
assert(id_set != NULL, "invariant");
return mutable_predicate(id_set, method_id);
return JfrMutablePredicate<traceid, compare_traceid>::test(id_set, method_id);
}

void ObjectSampleCheckpoint::add_to_leakp_set(const InstanceKlass* ik, traceid method_id) {
@@ -324,7 +283,7 @@ void ObjectSampleCheckpoint::add_to_leakp_set(const InstanceKlass* ik, traceid m
const Method* const method = JfrMethodLookup::lookup(ik, method_id);
assert(method != NULL, "invariant");
assert(method->method_holder() == ik, "invariant");
JfrTraceId::set_leakp(ik, method);
JfrTraceId::load_leakp(ik, method);
}

void ObjectSampleCheckpoint::write_stacktrace(const JfrStackTrace* trace, JfrCheckpointWriter& writer) {
@@ -419,21 +378,13 @@ void ObjectSampleCheckpoint::write(const ObjectSampler* sampler, EdgeStore* edge
}
}

static void clear_unloaded_klass_set() {
assert(ClassLoaderDataGraph_lock->owned_by_self(), "invariant");
if (unloaded_klass_set != NULL && unloaded_klass_set->is_nonempty()) {
unloaded_klass_set->clear();
}
}

// A linked list of saved type set blobs for the epoch.
// The link consist of a reference counted handle.
static JfrBlobHandle saved_type_set_blobs;

static void release_state_for_previous_epoch() {
// decrements the reference count and the list is reinitialized
saved_type_set_blobs = JfrBlobHandle();
clear_unloaded_klass_set();
}

class BlobInstaller {
@@ -50,7 +50,6 @@ class ObjectSampleCheckpoint : AllStatic {
static void write_stacktrace(const JfrStackTrace* trace, JfrCheckpointWriter& writer);
static void write(const ObjectSampler* sampler, EdgeStore* edge_store, bool emit_all, Thread* thread);
public:
static void on_klass_unload(const Klass* k);
static void on_type_set(JfrCheckpointWriter& writer);
static void on_type_set_unload(JfrCheckpointWriter& writer);
static void on_thread_exit(JavaThread* jt);

0 comments on commit c66bef0

Please sign in to comment.