Merge
This commit is contained in:
commit
f2ac065c42
@ -3632,23 +3632,11 @@ static inline void generate_satb_log_enqueue_if_necessary(bool with_frame) {
|
||||
if (satb_log_enqueue_with_frame == 0) {
|
||||
generate_satb_log_enqueue(with_frame);
|
||||
assert(satb_log_enqueue_with_frame != 0, "postcondition.");
|
||||
if (G1SATBPrintStubs) {
|
||||
tty->print_cr("Generated with-frame satb enqueue:");
|
||||
Disassembler::decode((u_char*)satb_log_enqueue_with_frame,
|
||||
satb_log_enqueue_with_frame_end,
|
||||
tty);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (satb_log_enqueue_frameless == 0) {
|
||||
generate_satb_log_enqueue(with_frame);
|
||||
assert(satb_log_enqueue_frameless != 0, "postcondition.");
|
||||
if (G1SATBPrintStubs) {
|
||||
tty->print_cr("Generated frameless satb enqueue:");
|
||||
Disassembler::decode((u_char*)satb_log_enqueue_frameless,
|
||||
satb_log_enqueue_frameless_end,
|
||||
tty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3841,12 +3829,6 @@ generate_dirty_card_log_enqueue_if_necessary(jbyte* byte_map_base) {
|
||||
if (dirty_card_log_enqueue == 0) {
|
||||
generate_dirty_card_log_enqueue(byte_map_base);
|
||||
assert(dirty_card_log_enqueue != 0, "postcondition.");
|
||||
if (G1SATBPrintStubs) {
|
||||
tty->print_cr("Generated dirty_card enqueue:");
|
||||
Disassembler::decode((u_char*)dirty_card_log_enqueue,
|
||||
dirty_card_log_enqueue_end,
|
||||
tty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1181,8 +1181,6 @@ public:
|
||||
// Accessors
|
||||
static oop target( oop site);
|
||||
static void set_target( oop site, oop target);
|
||||
|
||||
static volatile oop target_volatile(oop site);
|
||||
static void set_target_volatile(oop site, oop target);
|
||||
|
||||
// Testers
|
||||
|
@ -29,10 +29,6 @@
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
|
||||
inline volatile oop java_lang_invoke_CallSite::target_volatile(oop site) {
|
||||
return oop((oopDesc *)(site->obj_field_volatile(_target_offset)));
|
||||
}
|
||||
|
||||
inline void java_lang_invoke_CallSite::set_target_volatile(oop site, oop target) {
|
||||
site->obj_field_put_volatile(_target_offset, target);
|
||||
}
|
||||
|
@ -943,13 +943,6 @@ void ConcurrentMark::checkpointRootsInitialPre() {
|
||||
|
||||
_has_aborted = false;
|
||||
|
||||
#ifndef PRODUCT
|
||||
if (G1PrintReachableAtInitialMark) {
|
||||
print_reachable("at-cycle-start",
|
||||
VerifyOption_G1UsePrevMarking, true /* all */);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize marking structures. This has to be done in a STW phase.
|
||||
reset();
|
||||
|
||||
@ -2684,166 +2677,6 @@ void ConcurrentMark::checkpointRootsFinalWork() {
|
||||
print_stats();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
class PrintReachableOopClosure: public OopClosure {
|
||||
private:
|
||||
G1CollectedHeap* _g1h;
|
||||
outputStream* _out;
|
||||
VerifyOption _vo;
|
||||
bool _all;
|
||||
|
||||
public:
|
||||
PrintReachableOopClosure(outputStream* out,
|
||||
VerifyOption vo,
|
||||
bool all) :
|
||||
_g1h(G1CollectedHeap::heap()),
|
||||
_out(out), _vo(vo), _all(all) { }
|
||||
|
||||
void do_oop(narrowOop* p) { do_oop_work(p); }
|
||||
void do_oop( oop* p) { do_oop_work(p); }
|
||||
|
||||
template <class T> void do_oop_work(T* p) {
|
||||
oop obj = oopDesc::load_decode_heap_oop(p);
|
||||
const char* str = NULL;
|
||||
const char* str2 = "";
|
||||
|
||||
if (obj == NULL) {
|
||||
str = "";
|
||||
} else if (!_g1h->is_in_g1_reserved(obj)) {
|
||||
str = " O";
|
||||
} else {
|
||||
HeapRegion* hr = _g1h->heap_region_containing(obj);
|
||||
bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo);
|
||||
bool marked = _g1h->is_marked(obj, _vo);
|
||||
|
||||
if (over_tams) {
|
||||
str = " >";
|
||||
if (marked) {
|
||||
str2 = " AND MARKED";
|
||||
}
|
||||
} else if (marked) {
|
||||
str = " M";
|
||||
} else {
|
||||
str = " NOT";
|
||||
}
|
||||
}
|
||||
|
||||
_out->print_cr(" "PTR_FORMAT": "PTR_FORMAT"%s%s",
|
||||
p2i(p), p2i((void*) obj), str, str2);
|
||||
}
|
||||
};
|
||||
|
||||
class PrintReachableObjectClosure : public ObjectClosure {
|
||||
private:
|
||||
G1CollectedHeap* _g1h;
|
||||
outputStream* _out;
|
||||
VerifyOption _vo;
|
||||
bool _all;
|
||||
HeapRegion* _hr;
|
||||
|
||||
public:
|
||||
PrintReachableObjectClosure(outputStream* out,
|
||||
VerifyOption vo,
|
||||
bool all,
|
||||
HeapRegion* hr) :
|
||||
_g1h(G1CollectedHeap::heap()),
|
||||
_out(out), _vo(vo), _all(all), _hr(hr) { }
|
||||
|
||||
void do_object(oop o) {
|
||||
bool over_tams = _g1h->allocated_since_marking(o, _hr, _vo);
|
||||
bool marked = _g1h->is_marked(o, _vo);
|
||||
bool print_it = _all || over_tams || marked;
|
||||
|
||||
if (print_it) {
|
||||
_out->print_cr(" "PTR_FORMAT"%s",
|
||||
p2i((void *)o), (over_tams) ? " >" : (marked) ? " M" : "");
|
||||
PrintReachableOopClosure oopCl(_out, _vo, _all);
|
||||
o->oop_iterate_no_header(&oopCl);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PrintReachableRegionClosure : public HeapRegionClosure {
|
||||
private:
|
||||
G1CollectedHeap* _g1h;
|
||||
outputStream* _out;
|
||||
VerifyOption _vo;
|
||||
bool _all;
|
||||
|
||||
public:
|
||||
bool doHeapRegion(HeapRegion* hr) {
|
||||
HeapWord* b = hr->bottom();
|
||||
HeapWord* e = hr->end();
|
||||
HeapWord* t = hr->top();
|
||||
HeapWord* p = _g1h->top_at_mark_start(hr, _vo);
|
||||
_out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
|
||||
"TAMS: " PTR_FORMAT, p2i(b), p2i(e), p2i(t), p2i(p));
|
||||
_out->cr();
|
||||
|
||||
HeapWord* from = b;
|
||||
HeapWord* to = t;
|
||||
|
||||
if (to > from) {
|
||||
_out->print_cr("Objects in [" PTR_FORMAT ", " PTR_FORMAT "]", p2i(from), p2i(to));
|
||||
_out->cr();
|
||||
PrintReachableObjectClosure ocl(_out, _vo, _all, hr);
|
||||
hr->object_iterate_mem_careful(MemRegion(from, to), &ocl);
|
||||
_out->cr();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PrintReachableRegionClosure(outputStream* out,
|
||||
VerifyOption vo,
|
||||
bool all) :
|
||||
_g1h(G1CollectedHeap::heap()), _out(out), _vo(vo), _all(all) { }
|
||||
};
|
||||
|
||||
void ConcurrentMark::print_reachable(const char* str,
|
||||
VerifyOption vo,
|
||||
bool all) {
|
||||
gclog_or_tty->cr();
|
||||
gclog_or_tty->print_cr("== Doing heap dump... ");
|
||||
|
||||
if (G1PrintReachableBaseFile == NULL) {
|
||||
gclog_or_tty->print_cr(" #### error: no base file defined");
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(G1PrintReachableBaseFile) + 1 + strlen(str) >
|
||||
(JVM_MAXPATHLEN - 1)) {
|
||||
gclog_or_tty->print_cr(" #### error: file name too long");
|
||||
return;
|
||||
}
|
||||
|
||||
char file_name[JVM_MAXPATHLEN];
|
||||
sprintf(file_name, "%s.%s", G1PrintReachableBaseFile, str);
|
||||
gclog_or_tty->print_cr(" dumping to file %s", file_name);
|
||||
|
||||
fileStream fout(file_name);
|
||||
if (!fout.is_open()) {
|
||||
gclog_or_tty->print_cr(" #### error: could not open file");
|
||||
return;
|
||||
}
|
||||
|
||||
outputStream* out = &fout;
|
||||
out->print_cr("-- USING %s", _g1h->top_at_mark_start_str(vo));
|
||||
out->cr();
|
||||
|
||||
out->print_cr("--- ITERATING OVER REGIONS");
|
||||
out->cr();
|
||||
PrintReachableRegionClosure rcl(out, vo, all);
|
||||
_g1h->heap_region_iterate(&rcl);
|
||||
out->cr();
|
||||
|
||||
gclog_or_tty->print_cr(" done");
|
||||
gclog_or_tty->flush();
|
||||
}
|
||||
|
||||
#endif // PRODUCT
|
||||
|
||||
void ConcurrentMark::clearRangePrevBitmap(MemRegion mr) {
|
||||
// Note we are overriding the read-only view of the prev map here, via
|
||||
// the cast.
|
||||
@ -3887,12 +3720,11 @@ void CMTask::drain_satb_buffers() {
|
||||
|
||||
CMObjectClosure oc(this);
|
||||
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
||||
satb_mq_set.set_closure(_worker_id, &oc);
|
||||
|
||||
// This keeps claiming and applying the closure to completed buffers
|
||||
// until we run out of buffers or we need to abort.
|
||||
while (!has_aborted() &&
|
||||
satb_mq_set.apply_closure_to_completed_buffer(_worker_id)) {
|
||||
satb_mq_set.apply_closure_to_completed_buffer(&oc)) {
|
||||
if (_cm->verbose_medium()) {
|
||||
gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
|
||||
}
|
||||
@ -3906,8 +3738,6 @@ void CMTask::drain_satb_buffers() {
|
||||
concurrent() ||
|
||||
satb_mq_set.completed_buffers_num() == 0, "invariant");
|
||||
|
||||
satb_mq_set.set_closure(_worker_id, NULL);
|
||||
|
||||
// again, this was a potentially expensive operation, decrease the
|
||||
// limits to get the regular clock call early
|
||||
decrease_limits();
|
||||
|
@ -110,15 +110,15 @@ void G1DefaultAllocator::abandon_gc_alloc_regions() {
|
||||
_retained_old_gc_alloc_region = NULL;
|
||||
}
|
||||
|
||||
G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
|
||||
ParGCAllocBuffer(gclab_word_size), _retired(true) { }
|
||||
G1PLAB::G1PLAB(size_t gclab_word_size) :
|
||||
PLAB(gclab_word_size), _retired(true) { }
|
||||
|
||||
HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest,
|
||||
size_t word_sz,
|
||||
AllocationContext_t context) {
|
||||
size_t gclab_word_size = _g1h->desired_plab_sz(dest);
|
||||
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
|
||||
G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);
|
||||
G1PLAB* alloc_buf = alloc_buffer(dest, context);
|
||||
add_to_alloc_buffer_waste(alloc_buf->words_remaining());
|
||||
alloc_buf->retire();
|
||||
|
||||
@ -151,7 +151,7 @@ G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :
|
||||
|
||||
void G1DefaultParGCAllocator::retire_alloc_buffers() {
|
||||
for (uint state = 0; state < InCSetState::Num; state++) {
|
||||
G1ParGCAllocBuffer* const buf = _alloc_buffers[state];
|
||||
G1PLAB* const buf = _alloc_buffers[state];
|
||||
if (buf != NULL) {
|
||||
add_to_alloc_buffer_waste(buf->words_remaining());
|
||||
buf->flush_and_retire_stats(_g1h->alloc_buffer_stats(state));
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "gc_implementation/g1/g1AllocationContext.hpp"
|
||||
#include "gc_implementation/g1/g1AllocRegion.hpp"
|
||||
#include "gc_implementation/g1/g1InCSetState.hpp"
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
#include "gc_implementation/shared/plab.hpp"
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
|
||||
class EvacuationInfo;
|
||||
@ -147,18 +147,18 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class G1ParGCAllocBuffer: public ParGCAllocBuffer {
|
||||
class G1PLAB: public PLAB {
|
||||
private:
|
||||
bool _retired;
|
||||
|
||||
public:
|
||||
G1ParGCAllocBuffer(size_t gclab_word_size);
|
||||
virtual ~G1ParGCAllocBuffer() {
|
||||
G1PLAB(size_t gclab_word_size);
|
||||
virtual ~G1PLAB() {
|
||||
guarantee(_retired, "Allocation buffer has not been retired");
|
||||
}
|
||||
|
||||
virtual void set_buf(HeapWord* buf) {
|
||||
ParGCAllocBuffer::set_buf(buf);
|
||||
PLAB::set_buf(buf);
|
||||
_retired = false;
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ public:
|
||||
if (_retired) {
|
||||
return;
|
||||
}
|
||||
ParGCAllocBuffer::retire();
|
||||
PLAB::retire();
|
||||
_retired = true;
|
||||
}
|
||||
};
|
||||
@ -190,7 +190,7 @@ protected:
|
||||
void add_to_undo_waste(size_t waste) { _undo_waste += waste; }
|
||||
|
||||
virtual void retire_alloc_buffers() = 0;
|
||||
virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
|
||||
virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0;
|
||||
|
||||
// Calculate the survivor space object alignment in bytes. Returns that or 0 if
|
||||
// there are no restrictions on survivor alignment.
|
||||
@ -229,7 +229,7 @@ public:
|
||||
HeapWord* plab_allocate(InCSetState dest,
|
||||
size_t word_sz,
|
||||
AllocationContext_t context) {
|
||||
G1ParGCAllocBuffer* buffer = alloc_buffer(dest, context);
|
||||
G1PLAB* buffer = alloc_buffer(dest, context);
|
||||
if (_survivor_alignment_bytes == 0) {
|
||||
return buffer->allocate(word_sz);
|
||||
} else {
|
||||
@ -259,14 +259,14 @@ public:
|
||||
};
|
||||
|
||||
class G1DefaultParGCAllocator : public G1ParGCAllocator {
|
||||
G1ParGCAllocBuffer _surviving_alloc_buffer;
|
||||
G1ParGCAllocBuffer _tenured_alloc_buffer;
|
||||
G1ParGCAllocBuffer* _alloc_buffers[InCSetState::Num];
|
||||
G1PLAB _surviving_alloc_buffer;
|
||||
G1PLAB _tenured_alloc_buffer;
|
||||
G1PLAB* _alloc_buffers[InCSetState::Num];
|
||||
|
||||
public:
|
||||
G1DefaultParGCAllocator(G1CollectedHeap* g1h);
|
||||
|
||||
virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) {
|
||||
virtual G1PLAB* alloc_buffer(InCSetState dest, AllocationContext_t context) {
|
||||
assert(dest.is_valid(),
|
||||
err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value()));
|
||||
assert(_alloc_buffers[dest.value()] != NULL,
|
||||
|
@ -410,10 +410,6 @@ bool G1CollectedHeap::is_scavengable(const void* p) {
|
||||
return !hr->is_humongous();
|
||||
}
|
||||
|
||||
// Private class members.
|
||||
|
||||
G1CollectedHeap* G1CollectedHeap::_g1h;
|
||||
|
||||
// Private methods.
|
||||
|
||||
HeapRegion*
|
||||
@ -1769,14 +1765,12 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
|
||||
_gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()),
|
||||
_gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) {
|
||||
|
||||
_g1h = this;
|
||||
|
||||
_workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads,
|
||||
/* are_GC_task_threads */true,
|
||||
/* are_ConcurrentGC_threads */false);
|
||||
_workers->initialize_workers();
|
||||
|
||||
_allocator = G1Allocator::create_allocator(_g1h);
|
||||
_allocator = G1Allocator::create_allocator(this);
|
||||
_humongous_object_threshold_in_words = HeapRegion::GrainWords / 2;
|
||||
|
||||
int n_queues = MAX2((int)ParallelGCThreads, 1);
|
||||
@ -1939,8 +1933,6 @@ jint G1CollectedHeap::initialize() {
|
||||
|
||||
_bot_shared = new G1BlockOffsetSharedArray(reserved_region(), bot_storage);
|
||||
|
||||
_g1h = this;
|
||||
|
||||
{
|
||||
HeapWord* start = _hrm.reserved().start();
|
||||
HeapWord* end = _hrm.reserved().end();
|
||||
@ -3109,12 +3101,6 @@ void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
|
||||
// print_extended_on() instead of print_on().
|
||||
print_extended_on(gclog_or_tty);
|
||||
gclog_or_tty->cr();
|
||||
#ifndef PRODUCT
|
||||
if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) {
|
||||
concurrent_mark()->print_reachable("at-verification-failure",
|
||||
vo, false /* all */);
|
||||
}
|
||||
#endif
|
||||
gclog_or_tty->flush();
|
||||
}
|
||||
guarantee(!failures, "there should not have been any failures");
|
||||
@ -3320,9 +3306,10 @@ void G1CollectedHeap::print_all_rsets() {
|
||||
#endif // PRODUCT
|
||||
|
||||
G1CollectedHeap* G1CollectedHeap::heap() {
|
||||
assert(_g1h != NULL, "Uninitialized access to G1CollectedHeap::heap()");
|
||||
assert(_g1h->kind() == CollectedHeap::G1CollectedHeap, "Not a G1 heap");
|
||||
return _g1h;
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
assert(heap != NULL, "Uninitialized access to G1CollectedHeap::heap()");
|
||||
assert(heap->kind() == CollectedHeap::G1CollectedHeap, "Not a G1CollectedHeap");
|
||||
return (G1CollectedHeap*)heap;
|
||||
}
|
||||
|
||||
void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
|
||||
@ -4877,7 +4864,7 @@ void G1CollectedHeap::parallel_cleaning(BoolObjectClosure* is_alive,
|
||||
void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
|
||||
bool process_strings, bool process_symbols) {
|
||||
{
|
||||
uint n_workers = _g1h->workers()->active_workers();
|
||||
uint n_workers = workers()->active_workers();
|
||||
G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
|
||||
set_par_threads(n_workers);
|
||||
workers()->run_task(&g1_unlink_task);
|
||||
@ -4909,7 +4896,7 @@ class G1RedirtyLoggedCardsTask : public AbstractGangTask {
|
||||
void G1CollectedHeap::redirty_logged_cards() {
|
||||
double redirty_logged_cards_start = os::elapsedTime();
|
||||
|
||||
uint n_workers = _g1h->workers()->active_workers();
|
||||
uint n_workers = workers()->active_workers();
|
||||
|
||||
G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
|
||||
dirty_card_queue_set().reset_for_par_iteration();
|
||||
@ -5342,7 +5329,7 @@ void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
|
||||
|
||||
OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl;
|
||||
|
||||
if (_g1h->g1_policy()->during_initial_mark_pause()) {
|
||||
if (g1_policy()->during_initial_mark_pause()) {
|
||||
// We also need to mark copied objects.
|
||||
copy_non_heap_cl = ©_mark_non_heap_cl;
|
||||
}
|
||||
@ -6097,12 +6084,12 @@ void G1CollectedHeap::eagerly_reclaim_humongous_regions() {
|
||||
HeapRegionSetCount empty_set;
|
||||
remove_from_old_sets(empty_set, cl.humongous_free_count());
|
||||
|
||||
G1HRPrinter* hr_printer = _g1h->hr_printer();
|
||||
if (hr_printer->is_active()) {
|
||||
G1HRPrinter* hrp = hr_printer();
|
||||
if (hrp->is_active()) {
|
||||
FreeRegionListIterator iter(&local_cleanup_list);
|
||||
while (iter.more_available()) {
|
||||
HeapRegion* hr = iter.get_next();
|
||||
hr_printer->cleanup(hr);
|
||||
hrp->cleanup(hr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,6 @@
|
||||
#include "gc_implementation/g1/heapRegionManager.hpp"
|
||||
#include "gc_implementation/g1/heapRegionSet.hpp"
|
||||
#include "gc_implementation/shared/hSpaceCounters.hpp"
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
#include "memory/barrierSet.hpp"
|
||||
#include "memory/memRegion.hpp"
|
||||
@ -202,9 +201,6 @@ class G1CollectedHeap : public CollectedHeap {
|
||||
friend class G1CheckCSetFastTableClosure;
|
||||
|
||||
private:
|
||||
// The one and only G1CollectedHeap, so static functions can find it.
|
||||
static G1CollectedHeap* _g1h;
|
||||
|
||||
FlexibleWorkGang* _workers;
|
||||
|
||||
static size_t _humongous_object_threshold_in_words;
|
||||
|
@ -119,7 +119,6 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
|
||||
bool clear_all_softrefs) {
|
||||
// Recursively traverse all live objects and mark them
|
||||
GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
|
||||
GenMarkSweep::trace(" 1");
|
||||
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
|
||||
@ -199,7 +198,6 @@ void G1MarkSweep::mark_sweep_phase2() {
|
||||
// tracking expects us to do so. See comment under phase4.
|
||||
|
||||
GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
|
||||
GenMarkSweep::trace("2");
|
||||
|
||||
prepare_compaction();
|
||||
}
|
||||
@ -233,7 +231,6 @@ void G1MarkSweep::mark_sweep_phase3() {
|
||||
|
||||
// Adjust the pointers to reflect the new locations
|
||||
GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
|
||||
GenMarkSweep::trace("3");
|
||||
|
||||
// Need cleared claim bits for the roots processing
|
||||
ClassLoaderDataGraph::clear_claimed_marks();
|
||||
@ -295,7 +292,6 @@ void G1MarkSweep::mark_sweep_phase4() {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
|
||||
GCTraceTime tm("phase 4", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
|
||||
GenMarkSweep::trace("4");
|
||||
|
||||
G1SpaceCompactClosure blk;
|
||||
g1h->heap_region_iterate(&blk);
|
||||
|
@ -41,15 +41,6 @@
|
||||
develop(intx, G1MarkingVerboseLevel, 0, \
|
||||
"Level (0-4) of verboseness of the marking code") \
|
||||
\
|
||||
develop(bool, G1PrintReachableAtInitialMark, false, \
|
||||
"Reachable object dump at the initial mark pause") \
|
||||
\
|
||||
develop(bool, G1VerifyDuringGCPrintReachable, false, \
|
||||
"If conc mark verification fails, dump reachable objects") \
|
||||
\
|
||||
develop(ccstr, G1PrintReachableBaseFile, NULL, \
|
||||
"The base file name for the reachable object dumps") \
|
||||
\
|
||||
develop(bool, G1TraceMarkStackOverflow, false, \
|
||||
"If true, extra debugging code for CM restart for ovflw.") \
|
||||
\
|
||||
@ -99,9 +90,6 @@
|
||||
"the buffer will be enqueued for processing. A value of 0 " \
|
||||
"specifies that mutator threads should not do such filtering.") \
|
||||
\
|
||||
develop(bool, G1SATBPrintStubs, false, \
|
||||
"If true, print generated stubs for the SATB barrier") \
|
||||
\
|
||||
experimental(intx, G1ExpandByPercentOfAvailable, 20, \
|
||||
"When expanding, % of uncommitted space to claim.") \
|
||||
\
|
||||
|
@ -44,6 +44,7 @@
|
||||
// The solution is to remove this method from the definition
|
||||
// of a Space.
|
||||
|
||||
class G1CollectedHeap;
|
||||
class HeapRegionRemSet;
|
||||
class HeapRegionRemSetIterator;
|
||||
class HeapRegion;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2015, 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
|
||||
@ -33,30 +33,67 @@
|
||||
#include "runtime/vmThread.hpp"
|
||||
|
||||
void ObjPtrQueue::flush() {
|
||||
// The buffer might contain refs into the CSet. We have to filter it
|
||||
// first before we flush it, otherwise we might end up with an
|
||||
// enqueued buffer with refs into the CSet which breaks our invariants.
|
||||
// Filter now to possibly save work later. If filtering empties the
|
||||
// buffer then flush_impl can deallocate the buffer.
|
||||
filter();
|
||||
flush_impl();
|
||||
}
|
||||
|
||||
// This method removes entries from an SATB buffer that will not be
|
||||
// useful to the concurrent marking threads. An entry is removed if it
|
||||
// satisfies one of the following conditions:
|
||||
// Return true if a SATB buffer entry refers to an object that
|
||||
// requires marking.
|
||||
//
|
||||
// * it points to an object outside the G1 heap (G1's concurrent
|
||||
// marking only visits objects inside the G1 heap),
|
||||
// * it points to an object that has been allocated since marking
|
||||
// started (according to SATB those objects do not need to be
|
||||
// visited during marking), or
|
||||
// * it points to an object that has already been marked (no need to
|
||||
// process it again).
|
||||
// The entry must point into the G1 heap. In particular, it must not
|
||||
// be a NULL pointer. NULL pointers are pre-filtered and never
|
||||
// inserted into a SATB buffer.
|
||||
//
|
||||
// The rest of the entries will be retained and are compacted towards
|
||||
// the top of the buffer. Note that, because we do not allow old
|
||||
// regions in the CSet during marking, all objects on the CSet regions
|
||||
// are young (eden or survivors) and therefore implicitly live. So any
|
||||
// references into the CSet will be removed during filtering.
|
||||
// An entry that is below the NTAMS pointer for the containing heap
|
||||
// region requires marking. Such an entry must point to a valid object.
|
||||
//
|
||||
// An entry that is at least the NTAMS pointer for the containing heap
|
||||
// region might be any of the following, none of which should be marked.
|
||||
//
|
||||
// * A reference to an object allocated since marking started.
|
||||
// According to SATB, such objects are implicitly kept live and do
|
||||
// not need to be dealt with via SATB buffer processing.
|
||||
//
|
||||
// * A reference to a young generation object. Young objects are
|
||||
// handled separately and are not marked by concurrent marking.
|
||||
//
|
||||
// * A stale reference to a young generation object. If a young
|
||||
// generation object reference is recorded and not filtered out
|
||||
// before being moved by a young collection, the reference becomes
|
||||
// stale.
|
||||
//
|
||||
// * A stale reference to an eagerly reclaimed humongous object. If a
|
||||
// humongous object is recorded and then reclaimed, the reference
|
||||
// becomes stale.
|
||||
//
|
||||
// The stale reference cases are implicitly handled by the NTAMS
|
||||
// comparison. Because of the possibility of stale references, buffer
|
||||
// processing must be somewhat circumspect and not assume entries
|
||||
// in an unfiltered buffer refer to valid objects.
|
||||
|
||||
inline bool requires_marking(const void* entry, G1CollectedHeap* heap) {
|
||||
// Includes rejection of NULL pointers.
|
||||
assert(heap->is_in_reserved(entry),
|
||||
err_msg("Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)));
|
||||
|
||||
HeapRegion* region = heap->heap_region_containing_raw(entry);
|
||||
assert(region != NULL, err_msg("No region for " PTR_FORMAT, p2i(entry)));
|
||||
if (entry >= region->next_top_at_mark_start()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(((oop)entry)->is_oop(true /* ignore mark word */),
|
||||
err_msg("Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This method removes entries from a SATB buffer that will not be
|
||||
// useful to the concurrent marking threads. Entries are retained if
|
||||
// they require marking and are not already marked. Retained entries
|
||||
// are compacted toward the top of the buffer.
|
||||
|
||||
void ObjPtrQueue::filter() {
|
||||
G1CollectedHeap* g1h = G1CollectedHeap::heap();
|
||||
@ -78,26 +115,25 @@ void ObjPtrQueue::filter() {
|
||||
assert(i > 0, "we should have at least one more entry to process");
|
||||
i -= oopSize;
|
||||
debug_only(entries += 1;)
|
||||
oop* p = (oop*) &buf[byte_index_to_index((int) i)];
|
||||
oop obj = *p;
|
||||
void** p = &buf[byte_index_to_index((int) i)];
|
||||
void* entry = *p;
|
||||
// NULL the entry so that unused parts of the buffer contain NULLs
|
||||
// at the end. If we are going to retain it we will copy it to its
|
||||
// final place. If we have retained all entries we have visited so
|
||||
// far, we'll just end up copying it to the same place.
|
||||
*p = NULL;
|
||||
|
||||
bool retain = g1h->is_obj_ill(obj);
|
||||
if (retain) {
|
||||
if (requires_marking(entry, g1h) && !g1h->isMarkedNext((oop)entry)) {
|
||||
assert(new_index > 0, "we should not have already filled up the buffer");
|
||||
new_index -= oopSize;
|
||||
assert(new_index >= i,
|
||||
"new_index should never be below i, as we always compact 'up'");
|
||||
oop* new_p = (oop*) &buf[byte_index_to_index((int) new_index)];
|
||||
void** new_p = &buf[byte_index_to_index((int) new_index)];
|
||||
assert(new_p >= p, "the destination location should never be below "
|
||||
"the source as we always compact 'up'");
|
||||
assert(*new_p == NULL,
|
||||
"we should have already cleared the destination location");
|
||||
*new_p = obj;
|
||||
*new_p = entry;
|
||||
debug_only(retained += 1;)
|
||||
}
|
||||
}
|
||||
@ -184,23 +220,12 @@ void ObjPtrQueue::print(const char* name,
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
#ifdef ASSERT
|
||||
void ObjPtrQueue::verify_oops_in_buffer() {
|
||||
if (_buf == NULL) return;
|
||||
for (size_t i = _index; i < _sz; i += oopSize) {
|
||||
oop obj = (oop)_buf[byte_index_to_index((int)i)];
|
||||
assert(obj != NULL && obj->is_oop(true /* ignore mark word */),
|
||||
"Not an oop");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away
|
||||
#pragma warning( disable:4355 ) // 'this' : used in base member initializer list
|
||||
#endif // _MSC_VER
|
||||
|
||||
SATBMarkQueueSet::SATBMarkQueueSet() :
|
||||
PtrQueueSet(), _closures(NULL),
|
||||
PtrQueueSet(),
|
||||
_shared_satb_queue(this, true /*perm*/) { }
|
||||
|
||||
void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||
@ -208,11 +233,9 @@ void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
|
||||
Mutex* lock) {
|
||||
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
|
||||
_shared_satb_queue.set_lock(lock);
|
||||
_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
|
||||
}
|
||||
|
||||
void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
|
||||
DEBUG_ONLY(t->satb_mark_queue().verify_oops_in_buffer();)
|
||||
t->satb_mark_queue().handle_zero_index();
|
||||
}
|
||||
|
||||
@ -272,13 +295,7 @@ void SATBMarkQueueSet::filter_thread_buffers() {
|
||||
shared_satb_queue()->filter();
|
||||
}
|
||||
|
||||
void SATBMarkQueueSet::set_closure(uint worker, ObjectClosure* closure) {
|
||||
assert(_closures != NULL, "Precondition");
|
||||
assert(worker < ParallelGCThreads, "Worker index must be in range [0...ParallelGCThreads)");
|
||||
_closures[worker] = closure;
|
||||
}
|
||||
|
||||
bool SATBMarkQueueSet::apply_closure_to_completed_buffer(uint worker) {
|
||||
bool SATBMarkQueueSet::apply_closure_to_completed_buffer(ObjectClosure* cl) {
|
||||
BufferNode* nd = NULL;
|
||||
{
|
||||
MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
|
||||
@ -290,7 +307,6 @@ bool SATBMarkQueueSet::apply_closure_to_completed_buffer(uint worker) {
|
||||
if (_n_completed_buffers == 0) _process_completed = false;
|
||||
}
|
||||
}
|
||||
ObjectClosure* cl = _closures[worker];
|
||||
if (nd != NULL) {
|
||||
void **buf = BufferNode::make_buffer_from_node(nd);
|
||||
ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2015, 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
|
||||
@ -72,13 +72,9 @@ public:
|
||||
void print(const char* name);
|
||||
static void print(const char* name, void** buf, size_t index, size_t sz);
|
||||
#endif // PRODUCT
|
||||
|
||||
void verify_oops_in_buffer() NOT_DEBUG_RETURN;
|
||||
};
|
||||
|
||||
class SATBMarkQueueSet: public PtrQueueSet {
|
||||
ObjectClosure** _closures; // One per ParGCThread.
|
||||
|
||||
ObjPtrQueue _shared_satb_queue;
|
||||
|
||||
#ifdef ASSERT
|
||||
@ -104,16 +100,10 @@ public:
|
||||
// Filter all the currently-active SATB buffers.
|
||||
void filter_thread_buffers();
|
||||
|
||||
// Register closure for the given worker thread. The "apply_closure_to_completed_buffer"
|
||||
// method will apply this closure to a completed buffer, and "iterate_closure_all_threads"
|
||||
// applies it to partially-filled buffers (the latter should only be done
|
||||
// with the world stopped).
|
||||
void set_closure(uint worker, ObjectClosure* closure);
|
||||
|
||||
// If there exists some completed buffer, pop it, then apply the
|
||||
// registered closure to all its elements, and return true. If no
|
||||
// closure to all its elements, and return true. If no
|
||||
// completed buffers exist, return false.
|
||||
bool apply_closure_to_completed_buffer(uint worker);
|
||||
bool apply_closure_to_completed_buffer(ObjectClosure* closure);
|
||||
|
||||
// Apply the given closure on enqueued and currently-active buffers
|
||||
// respectively. Both methods are read-only, i.e., they do not
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "gc_implementation/shared/gcTimer.hpp"
|
||||
#include "gc_implementation/shared/gcTrace.hpp"
|
||||
#include "gc_implementation/shared/gcTraceTime.hpp"
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.inline.hpp"
|
||||
#include "gc_implementation/shared/plab.inline.hpp"
|
||||
#include "gc_implementation/shared/spaceDecorator.hpp"
|
||||
#include "memory/defNewGeneration.inline.hpp"
|
||||
#include "memory/genCollectedHeap.hpp"
|
||||
@ -226,7 +226,7 @@ HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
|
||||
// buffer.
|
||||
HeapWord* obj = NULL;
|
||||
if (!_to_space_full) {
|
||||
ParGCAllocBuffer* const plab = to_space_alloc_buffer();
|
||||
PLAB* const plab = to_space_alloc_buffer();
|
||||
Space* const sp = to_space();
|
||||
if (word_sz * 100 <
|
||||
ParallelGCBufferWastePct * plab->word_sz()) {
|
||||
@ -236,7 +236,7 @@ HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
|
||||
HeapWord* buf_space = sp->par_allocate(buf_size);
|
||||
if (buf_space == NULL) {
|
||||
const size_t min_bytes =
|
||||
ParGCAllocBuffer::min_size() << LogHeapWordSize;
|
||||
PLAB::min_size() << LogHeapWordSize;
|
||||
size_t free_bytes = sp->free();
|
||||
while(buf_space == NULL && free_bytes >= min_bytes) {
|
||||
buf_size = free_bytes >> LogHeapWordSize;
|
||||
@ -252,7 +252,7 @@ HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
|
||||
record_survivor_plab(buf_space, buf_size);
|
||||
obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
|
||||
// Note that we cannot compare buf_size < word_sz below
|
||||
// because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
|
||||
// because of AlignmentReserve (see PLAB::allocate()).
|
||||
assert(obj != NULL || plab->words_remaining() < word_sz,
|
||||
"Else should have been able to allocate");
|
||||
// It's conceivable that we may be able to use the
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include "gc_implementation/parNew/parOopClosures.hpp"
|
||||
#include "gc_implementation/shared/gcTrace.hpp"
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
#include "gc_implementation/shared/plab.hpp"
|
||||
#include "gc_implementation/shared/copyFailedInfo.hpp"
|
||||
#include "memory/defNewGeneration.hpp"
|
||||
#include "memory/padded.hpp"
|
||||
@ -65,7 +65,7 @@ class ParScanThreadState {
|
||||
ObjToScanQueue *_work_queue;
|
||||
Stack<oop, mtGC>* const _overflow_stack;
|
||||
|
||||
ParGCAllocBuffer _to_space_alloc_buffer;
|
||||
PLAB _to_space_alloc_buffer;
|
||||
|
||||
ParScanWithoutBarrierClosure _to_space_closure; // scan_without_gc_barrier
|
||||
ParScanWithBarrierClosure _old_gen_closure; // scan_with_gc_barrier
|
||||
@ -140,7 +140,7 @@ class ParScanThreadState {
|
||||
|
||||
ObjToScanQueue* work_queue() { return _work_queue; }
|
||||
|
||||
ParGCAllocBuffer* to_space_alloc_buffer() {
|
||||
PLAB* to_space_alloc_buffer() {
|
||||
return &_to_space_alloc_buffer;
|
||||
}
|
||||
|
||||
|
@ -49,16 +49,11 @@ PSYoungGen* ParallelScavengeHeap::_young_gen = NULL;
|
||||
PSOldGen* ParallelScavengeHeap::_old_gen = NULL;
|
||||
PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL;
|
||||
PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
|
||||
ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
|
||||
GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
|
||||
|
||||
jint ParallelScavengeHeap::initialize() {
|
||||
CollectedHeap::pre_initialize();
|
||||
|
||||
// Initialize collector policy
|
||||
_collector_policy = new GenerationSizer();
|
||||
_collector_policy->initialize_all();
|
||||
|
||||
const size_t heap_size = _collector_policy->max_heap_byte_size();
|
||||
|
||||
ReservedSpace heap_rs = Universe::reserve_heap(heap_size, _collector_policy->heap_alignment());
|
||||
@ -89,7 +84,6 @@ jint ParallelScavengeHeap::initialize() {
|
||||
double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
|
||||
double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
|
||||
|
||||
_psh = this;
|
||||
_gens = new AdjoiningGenerations(heap_rs, _collector_policy, generation_alignment());
|
||||
|
||||
_old_gen = _gens->old_gen();
|
||||
@ -634,9 +628,10 @@ void ParallelScavengeHeap::trace_heap(GCWhen::Type when, const GCTracer* gc_trac
|
||||
}
|
||||
|
||||
ParallelScavengeHeap* ParallelScavengeHeap::heap() {
|
||||
assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
|
||||
assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap");
|
||||
return _psh;
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
assert(heap != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
|
||||
assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Not a ParallelScavengeHeap");
|
||||
return (ParallelScavengeHeap*)heap;
|
||||
}
|
||||
|
||||
// Before delegating the resize to the young generation,
|
||||
|
@ -53,8 +53,6 @@ class ParallelScavengeHeap : public CollectedHeap {
|
||||
static PSAdaptiveSizePolicy* _size_policy;
|
||||
static PSGCAdaptivePolicyCounters* _gc_policy_counters;
|
||||
|
||||
static ParallelScavengeHeap* _psh;
|
||||
|
||||
GenerationSizer* _collector_policy;
|
||||
|
||||
// Collection of generations that are adjacent in the
|
||||
@ -76,7 +74,8 @@ class ParallelScavengeHeap : public CollectedHeap {
|
||||
HeapWord* mem_allocate_old_gen(size_t size);
|
||||
|
||||
public:
|
||||
ParallelScavengeHeap() : CollectedHeap(), _death_march_count(0) { }
|
||||
ParallelScavengeHeap(GenerationSizer* policy) :
|
||||
CollectedHeap(), _collector_policy(policy), _death_march_count(0) { }
|
||||
|
||||
// For use by VM operations
|
||||
enum CollectionType {
|
||||
|
@ -510,7 +510,6 @@ void PSMarkSweep::deallocate_stacks() {
|
||||
void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
// Recursively traverse all live objects and mark them
|
||||
GCTraceTime tm("phase 1", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace(" 1");
|
||||
|
||||
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
|
||||
|
||||
@ -570,7 +569,6 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
|
||||
void PSMarkSweep::mark_sweep_phase2() {
|
||||
GCTraceTime tm("phase 2", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("2");
|
||||
|
||||
// Now all live objects are marked, compute the new object addresses.
|
||||
|
||||
@ -598,7 +596,6 @@ static PSAlwaysTrueClosure always_true;
|
||||
void PSMarkSweep::mark_sweep_phase3() {
|
||||
// Adjust the pointers to reflect the new locations
|
||||
GCTraceTime tm("phase 3", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("3");
|
||||
|
||||
ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();
|
||||
PSYoungGen* young_gen = heap->young_gen();
|
||||
@ -639,7 +636,6 @@ void PSMarkSweep::mark_sweep_phase3() {
|
||||
void PSMarkSweep::mark_sweep_phase4() {
|
||||
EventMark m("4 compact heap");
|
||||
GCTraceTime tm("phase 4", PrintGCDetails && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("4");
|
||||
|
||||
// All pointers are now adjusted, move objects accordingly
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2015, 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
|
||||
@ -60,11 +60,29 @@ class PSOldGen : public CHeapObj<mtGC> {
|
||||
// Used when initializing the _name field.
|
||||
static inline const char* select_name();
|
||||
|
||||
#ifdef ASSERT
|
||||
void assert_block_in_covered_region(MemRegion new_memregion) {
|
||||
// Explictly capture current covered_region in a local
|
||||
MemRegion covered_region = this->start_array()->covered_region();
|
||||
assert(covered_region.contains(new_memregion),
|
||||
err_msg("new region is not in covered_region [ "PTR_FORMAT", "PTR_FORMAT" ], "
|
||||
"new region [ "PTR_FORMAT", "PTR_FORMAT" ], "
|
||||
"object space [ "PTR_FORMAT", "PTR_FORMAT" ]",
|
||||
p2i(covered_region.start()),
|
||||
p2i(covered_region.end()),
|
||||
p2i(new_memregion.start()),
|
||||
p2i(new_memregion.end()),
|
||||
p2i(this->object_space()->used_region().start()),
|
||||
p2i(this->object_space()->used_region().end())));
|
||||
}
|
||||
#endif
|
||||
|
||||
HeapWord* allocate_noexpand(size_t word_size) {
|
||||
// We assume the heap lock is held here.
|
||||
assert_locked_or_safepoint(Heap_lock);
|
||||
HeapWord* res = object_space()->allocate(word_size);
|
||||
if (res != NULL) {
|
||||
DEBUG_ONLY(assert_block_in_covered_region(MemRegion(res, word_size)));
|
||||
_start_array.allocate_block(res);
|
||||
}
|
||||
return res;
|
||||
@ -77,6 +95,7 @@ class PSOldGen : public CHeapObj<mtGC> {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "Must only be called at safepoint");
|
||||
HeapWord* res = object_space()->cas_allocate(word_size);
|
||||
if (res != NULL) {
|
||||
DEBUG_ONLY(assert_block_in_covered_region(MemRegion(res, word_size)));
|
||||
_start_array.allocate_block(res);
|
||||
}
|
||||
return res;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2007, 2015, 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
|
||||
@ -61,7 +61,6 @@
|
||||
\
|
||||
static_field(ParallelScavengeHeap, _young_gen, PSYoungGen*) \
|
||||
static_field(ParallelScavengeHeap, _old_gen, PSOldGen*) \
|
||||
static_field(ParallelScavengeHeap, _psh, ParallelScavengeHeap*) \
|
||||
\
|
||||
|
||||
#define VM_TYPES_PARALLELGC(declare_type, \
|
||||
|
@ -338,15 +338,6 @@ void marksweep_init() {
|
||||
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
void MarkSweep::trace(const char* msg) {
|
||||
if (TraceMarkSweep)
|
||||
gclog_or_tty->print("%s", msg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int InstanceKlass::oop_ms_adjust_pointers(oop obj) {
|
||||
int size = size_helper();
|
||||
oop_oop_iterate_oop_maps<true>(obj, &MarkSweep::adjust_pointer_closure);
|
||||
|
@ -131,9 +131,6 @@ class MarkSweep : AllStatic {
|
||||
// Non public closures
|
||||
static KeepAliveClosure keep_alive;
|
||||
|
||||
// Debugging
|
||||
static void trace(const char* msg) PRODUCT_RETURN;
|
||||
|
||||
public:
|
||||
// Public closures
|
||||
static IsAliveClosure is_alive;
|
||||
|
@ -23,21 +23,21 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
#include "gc_implementation/shared/plab.hpp"
|
||||
#include "memory/threadLocalAllocBuffer.hpp"
|
||||
#include "oops/arrayOop.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
|
||||
size_t ParGCAllocBuffer::min_size() {
|
||||
size_t PLAB::min_size() {
|
||||
// Make sure that we return something that is larger than AlignmentReserve
|
||||
return align_object_size(MAX2(MinTLABSize / HeapWordSize, (uintx)oopDesc::header_size())) + AlignmentReserve;
|
||||
}
|
||||
|
||||
size_t ParGCAllocBuffer::max_size() {
|
||||
size_t PLAB::max_size() {
|
||||
return ThreadLocalAllocBuffer::max_size();
|
||||
}
|
||||
|
||||
ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) :
|
||||
PLAB::PLAB(size_t desired_plab_sz_) :
|
||||
_word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
|
||||
_end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
|
||||
{
|
||||
@ -53,9 +53,9 @@ ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) :
|
||||
// the smallest object. We can't allow that because the buffer must
|
||||
// look like it's full of objects when we retire it, so we make
|
||||
// sure we have enough space for a filler int array object.
|
||||
size_t ParGCAllocBuffer::AlignmentReserve;
|
||||
size_t PLAB::AlignmentReserve;
|
||||
|
||||
void ParGCAllocBuffer::flush_and_retire_stats(PLABStats* stats) {
|
||||
void PLAB::flush_and_retire_stats(PLABStats* stats) {
|
||||
// Retire the last allocation buffer.
|
||||
size_t unused = retire_internal();
|
||||
|
||||
@ -71,11 +71,11 @@ void ParGCAllocBuffer::flush_and_retire_stats(PLABStats* stats) {
|
||||
_wasted = 0;
|
||||
}
|
||||
|
||||
void ParGCAllocBuffer::retire() {
|
||||
void PLAB::retire() {
|
||||
_wasted += retire_internal();
|
||||
}
|
||||
|
||||
size_t ParGCAllocBuffer::retire_internal() {
|
||||
size_t PLAB::retire_internal() {
|
||||
size_t result = 0;
|
||||
if (_top < _hard_end) {
|
||||
CollectedHeap::fill_with_object(_top, _hard_end);
|
||||
@ -126,8 +126,8 @@ void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void ParGCAllocBuffer::print() {
|
||||
gclog_or_tty->print_cr("parGCAllocBuffer: _bottom: " PTR_FORMAT " _top: " PTR_FORMAT
|
||||
void PLAB::print() {
|
||||
gclog_or_tty->print_cr("PLAB: _bottom: " PTR_FORMAT " _top: " PTR_FORMAT
|
||||
" _end: " PTR_FORMAT " _hard_end: " PTR_FORMAT ")",
|
||||
p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
|
||||
}
|
@ -22,8 +22,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
|
||||
|
||||
#include "gc_implementation/shared/gcUtil.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
@ -34,7 +34,7 @@
|
||||
class PLABStats;
|
||||
|
||||
// A per-thread allocation buffer used during GC.
|
||||
class ParGCAllocBuffer: public CHeapObj<mtGC> {
|
||||
class PLAB: public CHeapObj<mtGC> {
|
||||
protected:
|
||||
char head[32];
|
||||
size_t _word_sz; // In HeapWord units
|
||||
@ -65,8 +65,8 @@ protected:
|
||||
public:
|
||||
// Initializes the buffer to be empty, but with the given "word_sz".
|
||||
// Must get initialized with "set_buf" for an allocation to succeed.
|
||||
ParGCAllocBuffer(size_t word_sz);
|
||||
virtual ~ParGCAllocBuffer() {}
|
||||
PLAB(size_t word_sz);
|
||||
virtual ~PLAB() {}
|
||||
|
||||
// Minimum PLAB size.
|
||||
static size_t min_size();
|
||||
@ -166,11 +166,11 @@ class PLABStats VALUE_OBJ_CLASS_SPEC {
|
||||
{ }
|
||||
|
||||
static const size_t min_size() {
|
||||
return ParGCAllocBuffer::min_size();
|
||||
return PLAB::min_size();
|
||||
}
|
||||
|
||||
static const size_t max_size() {
|
||||
return ParGCAllocBuffer::max_size();
|
||||
return PLAB::max_size();
|
||||
}
|
||||
|
||||
size_t desired_plab_sz() {
|
||||
@ -194,4 +194,4 @@ class PLABStats VALUE_OBJ_CLASS_SPEC {
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, 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
|
||||
@ -22,13 +22,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
|
||||
#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
|
||||
#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
|
||||
|
||||
#include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
#include "gc_implementation/shared/plab.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
|
||||
HeapWord* ParGCAllocBuffer::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) {
|
||||
HeapWord* PLAB::allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes) {
|
||||
|
||||
HeapWord* res = CollectedHeap::align_allocation_or_fail(_top, _end, alignment_in_bytes);
|
||||
if (res == NULL) {
|
||||
@ -41,4 +41,4 @@ HeapWord* ParGCAllocBuffer::allocate_aligned(size_t word_sz, unsigned short alig
|
||||
return allocate(word_sz);
|
||||
}
|
||||
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
|
||||
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
|
@ -59,7 +59,6 @@
|
||||
#include "gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
GenCollectedHeap* GenCollectedHeap::_gch;
|
||||
NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;)
|
||||
|
||||
// The set of potentially parallel tasks in root scanning.
|
||||
@ -127,8 +126,6 @@ jint GenCollectedHeap::initialize() {
|
||||
_rem_set = collector_policy()->create_rem_set(reserved_region());
|
||||
set_barrier_set(rem_set()->bs());
|
||||
|
||||
_gch = this;
|
||||
|
||||
ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false);
|
||||
_young_gen = gen_policy()->young_gen_spec()->init(young_rs, 0, rem_set());
|
||||
heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size());
|
||||
@ -1103,9 +1100,10 @@ void GenCollectedHeap::save_marks() {
|
||||
}
|
||||
|
||||
GenCollectedHeap* GenCollectedHeap::heap() {
|
||||
assert(_gch != NULL, "Uninitialized access to GenCollectedHeap::heap()");
|
||||
assert(_gch->kind() == CollectedHeap::GenCollectedHeap, "not a generational heap");
|
||||
return _gch;
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
assert(heap != NULL, "Uninitialized access to GenCollectedHeap::heap()");
|
||||
assert(heap->kind() == CollectedHeap::GenCollectedHeap, "Not a GenCollectedHeap");
|
||||
return (GenCollectedHeap*)heap;
|
||||
}
|
||||
|
||||
void GenCollectedHeap::prepare_for_compaction() {
|
||||
|
@ -54,11 +54,7 @@ class GenCollectedHeap : public CollectedHeap {
|
||||
public:
|
||||
friend class VM_PopulateDumpSharedSpace;
|
||||
|
||||
protected:
|
||||
// Fields:
|
||||
static GenCollectedHeap* _gch;
|
||||
|
||||
private:
|
||||
private:
|
||||
Generation* _young_gen;
|
||||
Generation* _old_gen;
|
||||
|
||||
|
@ -187,7 +187,6 @@ void GenMarkSweep::mark_sweep_phase1(int level,
|
||||
bool clear_all_softrefs) {
|
||||
// Recursively traverse all live objects and mark them
|
||||
GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace(" 1");
|
||||
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
|
||||
@ -258,7 +257,6 @@ void GenMarkSweep::mark_sweep_phase2() {
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
|
||||
GCTraceTime tm("phase 2", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("2");
|
||||
|
||||
gch->prepare_for_compaction();
|
||||
}
|
||||
@ -275,7 +273,6 @@ void GenMarkSweep::mark_sweep_phase3(int level) {
|
||||
|
||||
// Adjust the pointers to reflect the new locations
|
||||
GCTraceTime tm("phase 3", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("3");
|
||||
|
||||
// Need new claim bits for the pointer adjustment tracing.
|
||||
ClassLoaderDataGraph::clear_claimed_marks();
|
||||
@ -325,7 +322,6 @@ void GenMarkSweep::mark_sweep_phase4() {
|
||||
GenCollectedHeap* gch = GenCollectedHeap::heap();
|
||||
|
||||
GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
|
||||
trace("4");
|
||||
|
||||
GenCompactClosure blk;
|
||||
gch->generation_iterate(&blk, true);
|
||||
|
@ -687,6 +687,15 @@ jint universe_init() {
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
template <class Heap, class Policy>
|
||||
jint Universe::create_heap() {
|
||||
assert(_collectedHeap == NULL, "Heap already created");
|
||||
Policy* policy = new Policy();
|
||||
policy->initialize_all();
|
||||
_collectedHeap = new Heap(policy);
|
||||
return _collectedHeap->initialize();
|
||||
}
|
||||
|
||||
// Choose the heap base address and oop encoding mode
|
||||
// when compressed oops are used:
|
||||
// Unscaled - Use 32-bits oops without encoding when
|
||||
@ -696,50 +705,37 @@ jint universe_init() {
|
||||
// HeapBased - Use compressed oops with heap base + encoding.
|
||||
|
||||
jint Universe::initialize_heap() {
|
||||
jint status = JNI_ERR;
|
||||
|
||||
#if !INCLUDE_ALL_GCS
|
||||
if (UseParallelGC) {
|
||||
#if INCLUDE_ALL_GCS
|
||||
Universe::_collectedHeap = new ParallelScavengeHeap();
|
||||
#else // INCLUDE_ALL_GCS
|
||||
fatal("UseParallelGC not supported in this VM.");
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
} else if (UseG1GC) {
|
||||
#if INCLUDE_ALL_GCS
|
||||
G1CollectorPolicyExt* g1p = new G1CollectorPolicyExt();
|
||||
g1p->initialize_all();
|
||||
G1CollectedHeap* g1h = new G1CollectedHeap(g1p);
|
||||
Universe::_collectedHeap = g1h;
|
||||
#else // INCLUDE_ALL_GCS
|
||||
fatal("UseG1GC not supported in java kernel vm.");
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
} else {
|
||||
GenCollectorPolicy *gc_policy;
|
||||
|
||||
if (UseSerialGC) {
|
||||
gc_policy = new MarkSweepPolicy();
|
||||
fatal("UseG1GC not supported in this VM.");
|
||||
} else if (UseConcMarkSweepGC) {
|
||||
#if INCLUDE_ALL_GCS
|
||||
gc_policy = new ConcurrentMarkSweepPolicy();
|
||||
#else // INCLUDE_ALL_GCS
|
||||
fatal("UseConcMarkSweepGC not supported in this VM.");
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
} else { // default old generation
|
||||
gc_policy = new MarkSweepPolicy();
|
||||
}
|
||||
gc_policy->initialize_all();
|
||||
|
||||
Universe::_collectedHeap = new GenCollectedHeap(gc_policy);
|
||||
#else
|
||||
if (UseParallelGC) {
|
||||
status = Universe::create_heap<ParallelScavengeHeap, GenerationSizer>();
|
||||
} else if (UseG1GC) {
|
||||
status = Universe::create_heap<G1CollectedHeap, G1CollectorPolicyExt>();
|
||||
} else if (UseConcMarkSweepGC) {
|
||||
status = Universe::create_heap<GenCollectedHeap, ConcurrentMarkSweepPolicy>();
|
||||
}
|
||||
#endif
|
||||
else { // UseSerialGC
|
||||
// Don't assert that UseSerialGC is set here because there are cases
|
||||
// where no GC it set and we then fall back to using SerialGC.
|
||||
status = Universe::create_heap<GenCollectedHeap, MarkSweepPolicy>();
|
||||
}
|
||||
|
||||
ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
|
||||
|
||||
jint status = Universe::heap()->initialize();
|
||||
if (status != JNI_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
// Subtract a page because something can get allocated at heap base.
|
||||
@ -1063,7 +1059,7 @@ bool universe_post_init() {
|
||||
|
||||
MemoryService::add_metaspace_memory_pools();
|
||||
|
||||
MemoryService::set_universe_heap(Universe::_collectedHeap);
|
||||
MemoryService::set_universe_heap(Universe::heap());
|
||||
#if INCLUDE_CDS
|
||||
SharedClassUtil::initialize(CHECK_false);
|
||||
#endif
|
||||
|
@ -214,6 +214,7 @@ class Universe: AllStatic {
|
||||
static size_t _heap_capacity_at_last_gc;
|
||||
static size_t _heap_used_at_last_gc;
|
||||
|
||||
template <class Heap, class Policy> static jint create_heap();
|
||||
static jint initialize_heap();
|
||||
static void initialize_basic_type_mirrors(TRAPS);
|
||||
static void fixup_mirrors(TRAPS);
|
||||
|
@ -201,7 +201,6 @@ class oopDesc {
|
||||
|
||||
// Access to fields in a instanceOop through these methods.
|
||||
oop obj_field(int offset) const;
|
||||
volatile oop obj_field_volatile(int offset) const;
|
||||
void obj_field_put(int offset, oop value);
|
||||
void obj_field_put_raw(int offset, oop value);
|
||||
void obj_field_put_volatile(int offset, oop value);
|
||||
|
@ -284,11 +284,6 @@ inline oop oopDesc::obj_field(int offset) const {
|
||||
load_decode_heap_oop(obj_field_addr<narrowOop>(offset)) :
|
||||
load_decode_heap_oop(obj_field_addr<oop>(offset));
|
||||
}
|
||||
inline volatile oop oopDesc::obj_field_volatile(int offset) const {
|
||||
volatile oop value = obj_field(offset);
|
||||
OrderAccess::acquire();
|
||||
return value;
|
||||
}
|
||||
inline void oopDesc::obj_field_put(int offset, oop value) {
|
||||
UseCompressedOops ? oop_store(obj_field_addr<narrowOop>(offset), value) :
|
||||
oop_store(obj_field_addr<oop>(offset), value);
|
||||
|
@ -315,7 +315,7 @@
|
||||
# include "gc_implementation/parallelScavenge/psYoungGen.hpp"
|
||||
# include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
|
||||
# include "gc_implementation/shared/gcPolicyCounters.hpp"
|
||||
# include "gc_implementation/shared/parGCAllocBuffer.hpp"
|
||||
# include "gc_implementation/shared/plab.hpp"
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
||||
#endif // !DONT_USE_PRECOMPILED_HEADER
|
||||
|
@ -1960,7 +1960,7 @@ class CommandLineFlags {
|
||||
"collection") \
|
||||
\
|
||||
develop(uintx, PromotionFailureALotCount, 1000, \
|
||||
"Number of promotion failures occurring at ParGCAllocBuffer " \
|
||||
"Number of promotion failures occurring at PLAB " \
|
||||
"refill attempts (ParNew) or promotion attempts " \
|
||||
"(other young collectors)") \
|
||||
\
|
||||
@ -2290,9 +2290,6 @@ class CommandLineFlags {
|
||||
"If non-zero, assert that GC threads yield within this " \
|
||||
"number of milliseconds") \
|
||||
\
|
||||
notproduct(bool, TraceMarkSweep, false, \
|
||||
"Trace mark sweep") \
|
||||
\
|
||||
product(bool, PrintReferenceGC, false, \
|
||||
"Print times spent handling reference objects during GC " \
|
||||
"(enabled only when PrintGCDetails)") \
|
||||
|
@ -555,7 +555,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
|
||||
nonstatic_field(GenerationSpec, _init_size, size_t) \
|
||||
nonstatic_field(GenerationSpec, _max_size, size_t) \
|
||||
\
|
||||
static_field(GenCollectedHeap, _gch, GenCollectedHeap*) \
|
||||
nonstatic_field(GenCollectedHeap, _young_gen, Generation*) \
|
||||
nonstatic_field(GenCollectedHeap, _old_gen, Generation*) \
|
||||
\
|
||||
|
@ -344,6 +344,34 @@ PHONY_LIST += sanitytest
|
||||
|
||||
################################################################
|
||||
|
||||
# basicvmtest (make sure various basic java options work)
|
||||
|
||||
# Set up the directory in which the jvm directories live (client/, server/, etc.)
|
||||
ifeq ($(PLATFORM),windows)
|
||||
JVMS_DIR := $(PRODUCT_HOME)/bin
|
||||
else ifeq ($(PLATFORM),bsd)
|
||||
JVMS_DIR := $(PRODUCT_HOME)/lib
|
||||
else
|
||||
# The jvms live in the architecture directory (amd64, sparcv9,
|
||||
# etc.). By using a wildcard there's no need to figure out the exact
|
||||
# name of that directory.
|
||||
JVMS_DIR := $(PRODUCT_HOME)/lib/*
|
||||
endif
|
||||
|
||||
# Use the existance of a directory as a sign that jvm variant is available
|
||||
CANDIDATE_JVM_VARIANTS := client minimal server
|
||||
JVM_VARIANTS := $(strip $(foreach x,$(CANDIDATE_JVM_VARIANTS),$(if $(wildcard $(JVMS_DIR)/$(x)),$(x))))
|
||||
|
||||
hotspot_basicvmtest:
|
||||
for variant in $(JVM_VARIANTS); \
|
||||
do \
|
||||
$(MAKE) JAVA_ARGS="$(JAVA_ARGS) -$$variant" hotspot_$${variant}test; \
|
||||
done
|
||||
|
||||
PHONY_LIST += hotspot_basicvmtest
|
||||
|
||||
################################################################
|
||||
|
||||
# clienttest (make sure various basic java client options work)
|
||||
|
||||
hotspot_clienttest clienttest: sanitytest
|
||||
|
Loading…
x
Reference in New Issue
Block a user