This commit is contained in:
Jesper Wilhelmsson 2015-04-20 14:26:54 +02:00
commit f2ac065c42
36 changed files with 220 additions and 439 deletions

View File

@ -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);
}
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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();

View File

@ -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));

View File

@ -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,

View File

@ -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 = &copy_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);
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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.") \
\

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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,

View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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, \

View File

@ -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);

View File

@ -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;

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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)") \

View File

@ -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*) \
\

View File

@ -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