8251179: Word tearing problem with _last_sweep
Reviewed-by: coleenp, dholmes, kbarrett
This commit is contained in:
parent
c148c2c176
commit
4d3baa2d37
@ -74,7 +74,7 @@ size_t EventEmitter::write_events(ObjectSampler* object_sampler, EdgeStore* edge
|
|||||||
assert(object_sampler != NULL, "invariant");
|
assert(object_sampler != NULL, "invariant");
|
||||||
assert(edge_store != NULL, "invariant");
|
assert(edge_store != NULL, "invariant");
|
||||||
|
|
||||||
const jlong last_sweep = emit_all ? max_jlong : object_sampler->last_sweep().value();
|
const jlong last_sweep = emit_all ? max_jlong : ObjectSampler::last_sweep();
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
// First pass associates a live sample with its immediate edge
|
// First pass associates a live sample with its immediate edge
|
||||||
|
@ -133,7 +133,7 @@ int ObjectSampleCheckpoint::save_mark_words(const ObjectSampler* sampler, Object
|
|||||||
if (sampler->last() == NULL) {
|
if (sampler->last() == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SampleMarker sample_marker(marker, emit_all ? max_jlong : sampler->last_sweep().value());
|
SampleMarker sample_marker(marker, emit_all ? max_jlong : ObjectSampler::last_sweep());
|
||||||
iterate_samples(sample_marker, true);
|
iterate_samples(sample_marker, true);
|
||||||
return sample_marker.count();
|
return sample_marker.count();
|
||||||
}
|
}
|
||||||
@ -361,7 +361,7 @@ class BlobWriter {
|
|||||||
|
|
||||||
static void write_sample_blobs(const ObjectSampler* sampler, bool emit_all, Thread* thread) {
|
static void write_sample_blobs(const ObjectSampler* sampler, bool emit_all, Thread* thread) {
|
||||||
// sample set is predicated on time of last sweep
|
// sample set is predicated on time of last sweep
|
||||||
const jlong last_sweep = emit_all ? max_jlong : sampler->last_sweep().value();
|
const jlong last_sweep = emit_all ? max_jlong : ObjectSampler::last_sweep();
|
||||||
JfrCheckpointWriter writer(thread, false);
|
JfrCheckpointWriter writer(thread, false);
|
||||||
BlobWriter cbw(sampler, writer, last_sweep);
|
BlobWriter cbw(sampler, writer, last_sweep);
|
||||||
iterate_samples(cbw, true);
|
iterate_samples(cbw, true);
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
|
#include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
|
||||||
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
|
#include "jfr/recorder/stacktrace/jfrStackTraceRepository.hpp"
|
||||||
#include "jfr/support/jfrThreadLocal.hpp"
|
#include "jfr/support/jfrThreadLocal.hpp"
|
||||||
|
#include "jfr/utilities/jfrTime.hpp"
|
||||||
#include "jfr/utilities/jfrTryLock.hpp"
|
#include "jfr/utilities/jfrTryLock.hpp"
|
||||||
#include "logging/log.hpp"
|
#include "logging/log.hpp"
|
||||||
#include "memory/universe.hpp"
|
#include "memory/universe.hpp"
|
||||||
@ -44,7 +45,8 @@
|
|||||||
#include "runtime/thread.hpp"
|
#include "runtime/thread.hpp"
|
||||||
|
|
||||||
// Timestamp of when the gc last processed the set of sampled objects.
|
// Timestamp of when the gc last processed the set of sampled objects.
|
||||||
static JfrTicks _last_sweep;
|
// Atomic access to prevent word tearing on 32-bit platforms.
|
||||||
|
static volatile int64_t _last_sweep;
|
||||||
|
|
||||||
// Condition variable to communicate that some sampled objects have been cleared by the gc
|
// Condition variable to communicate that some sampled objects have been cleared by the gc
|
||||||
// and can therefore be removed from the sample priority queue.
|
// and can therefore be removed from the sample priority queue.
|
||||||
@ -66,7 +68,7 @@ void ObjectSampler::oop_storage_gc_notification(size_t num_dead) {
|
|||||||
// instance was created concurrently. This allows for a small race where cleaning
|
// instance was created concurrently. This allows for a small race where cleaning
|
||||||
// could be done again.
|
// could be done again.
|
||||||
Atomic::store(&_dead_samples, true);
|
Atomic::store(&_dead_samples, true);
|
||||||
_last_sweep = JfrTicks::now();
|
Atomic::store(&_last_sweep, (int64_t)JfrTicks::now().value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +92,8 @@ ObjectSampler::ObjectSampler(size_t size) :
|
|||||||
_total_allocated(0),
|
_total_allocated(0),
|
||||||
_threshold(0),
|
_threshold(0),
|
||||||
_size(size) {
|
_size(size) {
|
||||||
_last_sweep = JfrTicks::now();
|
|
||||||
Atomic::store(&_dead_samples, false);
|
Atomic::store(&_dead_samples, false);
|
||||||
|
Atomic::store(&_last_sweep, (int64_t)JfrTicks::now().value());
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectSampler::~ObjectSampler() {
|
ObjectSampler::~ObjectSampler() {
|
||||||
@ -285,6 +287,6 @@ ObjectSample* ObjectSampler::item_at(int index) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JfrTicks& ObjectSampler::last_sweep() {
|
int64_t ObjectSampler::last_sweep() {
|
||||||
return _last_sweep;
|
return Atomic::load(&_last_sweep);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#define SHARE_JFR_LEAKPROFILER_SAMPLING_OBJECTSAMPLER_HPP
|
#define SHARE_JFR_LEAKPROFILER_SAMPLING_OBJECTSAMPLER_HPP
|
||||||
|
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
#include "jfr/utilities/jfrTime.hpp"
|
|
||||||
|
|
||||||
typedef u8 traceid;
|
typedef u8 traceid;
|
||||||
|
|
||||||
@ -80,7 +79,7 @@ class ObjectSampler : public CHeapObj<mtTracing> {
|
|||||||
// For operations that require exclusive access (non-safepoint)
|
// For operations that require exclusive access (non-safepoint)
|
||||||
static ObjectSampler* acquire();
|
static ObjectSampler* acquire();
|
||||||
static void release();
|
static void release();
|
||||||
static const JfrTicks& last_sweep();
|
static int64_t last_sweep();
|
||||||
const ObjectSample* first() const;
|
const ObjectSample* first() const;
|
||||||
ObjectSample* last() const;
|
ObjectSample* last() const;
|
||||||
const ObjectSample* last_resolved() const;
|
const ObjectSample* last_resolved() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user