8138707: TestPromotionEventWithParallelScavenge.java crashes using undefined GC id

Reviewed-by: mgerdin, jwilhelm
This commit is contained in:
Bengt Rutisson 2015-10-06 14:27:03 +02:00
parent 48bbdafeed
commit 3289307dbe
3 changed files with 25 additions and 28 deletions

View File

@ -26,6 +26,7 @@
#include "gc/parallel/gcTaskManager.hpp" #include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/gcTaskThread.hpp" #include "gc/parallel/gcTaskThread.hpp"
#include "gc/shared/adaptiveSizePolicy.hpp" #include "gc/shared/adaptiveSizePolicy.hpp"
#include "gc/shared/gcId.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "runtime/mutex.hpp" #include "runtime/mutex.hpp"
@ -61,33 +62,24 @@ const char* GCTask::Kind::to_string(kind value) {
return result; return result;
}; };
GCTask::GCTask() : GCTask::GCTask() {
_kind(Kind::ordinary_task), initialize(Kind::ordinary_task, GCId::current());
_affinity(GCTaskManager::sentinel_worker()){
initialize();
} }
GCTask::GCTask(Kind::kind kind) : GCTask::GCTask(Kind::kind kind) {
_kind(kind), initialize(kind, GCId::current());
_affinity(GCTaskManager::sentinel_worker()) {
initialize();
} }
GCTask::GCTask(uint affinity) : GCTask::GCTask(Kind::kind kind, uint gc_id) {
_kind(Kind::ordinary_task), initialize(kind, gc_id);
_affinity(affinity) {
initialize();
} }
GCTask::GCTask(Kind::kind kind, uint affinity) : void GCTask::initialize(Kind::kind kind, uint gc_id) {
_kind(kind), _kind = kind;
_affinity(affinity) { _affinity = GCTaskManager::sentinel_worker();
initialize();
}
void GCTask::initialize() {
_older = NULL; _older = NULL;
_newer = NULL; _newer = NULL;
_gc_id = gc_id;
} }
void GCTask::destruct() { void GCTask::destruct() {
@ -806,6 +798,10 @@ void NoopGCTask::destroy(NoopGCTask* that) {
} }
} }
// This task should never be performing GC work that require
// a valid GC id.
NoopGCTask::NoopGCTask() : GCTask(GCTask::Kind::noop_task, GCId::undefined()) { }
void NoopGCTask::destruct() { void NoopGCTask::destruct() {
// This has to know it's superclass structure, just like the constructor. // This has to know it's superclass structure, just like the constructor.
this->GCTask::destruct(); this->GCTask::destruct();

View File

@ -68,13 +68,16 @@ public:
}; };
private: private:
// Instance state. // Instance state.
const Kind::kind _kind; // For runtime type checking. Kind::kind _kind; // For runtime type checking.
const uint _affinity; // Which worker should run task. uint _affinity; // Which worker should run task.
GCTask* _newer; // Tasks are on doubly-linked ... GCTask* _newer; // Tasks are on doubly-linked ...
GCTask* _older; // ... lists. GCTask* _older; // ... lists.
uint _gc_id; // GC Id to use for the thread that executes this task
public: public:
virtual char* name() { return (char *)"task"; } virtual char* name() { return (char *)"task"; }
uint gc_id() { return _gc_id; }
// Abstract do_it method // Abstract do_it method
virtual void do_it(GCTaskManager* manager, uint which) = 0; virtual void do_it(GCTaskManager* manager, uint which) = 0;
// Accessors // Accessors
@ -116,17 +119,14 @@ protected:
GCTask(); GCTask();
// A GCTask of a particular kind, usually barrier or noop. // A GCTask of a particular kind, usually barrier or noop.
GCTask(Kind::kind kind); GCTask(Kind::kind kind);
// An ordinary GCTask with an affinity. GCTask(Kind::kind kind, uint gc_id);
GCTask(uint affinity);
// A GCTask of a particular kind, with and affinity.
GCTask(Kind::kind kind, uint affinity);
// We want a virtual destructor because virtual methods, // We want a virtual destructor because virtual methods,
// but since ResourceObj's don't have their destructors // but since ResourceObj's don't have their destructors
// called, we don't have one at all. Instead we have // called, we don't have one at all. Instead we have
// this method, which gets called by subclasses to clean up. // this method, which gets called by subclasses to clean up.
virtual void destruct(); virtual void destruct();
// Methods. // Methods.
void initialize(); void initialize(Kind::kind kind, uint gc_id);
}; };
// A doubly-linked list of GCTasks. // A doubly-linked list of GCTasks.
@ -567,8 +567,7 @@ public:
} }
protected: protected:
// Constructor. // Constructor.
NoopGCTask() : NoopGCTask();
GCTask(GCTask::Kind::noop_task) { }
// Destructor-like method. // Destructor-like method.
void destruct(); void destruct();
}; };

View File

@ -26,6 +26,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc/parallel/gcTaskManager.hpp" #include "gc/parallel/gcTaskManager.hpp"
#include "gc/parallel/gcTaskThread.hpp" #include "gc/parallel/gcTaskThread.hpp"
#include "gc/shared/gcId.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/allocation.inline.hpp" #include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp" #include "memory/resourceArea.hpp"
@ -124,6 +125,7 @@ void GCTaskThread::run() {
for (; /* break */; ) { for (; /* break */; ) {
// This will block until there is a task to be gotten. // This will block until there is a task to be gotten.
GCTask* task = manager()->get_task(which()); GCTask* task = manager()->get_task(which());
GCIdMark gc_id_mark(task->gc_id());
// Record if this is an idle task for later use. // Record if this is an idle task for later use.
bool is_idle_task = task->is_idle_task(); bool is_idle_task = task->is_idle_task();
// In case the update is costly // In case the update is costly