8323883: JFR AssertionError: Missing object ID 15101

Reviewed-by: egahlin
This commit is contained in:
Markus Grönlund 2024-02-14 14:10:28 +00:00
parent 61f249335d
commit 737b4c515e
15 changed files with 118 additions and 85 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, 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
@ -36,6 +36,7 @@
#include "jfr/recorder/repository/jfrEmergencyDump.hpp"
#include "jfr/recorder/service/jfrEventThrottler.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/recorder/service/jfrRecorderService.hpp"
#include "jfr/recorder/stacktrace/jfrStackFilter.hpp"
#include "jfr/recorder/stacktrace/jfrStackFilterRegistry.hpp"
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
@ -348,7 +349,8 @@ JVM_ENTRY_NO_ENV(void, jfr_set_force_instrumentation(JNIEnv* env, jclass jvm, jb
JVM_END
JVM_ENTRY_NO_ENV(void, jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean emit_all, jboolean skip_bfs))
LeakProfiler::emit_events(cutoff_ticks, emit_all == JNI_TRUE, skip_bfs == JNI_TRUE);
JfrRecorderService service;
service.emit_leakprofiler_events(cutoff_ticks, emit_all == JNI_TRUE, skip_bfs == JNI_TRUE);
JVM_END
JVM_ENTRY_NO_ENV(void, jfr_exclude_thread(JNIEnv* env, jclass jvm, jobject t))

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2024, 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
@ -205,6 +205,15 @@ static bool stack_trace_precondition(const ObjectSample* sample) {
return sample->has_stack_trace_id() && !sample->is_dead();
}
static void add_to_leakp_set(const ObjectSample* sample) {
assert(sample != nullptr, "invariant");
oop object = sample->object();
if (object == nullptr) {
return;
}
JfrTraceId::load_leakp(object->klass());
}
class StackTraceBlobInstaller {
private:
BlobCache _cache;
@ -219,6 +228,7 @@ class StackTraceBlobInstaller {
}
void sample_do(ObjectSample* sample) {
if (stack_trace_precondition(sample)) {
add_to_leakp_set(sample);
install(sample);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2024, 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
@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "jfr/leakprofiler/sampling/objectSample.hpp"
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
#include "oops/weakHandle.inline.hpp"
#include "runtime/handles.inline.hpp"
@ -36,7 +37,7 @@ void ObjectSample::reset() {
}
oop ObjectSample::object() const {
return _object.resolve();
return is_dead() ? nullptr :_object.resolve();
}
bool ObjectSample::is_dead() const {
@ -48,6 +49,7 @@ const oop* ObjectSample::object_addr() const {
}
void ObjectSample::set_object(oop object) {
assert(object != nullptr, "invariant");
assert(_object.is_empty(), "should be empty");
Handle h(Thread::current(), object);
_object = WeakHandle(ObjectSampler::oop_storage(), h);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024, 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
@ -126,7 +126,6 @@ static traceid artifact_tag(const T* ptr, bool leakp) {
SET_LEAKP(ptr);
}
assert(IS_LEAKP(ptr), "invariant");
return artifact_id(ptr);
}
if (not_used(ptr)) {
SET_TRANSIENT(ptr);
@ -153,7 +152,7 @@ static inline bool should_do_cld_klass(const Klass* cld_klass, bool leakp) {
static inline bool should_enqueue(const Klass* cld_klass) {
assert(cld_klass != nullptr, "invariant");
if (previous_epoch()) {
if (unloading() || previous_epoch()) {
return false;
}
CldPtr cld = get_cld(cld_klass);
@ -253,7 +252,11 @@ class ModuleFieldSelector {
static TypePtr select(KlassPtr klass) {
assert(klass != nullptr, "invariant");
PkgPtr pkg = klass->package();
return pkg != nullptr ? pkg->module() : nullptr;
if (pkg == nullptr) {
return nullptr;
}
assert(current_epoch() ? IS_SERIALIZED(pkg) : true, "invariant");
return pkg->module();
}
};
@ -272,7 +275,11 @@ class ModuleCldFieldSelector {
static TypePtr select(KlassPtr klass) {
assert(klass != nullptr, "invariant");
ModPtr mod = ModuleFieldSelector::select(klass);
return mod != nullptr ? mod->loader_data() : nullptr;
if (mod == nullptr) {
return nullptr;
}
assert(current_epoch() ? IS_SERIALIZED(mod) : true, "invariant");
return mod->loader_data();
}
};
@ -283,18 +290,7 @@ class SerializePredicate {
SerializePredicate(bool class_unload) : _class_unload(class_unload) {}
bool operator()(T const& value) {
assert(value != nullptr, "invariant");
return _class_unload ? _artifacts->should_do_unloading_artifact(value) : IS_NOT_SERIALIZED(value);
}
};
template <>
class SerializePredicate<const Klass*> {
bool _class_unload;
public:
SerializePredicate(bool class_unload) : _class_unload(class_unload) {}
bool operator()(const Klass* klass) {
assert(klass != nullptr, "invariant");
return _class_unload ? true : IS_NOT_SERIALIZED(klass);
return _class_unload ? true : IS_NOT_SERIALIZED(value);
}
};
@ -352,13 +348,19 @@ static void do_write_klass(JfrCheckpointWriter* writer, CldPtr cld, KlassPtr kla
writer->write(package_id(klass, leakp));
writer->write(klass->modifier_flags());
writer->write<bool>(klass->is_hidden());
if (!leakp) {
set_serialized(klass);
if (leakp) {
assert(IS_LEAKP(klass), "invariant");
CLEAR_LEAKP(klass);
assert(IS_NOT_LEAKP(klass), "invariant");
return;
}
assert(used(klass), "invariant");
assert(unloading() ? true : IS_NOT_SERIALIZED(klass), "invariant");
set_serialized(klass);
}
static inline bool should_write_cld_klass(KlassPtr klass, bool leakp) {
return klass != nullptr && (leakp || IS_NOT_SERIALIZED(klass));
return klass != nullptr && (leakp ? IS_LEAKP(klass) : unloading() ? true : IS_NOT_SERIALIZED(klass));
}
static void write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp, int& elements) {
@ -373,10 +375,10 @@ static void write_klass(JfrCheckpointWriter* writer, KlassPtr klass, bool leakp,
write_klass(writer, cld_klass, leakp, elements);
}
}
KlassPtr mod_klass = get_module_cld_klass(klass, leakp);
if (should_write_cld_klass(mod_klass, leakp)) {
KlassPtr mod_cld_klass = get_module_cld_klass(klass, leakp);
if (should_write_cld_klass(mod_cld_klass, leakp)) {
// Write the klass for the module cld.
write_klass(writer, mod_klass, leakp, elements);
write_klass(writer, mod_cld_klass, leakp, elements);
}
}
@ -398,7 +400,6 @@ int write__klass(JfrCheckpointWriter* writer, const void* k) {
int write__klass__leakp(JfrCheckpointWriter* writer, const void* k) {
assert(k != nullptr, "invariant");
KlassPtr klass = static_cast<KlassPtr>(k);
CLEAR_LEAKP(klass);
int elements = 0;
write_klass(writer, klass, true, elements);
return elements;
@ -978,15 +979,12 @@ class MethodIteratorHost {
MethodUsedPredicate _method_used_predicate;
MethodFlagPredicate<leakp> _method_flag_predicate;
public:
MethodIteratorHost(JfrCheckpointWriter* writer,
bool current_epoch = false,
bool class_unload = false,
bool skip_header = false) :
_method_cb(writer, class_unload, skip_header),
_klass_cb(writer, class_unload, skip_header),
_klass_used_predicate(current_epoch),
_method_used_predicate(current_epoch),
_method_flag_predicate(current_epoch) {}
MethodIteratorHost(JfrCheckpointWriter* writer) :
_method_cb(writer, unloading(), false),
_klass_cb(writer, unloading(), false),
_klass_used_predicate(current_epoch()),
_method_used_predicate(current_epoch()),
_method_flag_predicate(current_epoch()) {}
bool operator()(KlassPtr klass) {
if (_method_used_predicate(klass)) {
@ -1037,14 +1035,13 @@ typedef LeakPredicate<MethodPtr> LeakMethodPredicate;
typedef JfrPredicatedTypeWriterImplHost<MethodPtr, LeakMethodPredicate, write__method__leakp> LeakMethodWriterImplTarget;
typedef JfrTypeWriterHost<LeakMethodWriterImplTarget, TYPE_METHOD> LeakMethodWriterImpl;
typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, true> LeakMethodWriter;
typedef MethodIteratorHost<LeakMethodWriterImpl, KlassCallbackStub, true> LeakMethodWriter;
typedef CompositeFunctor<KlassPtr, LeakMethodWriter, MethodWriter> CompositeMethodWriter;
static void write_methods_with_leakp(MethodWriter& mw) {
assert(_writer != nullptr, "invariant");
assert(_leakp_writer != nullptr, "invariant");
assert(previous_epoch(), "invariant");
LeakMethodWriter lpmw(_leakp_writer, current_epoch(), unloading());
LeakMethodWriter lpmw(_leakp_writer);
CompositeMethodWriter cmw(&lpmw, &mw);
_artifacts->iterate_klasses(cmw);
_artifacts->tally(mw);
@ -1052,7 +1049,7 @@ static void write_methods_with_leakp(MethodWriter& mw) {
static void write_methods() {
assert(_writer != nullptr, "invariant");
MethodWriter mw(_writer, current_epoch(), unloading());
MethodWriter mw(_writer);
if (_leakp_writer == nullptr) {
_artifacts->iterate_klasses(mw);
_artifacts->tally(mw);
@ -1065,7 +1062,7 @@ static void write_methods_on_clear() {
assert(_writer != nullptr, "invariant");
assert(_leakp_writer != nullptr, "invariant");
assert(previous_epoch(), "invariant");
MethodWriter mw(_writer, current_epoch(), unloading());
MethodWriter mw(_writer);
write_methods_with_leakp(mw);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, 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
@ -54,10 +54,6 @@ void JfrArtifactSet::initialize(bool class_unload) {
_klass_list = new GrowableArray<const Klass*>(initial_klass_list_size);
_klass_loader_set = new GrowableArray<const Klass*>(initial_klass_loader_set_size);
_klass_loader_leakp_set = new GrowableArray<const Klass*>(initial_klass_loader_set_size);
if (class_unload) {
_unloading_set = new GrowableArray<const Klass*>(initial_klass_list_size);
}
}
void JfrArtifactSet::clear() {
@ -117,18 +113,9 @@ bool JfrArtifactSet::should_do_cld_klass(const Klass* k, bool leakp) {
return not_in_set(leakp ? _klass_loader_leakp_set : _klass_loader_set, k);
}
bool JfrArtifactSet::should_do_unloading_artifact(const void* ptr) {
assert(ptr != nullptr, "invariant");
assert(_class_unload, "invariant");
assert(_unloading_set != nullptr, "invariant");
// The incoming pointers are of all kinds of different types.
// However, we are only interested in set membership.
// Treat them uniformly as const Klass* for simplicity and code reuse.
return not_in_set(_unloading_set, static_cast<const Klass*>(ptr));
}
void JfrArtifactSet::register_klass(const Klass* k) {
assert(k != nullptr, "invariant");
assert(IS_SERIALIZED(k), "invariant");
assert(_klass_list != nullptr, "invariant");
_klass_list->append(k);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2024, 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
@ -80,6 +80,7 @@ class KlassToFieldEnvelope {
public:
KlassToFieldEnvelope(Letter* letter) : _letter(letter) {}
bool operator()(const Klass* klass) {
assert(IS_SERIALIZED(klass), "invariant");
typename FieldSelector::TypePtr t = FieldSelector::select(klass);
return t != nullptr ? (*_letter)(t) : true;
}
@ -130,7 +131,7 @@ class SymbolPredicate {
class KlassUsedPredicate {
bool _current_epoch;
public:
public:
KlassUsedPredicate(bool current_epoch) : _current_epoch(current_epoch) {}
bool operator()(const Klass* klass) {
return _current_epoch ? USED_THIS_EPOCH(klass) : USED_PREVIOUS_EPOCH(klass);
@ -201,7 +202,6 @@ class JfrArtifactSet : public JfrCHeapObj {
GrowableArray<const Klass*>* _klass_list;
GrowableArray<const Klass*>* _klass_loader_set;
GrowableArray<const Klass*>* _klass_loader_leakp_set;
GrowableArray<const Klass*>* _unloading_set;
size_t _total_count;
bool _class_unload;
@ -229,23 +229,8 @@ class JfrArtifactSet : public JfrCHeapObj {
size_t total_count() const;
void register_klass(const Klass* k);
bool should_do_cld_klass(const Klass* k, bool leakp);
bool should_do_unloading_artifact(const void* ptr);
void increment_checkpoint_id();
template <typename Functor>
void iterate_klasses(Functor& functor) const {
for (int i = 0; i < _klass_list->length(); ++i) {
if (!functor(_klass_list->at(i))) {
return;
}
}
for (int i = 0; i < _klass_loader_set->length(); ++i) {
if (!functor(_klass_loader_set->at(i))) {
return;
}
}
}
template <typename T>
void iterate_symbols(T& functor) {
_symbol_table->iterate_symbols(functor);
@ -261,6 +246,24 @@ class JfrArtifactSet : public JfrCHeapObj {
_total_count += writer.count();
}
template <typename Functor>
void iterate_klasses(Functor& functor) const {
if (iterate(functor, _klass_list)) {
iterate(functor, _klass_loader_set);
}
}
private:
template <typename Functor>
bool iterate(Functor& functor, GrowableArray<const Klass*>* list) const {
assert(list != nullptr, "invariant");
for (int i = 0; i < list->length(); ++i) {
if (!functor(list->at(i))) {
return false;
}
}
return true;
}
};
class KlassArtifactRegistrator {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2024, 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
@ -92,6 +92,7 @@ class JfrTraceId : public AllStatic {
static traceid load(const ModuleEntry* module);
static traceid load(const PackageEntry* package);
static traceid load(const ClassLoaderData* cld);
static traceid load_leakp(const Klass* klass); // leak profiler
static traceid load_leakp(const Klass* klass, const Method* method); // leak profiler
static traceid load_leakp_previous_epoch(const Klass* klass, const Method* method); // leak profiler
static traceid load_no_enqueue(const Method* method);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024, 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
@ -68,6 +68,10 @@ inline traceid JfrTraceId::load(const ClassLoaderData* cld) {
return JfrTraceIdLoadBarrier::load(cld);
}
inline traceid JfrTraceId::load_leakp(const Klass* klass) {
return JfrTraceIdLoadBarrier::load_leakp(klass);
}
inline traceid JfrTraceId::load_leakp(const Klass* klass, const Method* method) {
return JfrTraceIdLoadBarrier::load_leakp(klass, method);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
@ -87,6 +87,7 @@ class JfrTraceIdLoadBarrier : AllStatic {
static traceid load(const Method* method);
static traceid load(const ModuleEntry* module);
static traceid load(const PackageEntry* package);
static traceid load_leakp(const Klass* klass); // leak profiler
static traceid load_leakp(const Klass* klass, const Method* method); // leak profiler
static traceid load_leakp_previuos_epoch(const Klass* klass, const Method* method); // leak profiler
static void do_klasses(void f(Klass*), bool previous_epoch = false);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, 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
@ -82,7 +82,7 @@ inline traceid JfrTraceIdLoadBarrier::load(const Klass* klass) {
if (should_tag(klass)) {
load_barrier(klass);
}
assert(USED_THIS_EPOCH(klass), "invariant");
assert(METHOD_AND_CLASS_USED_THIS_EPOCH(klass), "invariant");
return TRACE_ID(klass);
}
@ -148,6 +148,13 @@ inline traceid JfrTraceIdLoadBarrier::load(const PackageEntry* package) {
return set_used_and_get(package);
}
inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass) {
assert(klass != nullptr, "invariant");
load(klass); // Ensure tagged and enqueued.
SET_LEAKP(klass);
return TRACE_ID(klass);
}
inline traceid JfrTraceIdLoadBarrier::load_leakp(const Klass* klass, const Method* method) {
assert(klass != nullptr, "invariant");
assert(METHOD_AND_CLASS_USED_THIS_EPOCH(klass), "invariant");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024, 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
@ -691,3 +691,15 @@ void JfrRecorderService::evaluate_chunk_size_for_rotation() {
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(JavaThread::current()));
JfrChunkRotation::evaluate(_chunkwriter);
}
void JfrRecorderService::emit_leakprofiler_events(int64_t cutoff_ticks, bool emit_all, bool skip_bfs) {
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(JavaThread::current()));
// Take the rotation lock to exclude flush() during event emits. This is because event emit
// also creates a number checkpoint events. Those checkpoint events require a future typeset checkpoint
// event for completeness, i.e. to be generated before being flushed to a segment.
// The upcoming flush() or rotation() after event emit completes this typeset checkpoint
// and serializes all event emit checkpoint events to the same segment.
JfrRotationLock lock;
LeakProfiler::emit_events(cutoff_ticks, emit_all, skip_bfs);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2024, 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
@ -70,6 +70,7 @@ class JfrRecorderService : public StackObj {
void flushpoint();
void process_full_buffers();
void evaluate_chunk_size_for_rotation();
void emit_leakprofiler_events(int64_t cutoff_ticks, bool emit_all, bool skip_bfs);
static bool is_recording();
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024, 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
@ -95,6 +95,10 @@ class JfrTraceFlag {
} \
uint8_t* trace_meta_addr() const { \
return _trace_flags.meta_addr(); \
} \
void copy_trace_flags(uint8_t src_flags) const { \
uint8_t flags = *_trace_flags.flags_addr(); \
_trace_flags.set_flags(flags | src_flags); \
}
#endif // SHARE_JFR_SUPPORT_JFRTRACEIDEXTENSION_HPP

View File

@ -48,6 +48,7 @@
#include "oops/fieldStreams.inline.hpp"
#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/method.hpp"
#include "oops/oop.inline.hpp"
#include "oops/recordComponent.hpp"
#include "prims/jvmtiImpl.hpp"
@ -64,6 +65,7 @@
#include "utilities/bitMap.inline.hpp"
#include "utilities/checkedCast.hpp"
#include "utilities/events.hpp"
#include "utilities/macros.hpp"
Array<Method*>* VM_RedefineClasses::_old_methods = nullptr;
Array<Method*>* VM_RedefineClasses::_new_methods = nullptr;
@ -1171,6 +1173,7 @@ jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
}
}
}
JFR_ONLY(k_new_method->copy_trace_flags(*k_old_method->trace_flags_addr());)
log_trace(redefine, class, normalize)
("Method matched: new: %s [%d] == old: %s [%d]",
k_new_method->name_and_sig_as_C_string(), ni, k_old_method->name_and_sig_as_C_string(), oi);

View File

@ -77,8 +77,7 @@ final class ConstantMap {
if (id != 0) {
String msg = "Missing object ID " + id + " in pool " + getName() + ". All IDs should reference an object";
Logger.log(LogTag.JFR_SYSTEM_PARSER, LogLevel.INFO, msg);
// Disable assertion until JDK-8323883 is fixed
// assert false : msg;
assert false : msg;
}
return null;
}