diff -r 2c3cc4b01880 -r c16ac7a2eba4 src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp --- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp Wed Oct 30 16:14:56 2019 +0100 +++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp Wed Oct 30 19:43:52 2019 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -29,61 +29,53 @@ #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 Semaphore metadata_mutex_semaphore(1); +static jbyteArray metadata_blob = NULL; +static u8 metadata_id = 0; +static u8 last_metadata_id = 0; -void JfrMetadataEvent::lock() { - metadata_mutex_semaphore.wait(); -} - -void JfrMetadataEvent::unlock() { - metadata_mutex_semaphore.signal(); +static void write_metadata_blob(JfrChunkWriter& chunkwriter) { + assert(metadata_blob != NULL, "invariant"); + const typeArrayOop arr = (typeArrayOop)JfrJavaSupport::resolve_non_null(metadata_blob); + assert(arr != NULL, "invariant"); + const int length = arr->length(); + const Klass* const k = arr->klass(); + assert(k != NULL && k->is_array_klass(), "invariant"); + const TypeArrayKlass* const byte_arr_klass = TypeArrayKlass::cast(k); + const jbyte* const data_address = arr->byte_at_addr(0); + chunkwriter.write_unbuffered(data_address, length); } -static void write_metadata_blob(JfrChunkWriter& chunkwriter, jbyteArray metadata_blob) { - if (metadata_blob != NULL) { - const typeArrayOop arr = (typeArrayOop)JfrJavaSupport::resolve_non_null(metadata_blob); - assert(arr != NULL, "invariant"); - const int length = arr->length(); - const Klass* const k = arr->klass(); - assert(k != NULL && k->is_array_klass(), "invariant"); - const TypeArrayKlass* const byte_arr_klass = TypeArrayKlass::cast(k); - const jbyte* const data_address = arr->byte_at_addr(0); - chunkwriter.write_unbuffered(data_address, length); +void JfrMetadataEvent::write(JfrChunkWriter& chunkwriter) { + assert(chunkwriter.is_valid(), "invariant"); + if (last_metadata_id == metadata_id && chunkwriter.has_metadata()) { + return; } -} - -// the semaphore is assumed to be locked (was locked previous safepoint) -size_t JfrMetadataEvent::write(JfrChunkWriter& chunkwriter, jlong metadata_offset) { - assert(chunkwriter.is_valid(), "invariant"); - assert(chunkwriter.current_offset() == metadata_offset, "invariant"); // header - chunkwriter.reserve(sizeof(u4)); + const int64_t metadata_offset = chunkwriter.reserve(sizeof(u4)); chunkwriter.write(EVENT_METADATA); // ID 0 // time data chunkwriter.write(JfrTicks::now()); chunkwriter.write((u8)0); // duration - chunkwriter.write((u8)0); // metadata id - write_metadata_blob(chunkwriter, _metadata_blob); // payload - unlock(); // open up for java to provide updated metadata + chunkwriter.write(metadata_id); // metadata id + write_metadata_blob(chunkwriter); // payload // fill in size of metadata descriptor event - const jlong size_written = chunkwriter.current_offset() - metadata_offset; + const int64_t size_written = chunkwriter.current_offset() - metadata_offset; chunkwriter.write_padded_at_offset((u4)size_written, metadata_offset); - return size_written; + chunkwriter.set_last_metadata_offset(metadata_offset); + last_metadata_id = metadata_id; } void JfrMetadataEvent::update(jbyteArray metadata) { JavaThread* thread = (JavaThread*)Thread::current(); assert(thread->is_Java_thread(), "invariant"); DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread)); - lock(); - if (_metadata_blob != NULL) { - JfrJavaSupport::destroy_global_jni_handle(_metadata_blob); + if (metadata_blob != NULL) { + JfrJavaSupport::destroy_global_jni_handle(metadata_blob); } const oop new_desc_oop = JfrJavaSupport::resolve_non_null(metadata); - _metadata_blob = new_desc_oop != NULL ? (jbyteArray)JfrJavaSupport::global_jni_handle(new_desc_oop, thread) : NULL; - unlock(); + assert(new_desc_oop != NULL, "invariant"); + metadata_blob = (jbyteArray)JfrJavaSupport::global_jni_handle(new_desc_oop, thread); + ++metadata_id; }