--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Mon Apr 27 14:41:49 2015 +0200
@@ -259,8 +259,7 @@
saProps = new Properties();
URL url = null;
try {
- url = VM.class.getClassLoader().getResource("sa.properties");
- saProps.load(new BufferedInputStream(url.openStream()));
+ saProps.load(VM.class.getResourceAsStream("/sa.properties"));
} catch (Exception e) {
System.err.println("Unable to load properties " +
(url == null ? "null" : url.toString()) +
--- a/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/cpu/sparc/vm/macroAssembler_sparc.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -3695,23 +3695,11 @@
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);
- }
}
}
}
@@ -3904,12 +3892,6 @@
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);
- }
}
}
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -1181,8 +1181,6 @@
// 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
--- a/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.inline.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -943,13 +943,6 @@
_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 @@
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.
@@ -2960,9 +2793,7 @@
#ifndef PRODUCT
enum VerifyNoCSetOopsPhase {
VerifyNoCSetOopsStack,
- VerifyNoCSetOopsQueues,
- VerifyNoCSetOopsSATBCompleted,
- VerifyNoCSetOopsSATBThread
+ VerifyNoCSetOopsQueues
};
class VerifyNoCSetOopsClosure : public OopClosure, public ObjectClosure {
@@ -2975,8 +2806,6 @@
switch (_phase) {
case VerifyNoCSetOopsStack: return "Stack";
case VerifyNoCSetOopsQueues: return "Queue";
- case VerifyNoCSetOopsSATBCompleted: return "Completed SATB Buffers";
- case VerifyNoCSetOopsSATBThread: return "Thread SATB Buffers";
default: ShouldNotReachHere();
}
return NULL;
@@ -3003,7 +2832,7 @@
virtual void do_oop(narrowOop* p) {
// We should not come across narrow oops while scanning marking
- // stacks and SATB buffers.
+ // stacks
ShouldNotReachHere();
}
@@ -3012,10 +2841,7 @@
}
};
-void ConcurrentMark::verify_no_cset_oops(bool verify_stacks,
- bool verify_enqueued_buffers,
- bool verify_thread_buffers,
- bool verify_fingers) {
+void ConcurrentMark::verify_no_cset_oops() {
assert(SafepointSynchronize::is_at_safepoint(), "should be at a safepoint");
if (!G1CollectedHeap::heap()->mark_in_progress()) {
return;
@@ -3023,65 +2849,47 @@
VerifyNoCSetOopsClosure cl;
- if (verify_stacks) {
- // Verify entries on the global mark stack
- cl.set_phase(VerifyNoCSetOopsStack);
- _markStack.oops_do(&cl);
-
- // Verify entries on the task queues
- for (uint i = 0; i < _max_worker_id; i += 1) {
- cl.set_phase(VerifyNoCSetOopsQueues, i);
- CMTaskQueue* queue = _task_queues->queue(i);
- queue->oops_do(&cl);
- }
- }
-
- SATBMarkQueueSet& satb_qs = JavaThread::satb_mark_queue_set();
-
- // Verify entries on the enqueued SATB buffers
- if (verify_enqueued_buffers) {
- cl.set_phase(VerifyNoCSetOopsSATBCompleted);
- satb_qs.iterate_completed_buffers_read_only(&cl);
- }
-
- // Verify entries on the per-thread SATB buffers
- if (verify_thread_buffers) {
- cl.set_phase(VerifyNoCSetOopsSATBThread);
- satb_qs.iterate_thread_buffers_read_only(&cl);
+ // Verify entries on the global mark stack
+ cl.set_phase(VerifyNoCSetOopsStack);
+ _markStack.oops_do(&cl);
+
+ // Verify entries on the task queues
+ for (uint i = 0; i < _max_worker_id; i += 1) {
+ cl.set_phase(VerifyNoCSetOopsQueues, i);
+ CMTaskQueue* queue = _task_queues->queue(i);
+ queue->oops_do(&cl);
}
- if (verify_fingers) {
- // Verify the global finger
- HeapWord* global_finger = finger();
- if (global_finger != NULL && global_finger < _heap_end) {
- // The global finger always points to a heap region boundary. We
- // use heap_region_containing_raw() to get the containing region
- // given that the global finger could be pointing to a free region
- // which subsequently becomes continues humongous. If that
- // happens, heap_region_containing() will return the bottom of the
- // corresponding starts humongous region and the check below will
- // not hold any more.
- // Since we always iterate over all regions, we might get a NULL HeapRegion
- // here.
- HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
- guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
- err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
- p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
- }
-
- // Verify the task fingers
- assert(parallel_marking_threads() <= _max_worker_id, "sanity");
- for (int i = 0; i < (int) parallel_marking_threads(); i += 1) {
- CMTask* task = _tasks[i];
- HeapWord* task_finger = task->finger();
- if (task_finger != NULL && task_finger < _heap_end) {
- // See above note on the global finger verification.
- HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
- guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
- !task_hr->in_collection_set(),
- err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
- p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
- }
+ // Verify the global finger
+ HeapWord* global_finger = finger();
+ if (global_finger != NULL && global_finger < _heap_end) {
+ // The global finger always points to a heap region boundary. We
+ // use heap_region_containing_raw() to get the containing region
+ // given that the global finger could be pointing to a free region
+ // which subsequently becomes continues humongous. If that
+ // happens, heap_region_containing() will return the bottom of the
+ // corresponding starts humongous region and the check below will
+ // not hold any more.
+ // Since we always iterate over all regions, we might get a NULL HeapRegion
+ // here.
+ HeapRegion* global_hr = _g1h->heap_region_containing_raw(global_finger);
+ guarantee(global_hr == NULL || global_finger == global_hr->bottom(),
+ err_msg("global finger: "PTR_FORMAT" region: "HR_FORMAT,
+ p2i(global_finger), HR_FORMAT_PARAMS(global_hr)));
+ }
+
+ // Verify the task fingers
+ assert(parallel_marking_threads() <= _max_worker_id, "sanity");
+ for (int i = 0; i < (int) parallel_marking_threads(); i += 1) {
+ CMTask* task = _tasks[i];
+ HeapWord* task_finger = task->finger();
+ if (task_finger != NULL && task_finger < _heap_end) {
+ // See above note on the global finger verification.
+ HeapRegion* task_hr = _g1h->heap_region_containing_raw(task_finger);
+ guarantee(task_hr == NULL || task_finger == task_hr->bottom() ||
+ !task_hr->in_collection_set(),
+ err_msg("task finger: "PTR_FORMAT" region: "HR_FORMAT,
+ p2i(task_finger), HR_FORMAT_PARAMS(task_hr)));
}
}
}
@@ -3887,12 +3695,11 @@
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 +3713,6 @@
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();
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -785,14 +785,9 @@
}
// Verify that there are no CSet oops on the stacks (taskqueues /
- // global mark stack), enqueued SATB buffers, per-thread SATB
- // buffers, and fingers (global / per-task). The boolean parameters
- // decide which of the above data structures to verify. If marking
- // is not in progress, it's a no-op.
- void verify_no_cset_oops(bool verify_stacks,
- bool verify_enqueued_buffers,
- bool verify_thread_buffers,
- bool verify_fingers) PRODUCT_RETURN;
+ // global mark stack) and fingers (global / per-task).
+ // If marking is not in progress, it's a no-op.
+ void verify_no_cset_oops() PRODUCT_RETURN;
bool isPrevMarked(oop p) const {
assert(p != NULL && p->is_oop(), "expected an oop");
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -110,15 +110,15 @@
_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 @@
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));
--- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
}
};
-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,12 @@
if (_retired) {
return;
}
- ParGCAllocBuffer::retire();
+ PLAB::retire();
+ _retired = true;
+ }
+
+ virtual void flush_and_retire_stats(PLABStats* stats) {
+ PLAB::flush_and_retire_stats(stats);
_retired = true;
}
};
@@ -190,7 +195,7 @@
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.
@@ -211,6 +216,7 @@
_g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()),
_alloc_buffer_waste(0), _undo_waste(0) {
}
+ virtual ~G1ParGCAllocator() { }
static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h);
@@ -229,7 +235,7 @@
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 +265,14 @@
};
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,
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -22,11 +22,6 @@
*
*/
-#if !defined(__clang_major__) && defined(__GNUC__)
-// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information.
-#define ATTRIBUTE_PRINTF(x,y)
-#endif
-
#include "precompiled.hpp"
#include "classfile/metadataOnStackMark.hpp"
#include "classfile/stringTable.hpp"
@@ -201,7 +196,7 @@
if (!curr->is_young()) {
gclog_or_tty->print_cr("### YOUNG REGION "PTR_FORMAT"-"PTR_FORMAT" "
"incorrectly tagged (y: %d, surv: %d)",
- curr->bottom(), curr->end(),
+ p2i(curr->bottom()), p2i(curr->end()),
curr->is_young(), curr->is_survivor());
ret = false;
}
@@ -330,8 +325,8 @@
while (curr != NULL) {
gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT ", N: "PTR_FORMAT", age: %4d",
HR_FORMAT_PARAMS(curr),
- curr->prev_top_at_mark_start(),
- curr->next_top_at_mark_start(),
+ p2i(curr->prev_top_at_mark_start()),
+ p2i(curr->next_top_at_mark_start()),
curr->age_in_surv_rate_group_cond());
curr = curr->get_next_young_region();
}
@@ -410,10 +405,6 @@
return !hr->is_humongous();
}
-// Private class members.
-
-G1CollectedHeap* G1CollectedHeap::_g1h;
-
// Private methods.
HeapRegion*
@@ -1769,14 +1760,12 @@
_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 +1928,6 @@
_bot_shared = new G1BlockOffsetSharedArray(reserved_region(), bot_storage);
- _g1h = this;
-
{
HeapWord* start = _hrm.reserved().start();
HeapWord* end = _hrm.reserved().end();
@@ -2760,9 +2747,9 @@
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (_g1h->is_obj_dead_cond(obj, _vo)) {
gclog_or_tty->print_cr("Root location "PTR_FORMAT" "
- "points to dead obj "PTR_FORMAT, p, (void*) obj);
+ "points to dead obj "PTR_FORMAT, p2i(p), p2i(obj));
if (_vo == VerifyOption_G1UseMarkWord) {
- gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark()));
+ gclog_or_tty->print_cr(" Mark word: "INTPTR_FORMAT, (intptr_t)obj->mark());
}
obj->print_on(gclog_or_tty);
_failures = true;
@@ -2810,9 +2797,9 @@
// contains the nmethod
if (!hrrs->strong_code_roots_list_contains(_nm)) {
gclog_or_tty->print_cr("Code root location "PTR_FORMAT" "
- "from nmethod "PTR_FORMAT" not in strong "
- "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
- p, _nm, hr->bottom(), hr->end());
+ "from nmethod "PTR_FORMAT" not in strong "
+ "code roots for region ["PTR_FORMAT","PTR_FORMAT")",
+ p2i(p), p2i(_nm), p2i(hr->bottom()), p2i(hr->end()));
_failures = true;
}
}
@@ -2868,7 +2855,7 @@
_young_ref_counter_closure.reset_count();
k->oops_do(&_young_ref_counter_closure);
if (_young_ref_counter_closure.count() > 0) {
- guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", k));
+ guarantee(k->has_modified_oops(), err_msg("Klass " PTR_FORMAT ", has young refs but is not dirty.", p2i(k)));
}
}
};
@@ -2929,35 +2916,6 @@
size_t live_bytes() { return _live_bytes; }
};
-class PrintObjsInRegionClosure : public ObjectClosure {
- HeapRegion *_hr;
- G1CollectedHeap *_g1;
-public:
- PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) {
- _g1 = G1CollectedHeap::heap();
- };
-
- void do_object(oop o) {
- if (o != NULL) {
- HeapWord *start = (HeapWord *) o;
- size_t word_sz = o->size();
- gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT
- " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n",
- (void*) o, word_sz,
- _g1->isMarkedPrev(o),
- _g1->isMarkedNext(o),
- _hr->obj_allocated_since_prev_marking(o));
- HeapWord *end = start + word_sz;
- HeapWord *cur;
- int *val;
- for (cur = start; cur < end; cur++) {
- val = (int *) cur;
- gclog_or_tty->print("\t "PTR_FORMAT":%d\n", val, *val);
- }
- }
- }
-};
-
class VerifyRegionClosure: public HeapRegionClosure {
private:
bool _par;
@@ -2990,7 +2948,7 @@
gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] "
"max_live_bytes "SIZE_FORMAT" "
"< calculated "SIZE_FORMAT,
- r->bottom(), r->end(),
+ p2i(r->bottom()), p2i(r->end()),
r->max_live_bytes(),
not_dead_yet_cl.live_bytes());
_failures = true;
@@ -3109,12 +3067,6 @@
// 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");
@@ -3194,10 +3146,10 @@
st->print(" %-20s", "garbage-first heap");
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity()/K, used_unlocked()/K);
- st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
- _hrm.reserved().start(),
- _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
- _hrm.reserved().end());
+ st->print(" [" PTR_FORMAT ", " PTR_FORMAT ", " PTR_FORMAT ")",
+ p2i(_hrm.reserved().start()),
+ p2i(_hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords),
+ p2i(_hrm.reserved().end()));
st->cr();
st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
uint young_regions = _young_list->length();
@@ -3320,9 +3272,10 @@
#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 */) {
@@ -3853,14 +3806,9 @@
assert(check_cset_fast_test(), "Inconsistency in the InCSetState table.");
_cm->note_start_of_gc();
- // We should not verify the per-thread SATB buffers given that
- // we have not filtered them yet (we'll do so during the
- // GC). We also call this after finalize_cset() to
+ // We call this after finalize_cset() to
// ensure that the CSet has been finalized.
- _cm->verify_no_cset_oops(true /* verify_stacks */,
- true /* verify_enqueued_buffers */,
- false /* verify_thread_buffers */,
- true /* verify_fingers */);
+ _cm->verify_no_cset_oops();
if (_hr_printer.is_active()) {
HeapRegion* hr = g1_policy()->collection_set();
@@ -3883,16 +3831,6 @@
// Actually do the work...
evacuate_collection_set(evacuation_info);
- // We do this to mainly verify the per-thread SATB buffers
- // (which have been filtered by now) since we didn't verify
- // them earlier. No point in re-checking the stacks / enqueued
- // buffers given that the CSet has not changed since last time
- // we checked.
- _cm->verify_no_cset_oops(false /* verify_stacks */,
- false /* verify_enqueued_buffers */,
- true /* verify_thread_buffers */,
- true /* verify_fingers */);
-
free_collection_set(g1_policy()->collection_set(), evacuation_info);
eagerly_reclaim_humongous_regions();
@@ -3975,10 +3913,7 @@
// We redo the verification but now wrt to the new CSet which
// has just got initialized after the previous CSet was freed.
- _cm->verify_no_cset_oops(true /* verify_stacks */,
- true /* verify_enqueued_buffers */,
- true /* verify_thread_buffers */,
- true /* verify_fingers */);
+ _cm->verify_no_cset_oops();
_cm->note_end_of_gc();
// This timing is only used by the ergonomics to handle our pause target.
@@ -4137,7 +4072,7 @@
oop old) {
assert(obj_in_cs(old),
err_msg("obj: "PTR_FORMAT" should still be in the CSet",
- (HeapWord*) old));
+ p2i(old)));
markOop m = old->mark();
oop forward_ptr = old->forward_to_atomic(old);
if (forward_ptr == NULL) {
@@ -4172,7 +4107,7 @@
assert(old == forward_ptr || !obj_in_cs(forward_ptr),
err_msg("obj: "PTR_FORMAT" forwarded to: "PTR_FORMAT" "
"should not be in the CSet",
- (HeapWord*) old, (HeapWord*) forward_ptr));
+ p2i(old), p2i(forward_ptr)));
return forward_ptr;
}
}
@@ -4877,7 +4812,7 @@
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 +4844,7 @@
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();
@@ -5022,8 +4957,7 @@
_par_scan_state->push_on_queue(p);
} else {
assert(!Metaspace::contains((const void*)p),
- err_msg("Unexpectedly found a pointer from metadata: "
- PTR_FORMAT, p));
+ err_msg("Unexpectedly found a pointer from metadata: " PTR_FORMAT, p2i(p)));
_copy_non_heap_obj_cl->do_oop(p);
}
}
@@ -5342,7 +5276,7 @@
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;
}
@@ -5688,14 +5622,14 @@
bool G1CollectedHeap::verify_no_bits_over_tams(const char* bitmap_name, CMBitMapRO* bitmap,
HeapWord* tams, HeapWord* end) {
guarantee(tams <= end,
- err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, tams, end));
+ err_msg("tams: "PTR_FORMAT" end: "PTR_FORMAT, p2i(tams), p2i(end)));
HeapWord* result = bitmap->getNextMarkedWordAddress(tams, end);
if (result < end) {
gclog_or_tty->cr();
gclog_or_tty->print_cr("## wrong marked address on %s bitmap: "PTR_FORMAT,
- bitmap_name, result);
+ bitmap_name, p2i(result));
gclog_or_tty->print_cr("## %s tams: "PTR_FORMAT" end: "PTR_FORMAT,
- bitmap_name, tams, end);
+ bitmap_name, p2i(tams), p2i(end));
return false;
}
return true;
@@ -6019,10 +5953,10 @@
!r->rem_set()->is_empty()) {
if (G1TraceEagerReclaimHumongousObjects) {
- gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
+ gclog_or_tty->print_cr("Live humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
region_idx,
- obj->size()*HeapWordSize,
- r->bottom(),
+ (size_t)obj->size() * HeapWordSize,
+ p2i(r->bottom()),
r->region_num(),
r->rem_set()->occupied(),
r->rem_set()->strong_code_roots_list_length(),
@@ -6038,13 +5972,13 @@
guarantee(obj->is_typeArray(),
err_msg("Only eagerly reclaiming type arrays is supported, but the object "
PTR_FORMAT " is not.",
- r->bottom()));
+ p2i(r->bottom())));
if (G1TraceEagerReclaimHumongousObjects) {
- gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length "UINT32_FORMAT" with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
+ gclog_or_tty->print_cr("Dead humongous region %u size "SIZE_FORMAT" start "PTR_FORMAT" length %u with remset "SIZE_FORMAT" code roots "SIZE_FORMAT" is marked %d reclaim candidate %d type array %d",
region_idx,
- obj->size()*HeapWordSize,
- r->bottom(),
+ (size_t)obj->size() * HeapWordSize,
+ p2i(r->bottom()),
r->region_num(),
r->rem_set()->occupied(),
r->rem_set()->strong_code_roots_list_length(),
@@ -6097,12 +6031,12 @@
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);
}
}
@@ -6196,7 +6130,7 @@
bool doHeapRegion(HeapRegion* r) {
if (r->is_young()) {
gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young",
- r->bottom(), r->end());
+ p2i(r->bottom()), p2i(r->end()));
_success = false;
}
return false;
@@ -6546,7 +6480,7 @@
assert(!hr->is_continues_humongous(),
err_msg("trying to add code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
" starting at "HR_FORMAT,
- _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+ p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
// HeapRegion::add_strong_code_root_locked() avoids adding duplicate entries.
hr->add_strong_code_root_locked(_nm);
@@ -6573,7 +6507,7 @@
assert(!hr->is_continues_humongous(),
err_msg("trying to remove code root "PTR_FORMAT" in continuation of humongous region "HR_FORMAT
" starting at "HR_FORMAT,
- _nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
+ p2i(_nm), HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region())));
hr->remove_strong_code_root(_nm);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
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;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -22,11 +22,6 @@
*
*/
-#ifndef __clang_major__
-// FIXME, formats have issues. Disable this macro definition, compile, and study warnings for more information.
-#define ATTRIBUTE_PRINTF(x,y)
-#endif
-
#include "precompiled.hpp"
#include "gc_implementation/g1/concurrentG1Refine.hpp"
#include "gc_implementation/g1/concurrentMark.hpp"
@@ -302,7 +297,7 @@
if (reserve_perc > 50) {
reserve_perc = 50;
warning("G1ReservePercent is set to a value that is too large, "
- "it's been updated to %u", reserve_perc);
+ "it's been updated to " UINTX_FORMAT, reserve_perc);
}
_reserve_factor = (double) reserve_perc / 100.0;
// This will be set when the heap is expanded
@@ -1800,7 +1795,7 @@
assert(csr->in_collection_set(), "bad CS");
st->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
HR_FORMAT_PARAMS(csr),
- csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(),
+ p2i(csr->prev_top_at_mark_start()), p2i(csr->next_top_at_mark_start()),
csr->age_in_surv_rate_group_cond());
csr = next;
}
@@ -2166,7 +2161,7 @@
void TraceYoungGenTimeData::print_summary_sd(const char* str,
const NumberSeq* seq) const {
print_summary(str, seq);
- gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+ gclog_or_tty->print_cr("%45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
"(num", seq->num(), seq->sd(), seq->maximum());
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -160,40 +160,43 @@
} while (0)
-#define ergo_verbose(_tag_, _action_) \
- ergo_verbose_common(_tag_, _action_, "", 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose0(_tag_, _action_, _extra_format_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, 0, 0, 0, 0, 0, 0)
-
-#define ergo_verbose1(_tag_, _action_, _extra_format_, \
- _arg0_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, \
- _arg0_, 0, 0, 0, 0, 0)
-
-#define ergo_verbose2(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, 0, 0, 0, 0)
-
-#define ergo_verbose3(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_, 0, 0, 0)
-
-#define ergo_verbose4(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_, _arg3_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_, _arg3_, 0, 0)
-
-#define ergo_verbose5(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_, _arg3_, _arg4_) \
- ergo_verbose_common(_tag_, _action_, _extra_format_, \
- _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, 0)
-
#define ergo_verbose6(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_) \
ergo_verbose_common(_tag_, _action_, _extra_format_, \
_arg0_, _arg1_, _arg2_, _arg3_, _arg4_, _arg5_)
+#define ergo_verbose5(_tag_, _action_, _extra_format_, \
+ _arg0_, _arg1_, _arg2_, _arg3_, _arg4_) \
+ ergo_verbose6(_tag_, _action_, _extra_format_ "%s", \
+ _arg0_, _arg1_, _arg2_, _arg3_, _arg4_, "")
+
+#define ergo_verbose4(_tag_, _action_, _extra_format_, \
+ _arg0_, _arg1_, _arg2_, _arg3_) \
+ ergo_verbose5(_tag_, _action_, _extra_format_ "%s", \
+ _arg0_, _arg1_, _arg2_, _arg3_, "")
+
+#define ergo_verbose3(_tag_, _action_, _extra_format_, \
+ _arg0_, _arg1_, _arg2_) \
+ ergo_verbose4(_tag_, _action_, _extra_format_ "%s", \
+ _arg0_, _arg1_, _arg2_, "")
+
+#define ergo_verbose2(_tag_, _action_, _extra_format_, \
+ _arg0_, _arg1_) \
+ ergo_verbose3(_tag_, _action_, _extra_format_ "%s", \
+ _arg0_, _arg1_, "")
+
+#define ergo_verbose1(_tag_, _action_, _extra_format_, \
+ _arg0_) \
+ ergo_verbose2(_tag_, _action_, _extra_format_ "%s", \
+ _arg0_, "")
+
+
+#define ergo_verbose0(_tag_, _action_, _extra_format_) \
+ ergo_verbose1(_tag_, _action_, _extra_format_ "%s", \
+ "")
+
+#define ergo_verbose(_tag_, _action_) \
+ ergo_verbose0(_tag_, _action_, "")
+
+
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1ERGOVERBOSE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -119,7 +119,6 @@
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 @@
// 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 @@
// 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 @@
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);
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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.") \
\
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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;
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -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.
+//
+// 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.
+//
+// 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.
//
-// * 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).
+// * A stale reference to an eagerly reclaimed humongous object. If a
+// humongous object is recorded and then reclaimed, the reference
+// becomes stale.
//
-// 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.
+// 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 @@
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;)
}
}
@@ -144,12 +180,6 @@
return should_enqueue;
}
-void ObjPtrQueue::apply_closure(ObjectClosure* cl) {
- if (_buf != NULL) {
- apply_closure_to_buffer(cl, _buf, _index, _sz);
- }
-}
-
void ObjPtrQueue::apply_closure_and_empty(ObjectClosure* cl) {
if (_buf != NULL) {
apply_closure_to_buffer(cl, _buf, _index, _sz);
@@ -184,23 +214,12 @@
}
#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 +227,9 @@
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 +289,7 @@
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 +301,6 @@
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);
@@ -301,28 +311,6 @@
}
}
-void SATBMarkQueueSet::iterate_completed_buffers_read_only(ObjectClosure* cl) {
- assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
- assert(cl != NULL, "pre-condition");
-
- BufferNode* nd = _completed_buffers_head;
- while (nd != NULL) {
- void** buf = BufferNode::make_buffer_from_node(nd);
- ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
- nd = nd->next();
- }
-}
-
-void SATBMarkQueueSet::iterate_thread_buffers_read_only(ObjectClosure* cl) {
- assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
- assert(cl != NULL, "pre-condition");
-
- for (JavaThread* t = Threads::first(); t; t = t->next()) {
- t->satb_mark_queue().apply_closure(cl);
- }
- shared_satb_queue()->apply_closure(cl);
-}
-
#ifndef PRODUCT
// Helpful for debugging
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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
@@ -41,9 +41,6 @@
// Filter out unwanted entries from the buffer.
void filter();
- // Apply the closure to all elements.
- void apply_closure(ObjectClosure* cl);
-
// Apply the closure to all elements and empty the buffer;
void apply_closure_and_empty(ObjectClosure* cl);
@@ -72,13 +69,9 @@
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,22 +97,10 @@
// 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);
-
- // Apply the given closure on enqueued and currently-active buffers
- // respectively. Both methods are read-only, i.e., they do not
- // modify any of the buffers.
- void iterate_completed_buffers_read_only(ObjectClosure* cl);
- void iterate_thread_buffers_read_only(ObjectClosure* cl);
+ bool apply_closure_to_completed_buffer(ObjectClosure* closure);
#ifndef PRODUCT
// Helpful for debugging
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
// 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* 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 @@
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
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
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 @@
ObjToScanQueue* work_queue() { return _work_queue; }
- ParGCAllocBuffer* to_space_alloc_buffer() {
+ PLAB* to_space_alloc_buffer() {
return &_to_space_alloc_buffer;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -49,30 +49,19 @@
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());
- MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
os::trace_page_sizes("ps main", _collector_policy->min_heap_byte_size(),
heap_size, generation_alignment(),
heap_rs.base(),
heap_rs.size());
- if (!heap_rs.is_reserved()) {
- vm_shutdown_during_initialization(
- "Could not reserve enough space for object heap");
- return JNI_ENOMEM;
- }
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
@@ -89,7 +78,6 @@
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 +622,10 @@
}
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,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -53,8 +53,6 @@
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 @@
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 {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -510,7 +510,6 @@
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_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 @@
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_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
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
// 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 @@
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;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -26,7 +26,6 @@
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.hpp"
-#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
#include "gc_implementation/parallelScavenge/vmPSOperations.hpp"
#include "memory/gcLocker.inline.hpp"
#include "utilities/dtrace.hpp"
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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, \
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -338,15 +338,6 @@
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);
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -131,9 +131,6 @@
// Non public closures
static KeepAliveClosure keep_alive;
- // Debugging
- static void trace(const char* msg) PRODUCT_RETURN;
-
public:
// Public closures
static IsAliveClosure is_alive;
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#include "memory/threadLocalAllocBuffer.hpp"
-#include "oops/arrayOop.hpp"
-#include "oops/oop.inline.hpp"
-
-size_t ParGCAllocBuffer::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() {
- return ThreadLocalAllocBuffer::max_size();
-}
-
-ParGCAllocBuffer::ParGCAllocBuffer(size_t desired_plab_sz_) :
- _word_sz(desired_plab_sz_), _bottom(NULL), _top(NULL),
- _end(NULL), _hard_end(NULL), _allocated(0), _wasted(0)
-{
- // ArrayOopDesc::header_size depends on command line initialization.
- AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
- assert(min_size() > AlignmentReserve,
- err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
- "to be able to contain objects", min_size(), AlignmentReserve));
-}
-
-// If the minimum object size is greater than MinObjAlignment, we can
-// end up with a shard at the end of the buffer that's smaller than
-// 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;
-
-void ParGCAllocBuffer::flush_and_retire_stats(PLABStats* stats) {
- // Retire the last allocation buffer.
- size_t unused = retire_internal();
-
- // Now flush the statistics.
- stats->add_allocated(_allocated);
- stats->add_wasted(_wasted);
- stats->add_unused(unused);
-
- // Since we have flushed the stats we need to clear the _allocated and _wasted
- // fields in case somebody retains an instance of this over GCs. Not doing so
- // will artifically inflate the values in the statistics.
- _allocated = 0;
- _wasted = 0;
-}
-
-void ParGCAllocBuffer::retire() {
- _wasted += retire_internal();
-}
-
-size_t ParGCAllocBuffer::retire_internal() {
- size_t result = 0;
- if (_top < _hard_end) {
- CollectedHeap::fill_with_object(_top, _hard_end);
- result += invalidate();
- }
- return result;
-}
-
-// Compute desired plab size and latch result for later
-// use. This should be called once at the end of parallel
-// scavenge; it clears the sensor accumulators.
-void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
- assert(ResizePLAB, "Not set");
-
- assert(is_object_aligned(max_size()) && min_size() <= max_size(),
- "PLAB clipping computation may be incorrect");
-
- if (_allocated == 0) {
- assert(_unused == 0,
- err_msg("Inconsistency in PLAB stats: "
- "_allocated: "SIZE_FORMAT", "
- "_wasted: "SIZE_FORMAT", "
- "_unused: "SIZE_FORMAT,
- _allocated, _wasted, _unused));
-
- _allocated = 1;
- }
- double wasted_frac = (double)_unused / (double)_allocated;
- size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
- if (target_refills == 0) {
- target_refills = 1;
- }
- size_t used = _allocated - _wasted - _unused;
- size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
- // Take historical weighted average
- _filter.sample(recent_plab_sz);
- // Clip from above and below, and align to object boundary
- size_t new_plab_sz = MAX2(min_size(), (size_t)_filter.average());
- new_plab_sz = MIN2(max_size(), new_plab_sz);
- new_plab_sz = align_object_size(new_plab_sz);
- // Latch the result
- if (PrintPLAB) {
- gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
- }
- _desired_plab_sz = new_plab_sz;
-
- reset();
-}
-
-#ifndef PRODUCT
-void ParGCAllocBuffer::print() {
- gclog_or_tty->print_cr("parGCAllocBuffer: _bottom: " PTR_FORMAT " _top: " PTR_FORMAT
- " _end: " PTR_FORMAT " _hard_end: " PTR_FORMAT ")",
- p2i(_bottom), p2i(_top), p2i(_end), p2i(_hard_end));
-}
-#endif // !PRODUCT
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
-
-#include "gc_implementation/shared/gcUtil.hpp"
-#include "memory/allocation.hpp"
-#include "runtime/atomic.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-// Forward declarations.
-class PLABStats;
-
-// A per-thread allocation buffer used during GC.
-class ParGCAllocBuffer: public CHeapObj<mtGC> {
-protected:
- char head[32];
- size_t _word_sz; // In HeapWord units
- HeapWord* _bottom;
- HeapWord* _top;
- HeapWord* _end; // Last allocatable address + 1
- HeapWord* _hard_end; // _end + AlignmentReserve
- // In support of ergonomic sizing of PLAB's
- size_t _allocated; // in HeapWord units
- size_t _wasted; // in HeapWord units
- char tail[32];
- static size_t AlignmentReserve;
-
- // Force future allocations to fail and queries for contains()
- // to return false. Returns the amount of unused space in this PLAB.
- size_t invalidate() {
- _end = _hard_end;
- size_t remaining = pointer_delta(_end, _top); // Calculate remaining space.
- _top = _end; // Force future allocations to fail.
- _bottom = _end; // Force future contains() queries to return false.
- return remaining;
- }
-
- // Fill in remaining space with a dummy object and invalidate the PLAB. Returns
- // the amount of remaining space.
- size_t retire_internal();
-
-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() {}
-
- // Minimum PLAB size.
- static size_t min_size();
- // Maximum PLAB size.
- static size_t max_size();
-
- // If an allocation of the given "word_sz" can be satisfied within the
- // buffer, do the allocation, returning a pointer to the start of the
- // allocated block. If the allocation request cannot be satisfied,
- // return NULL.
- HeapWord* allocate(size_t word_sz) {
- HeapWord* res = _top;
- if (pointer_delta(_end, _top) >= word_sz) {
- _top = _top + word_sz;
- return res;
- } else {
- return NULL;
- }
- }
-
- // Allocate the object aligned to "alignment_in_bytes".
- HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
-
- // Undo the last allocation in the buffer, which is required to be of the
- // "obj" of the given "word_sz".
- void undo_allocation(HeapWord* obj, size_t word_sz) {
- assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo");
- assert(pointer_delta(_top, obj) == word_sz, "Bad undo");
- _top = obj;
- }
-
- // The total (word) size of the buffer, including both allocated and
- // unallocated space.
- size_t word_sz() { return _word_sz; }
-
- // Should only be done if we are about to reset with a new buffer of the
- // given size.
- void set_word_size(size_t new_word_sz) {
- assert(new_word_sz > AlignmentReserve, "Too small");
- _word_sz = new_word_sz;
- }
-
- // The number of words of unallocated space remaining in the buffer.
- size_t words_remaining() {
- assert(_end >= _top, "Negative buffer");
- return pointer_delta(_end, _top, HeapWordSize);
- }
-
- bool contains(void* addr) {
- return (void*)_bottom <= addr && addr < (void*)_hard_end;
- }
-
- // Sets the space of the buffer to be [buf, space+word_sz()).
- virtual void set_buf(HeapWord* buf) {
- _bottom = buf;
- _top = _bottom;
- _hard_end = _bottom + word_sz();
- _end = _hard_end - AlignmentReserve;
- assert(_end >= _top, "Negative buffer");
- // In support of ergonomic sizing
- _allocated += word_sz();
- }
-
- // Flush allocation statistics into the given PLABStats supporting ergonomic
- // sizing of PLAB's and retire the current buffer. To be called at the end of
- // GC.
- void flush_and_retire_stats(PLABStats* stats);
-
- // Fills in the unallocated portion of the buffer with a garbage object and updates
- // statistics. To be called during GC.
- virtual void retire();
-
- void print() PRODUCT_RETURN;
-};
-
-// PLAB book-keeping.
-class PLABStats VALUE_OBJ_CLASS_SPEC {
- size_t _allocated; // Total allocated
- size_t _wasted; // of which wasted (internal fragmentation)
- size_t _unused; // Unused in last buffer
- size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
- AdaptiveWeightedAverage
- _filter; // Integrator with decay
-
- void reset() {
- _allocated = 0;
- _wasted = 0;
- _unused = 0;
- }
- public:
- PLABStats(size_t desired_plab_sz_, unsigned wt) :
- _allocated(0),
- _wasted(0),
- _unused(0),
- _desired_plab_sz(desired_plab_sz_),
- _filter(wt)
- { }
-
- static const size_t min_size() {
- return ParGCAllocBuffer::min_size();
- }
-
- static const size_t max_size() {
- return ParGCAllocBuffer::max_size();
- }
-
- size_t desired_plab_sz() {
- return _desired_plab_sz;
- }
-
- // Updates the current desired PLAB size. Computes the new desired PLAB size,
- // updates _desired_plab_sz and clears sensor accumulators.
- void adjust_desired_plab_sz(uint no_of_gc_workers);
-
- void add_allocated(size_t v) {
- Atomic::add_ptr(v, &_allocated);
- }
-
- void add_unused(size_t v) {
- Atomic::add_ptr(v, &_unused);
- }
-
- void add_wasted(size_t v) {
- Atomic::add_ptr(v, &_wasted);
- }
-};
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARGCALLOCBUFFER_HPP
--- a/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.inline.hpp Thu Apr 23 12:47:23 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2014, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
-
-#include "gc_implementation/shared/parGCAllocBuffer.hpp"
-#include "gc_interface/collectedHeap.inline.hpp"
-
-HeapWord* ParGCAllocBuffer::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) {
- return NULL;
- }
-
- // Set _top so that allocate(), which expects _top to be correctly set,
- // can be used below.
- _top = res;
- return allocate(word_sz);
-}
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PARGCALLOCBUFFER_INLINE_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,134 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/plab.hpp"
+#include "memory/threadLocalAllocBuffer.hpp"
+#include "oops/arrayOop.hpp"
+#include "oops/oop.inline.hpp"
+
+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 PLAB::max_size() {
+ return ThreadLocalAllocBuffer::max_size();
+}
+
+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)
+{
+ // ArrayOopDesc::header_size depends on command line initialization.
+ AlignmentReserve = oopDesc::header_size() > MinObjAlignment ? align_object_size(arrayOopDesc::header_size(T_INT)) : 0;
+ assert(min_size() > AlignmentReserve,
+ err_msg("Minimum PLAB size " SIZE_FORMAT" must be larger than alignment reserve " SIZE_FORMAT" "
+ "to be able to contain objects", min_size(), AlignmentReserve));
+}
+
+// If the minimum object size is greater than MinObjAlignment, we can
+// end up with a shard at the end of the buffer that's smaller than
+// 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 PLAB::AlignmentReserve;
+
+void PLAB::flush_and_retire_stats(PLABStats* stats) {
+ // Retire the last allocation buffer.
+ size_t unused = retire_internal();
+
+ // Now flush the statistics.
+ stats->add_allocated(_allocated);
+ stats->add_wasted(_wasted);
+ stats->add_unused(unused);
+
+ // Since we have flushed the stats we need to clear the _allocated and _wasted
+ // fields in case somebody retains an instance of this over GCs. Not doing so
+ // will artifically inflate the values in the statistics.
+ _allocated = 0;
+ _wasted = 0;
+}
+
+void PLAB::retire() {
+ _wasted += retire_internal();
+}
+
+size_t PLAB::retire_internal() {
+ size_t result = 0;
+ if (_top < _hard_end) {
+ CollectedHeap::fill_with_object(_top, _hard_end);
+ result += invalidate();
+ }
+ return result;
+}
+
+// Compute desired plab size and latch result for later
+// use. This should be called once at the end of parallel
+// scavenge; it clears the sensor accumulators.
+void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
+ assert(ResizePLAB, "Not set");
+
+ assert(is_object_aligned(max_size()) && min_size() <= max_size(),
+ "PLAB clipping computation may be incorrect");
+
+ if (_allocated == 0) {
+ assert(_unused == 0,
+ err_msg("Inconsistency in PLAB stats: "
+ "_allocated: "SIZE_FORMAT", "
+ "_wasted: "SIZE_FORMAT", "
+ "_unused: "SIZE_FORMAT,
+ _allocated, _wasted, _unused));
+
+ _allocated = 1;
+ }
+ double wasted_frac = (double)_unused / (double)_allocated;
+ size_t target_refills = (size_t)((wasted_frac * TargetSurvivorRatio) / TargetPLABWastePct);
+ if (target_refills == 0) {
+ target_refills = 1;
+ }
+ size_t used = _allocated - _wasted - _unused;
+ size_t recent_plab_sz = used / (target_refills * no_of_gc_workers);
+ // Take historical weighted average
+ _filter.sample(recent_plab_sz);
+ // Clip from above and below, and align to object boundary
+ size_t new_plab_sz = MAX2(min_size(), (size_t)_filter.average());
+ new_plab_sz = MIN2(max_size(), new_plab_sz);
+ new_plab_sz = align_object_size(new_plab_sz);
+ // Latch the result
+ if (PrintPLAB) {
+ gclog_or_tty->print(" (plab_sz = " SIZE_FORMAT" desired_plab_sz = " SIZE_FORMAT") ", recent_plab_sz, new_plab_sz);
+ }
+ _desired_plab_sz = new_plab_sz;
+
+ reset();
+}
+
+#ifndef PRODUCT
+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));
+}
+#endif // !PRODUCT
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,197 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#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"
+#include "runtime/atomic.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Forward declarations.
+class PLABStats;
+
+// A per-thread allocation buffer used during GC.
+class PLAB: public CHeapObj<mtGC> {
+protected:
+ char head[32];
+ size_t _word_sz; // In HeapWord units
+ HeapWord* _bottom;
+ HeapWord* _top;
+ HeapWord* _end; // Last allocatable address + 1
+ HeapWord* _hard_end; // _end + AlignmentReserve
+ // In support of ergonomic sizing of PLAB's
+ size_t _allocated; // in HeapWord units
+ size_t _wasted; // in HeapWord units
+ char tail[32];
+ static size_t AlignmentReserve;
+
+ // Force future allocations to fail and queries for contains()
+ // to return false. Returns the amount of unused space in this PLAB.
+ size_t invalidate() {
+ _end = _hard_end;
+ size_t remaining = pointer_delta(_end, _top); // Calculate remaining space.
+ _top = _end; // Force future allocations to fail.
+ _bottom = _end; // Force future contains() queries to return false.
+ return remaining;
+ }
+
+ // Fill in remaining space with a dummy object and invalidate the PLAB. Returns
+ // the amount of remaining space.
+ size_t retire_internal();
+
+public:
+ // Initializes the buffer to be empty, but with the given "word_sz".
+ // Must get initialized with "set_buf" for an allocation to succeed.
+ PLAB(size_t word_sz);
+ virtual ~PLAB() {}
+
+ // Minimum PLAB size.
+ static size_t min_size();
+ // Maximum PLAB size.
+ static size_t max_size();
+
+ // If an allocation of the given "word_sz" can be satisfied within the
+ // buffer, do the allocation, returning a pointer to the start of the
+ // allocated block. If the allocation request cannot be satisfied,
+ // return NULL.
+ HeapWord* allocate(size_t word_sz) {
+ HeapWord* res = _top;
+ if (pointer_delta(_end, _top) >= word_sz) {
+ _top = _top + word_sz;
+ return res;
+ } else {
+ return NULL;
+ }
+ }
+
+ // Allocate the object aligned to "alignment_in_bytes".
+ HeapWord* allocate_aligned(size_t word_sz, unsigned short alignment_in_bytes);
+
+ // Undo the last allocation in the buffer, which is required to be of the
+ // "obj" of the given "word_sz".
+ void undo_allocation(HeapWord* obj, size_t word_sz) {
+ assert(pointer_delta(_top, _bottom) >= word_sz, "Bad undo");
+ assert(pointer_delta(_top, obj) == word_sz, "Bad undo");
+ _top = obj;
+ }
+
+ // The total (word) size of the buffer, including both allocated and
+ // unallocated space.
+ size_t word_sz() { return _word_sz; }
+
+ // Should only be done if we are about to reset with a new buffer of the
+ // given size.
+ void set_word_size(size_t new_word_sz) {
+ assert(new_word_sz > AlignmentReserve, "Too small");
+ _word_sz = new_word_sz;
+ }
+
+ // The number of words of unallocated space remaining in the buffer.
+ size_t words_remaining() {
+ assert(_end >= _top, "Negative buffer");
+ return pointer_delta(_end, _top, HeapWordSize);
+ }
+
+ bool contains(void* addr) {
+ return (void*)_bottom <= addr && addr < (void*)_hard_end;
+ }
+
+ // Sets the space of the buffer to be [buf, space+word_sz()).
+ virtual void set_buf(HeapWord* buf) {
+ _bottom = buf;
+ _top = _bottom;
+ _hard_end = _bottom + word_sz();
+ _end = _hard_end - AlignmentReserve;
+ assert(_end >= _top, "Negative buffer");
+ // In support of ergonomic sizing
+ _allocated += word_sz();
+ }
+
+ // Flush allocation statistics into the given PLABStats supporting ergonomic
+ // sizing of PLAB's and retire the current buffer. To be called at the end of
+ // GC.
+ virtual void flush_and_retire_stats(PLABStats* stats);
+
+ // Fills in the unallocated portion of the buffer with a garbage object and updates
+ // statistics. To be called during GC.
+ virtual void retire();
+
+ void print() PRODUCT_RETURN;
+};
+
+// PLAB book-keeping.
+class PLABStats VALUE_OBJ_CLASS_SPEC {
+ size_t _allocated; // Total allocated
+ size_t _wasted; // of which wasted (internal fragmentation)
+ size_t _unused; // Unused in last buffer
+ size_t _desired_plab_sz;// Output of filter (below), suitably trimmed and quantized
+ AdaptiveWeightedAverage
+ _filter; // Integrator with decay
+
+ void reset() {
+ _allocated = 0;
+ _wasted = 0;
+ _unused = 0;
+ }
+ public:
+ PLABStats(size_t desired_plab_sz_, unsigned wt) :
+ _allocated(0),
+ _wasted(0),
+ _unused(0),
+ _desired_plab_sz(desired_plab_sz_),
+ _filter(wt)
+ { }
+
+ static const size_t min_size() {
+ return PLAB::min_size();
+ }
+
+ static const size_t max_size() {
+ return PLAB::max_size();
+ }
+
+ size_t desired_plab_sz() {
+ return _desired_plab_sz;
+ }
+
+ // Updates the current desired PLAB size. Computes the new desired PLAB size,
+ // updates _desired_plab_sz and clears sensor accumulators.
+ void adjust_desired_plab_sz(uint no_of_gc_workers);
+
+ void add_allocated(size_t v) {
+ Atomic::add_ptr(v, &_allocated);
+ }
+
+ void add_unused(size_t v) {
+ Atomic::add_ptr(v, &_unused);
+ }
+
+ void add_wasted(size_t v) {
+ Atomic::add_ptr(v, &_wasted);
+ }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/shared/plab.inline.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
+
+#include "gc_implementation/shared/plab.hpp"
+#include "gc_interface/collectedHeap.inline.hpp"
+
+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) {
+ return NULL;
+ }
+
+ // Set _top so that allocate(), which expects _top to be correctly set,
+ // can be used below.
+ _top = res;
+ return allocate(word_sz);
+}
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_PLAB_INLINE_HPP
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -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 @@
_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 @@
}
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() {
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -54,11 +54,7 @@
public:
friend class VM_PopulateDumpSharedSpace;
- protected:
- // Fields:
- static GenCollectedHeap* _gch;
-
- private:
+private:
Generation* _young_gen;
Generation* _old_gen;
@@ -277,11 +273,6 @@
// only and may need to be re-examined in case other
// kinds of collectors are implemented in the future.
virtual bool can_elide_initializing_store_barrier(oop new_obj) {
- // We wanted to assert that:-
- // assert(UseSerialGC || UseConcMarkSweepGC,
- // "Check can_elide_initializing_store_barrier() for this collector");
- // but unfortunately the flag UseSerialGC need not necessarily always
- // be set when DefNew+Tenured are being used.
return is_in_young(new_obj);
}
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -187,7 +187,6 @@
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 @@
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 @@
// 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 @@
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);
--- a/hotspot/src/share/vm/memory/universe.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -687,6 +687,15 @@
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,35 @@
// HeapBased - Use compressed oops with heap base + encoding.
jint Universe::initialize_heap() {
-
- 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
+ jint status = JNI_ERR;
+#if !INCLUDE_ALL_GCS
+ if (UseParallelGC) {
+ fatal("UseParallelGC not supported in this VM.");
+ } else if (UseG1GC) {
+ fatal("UseG1GC not supported in this VM.");
+ } else if (UseConcMarkSweepGC) {
+ fatal("UseConcMarkSweepGC not supported in this VM.");
+#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 if (UseSerialGC) {
+ status = Universe::create_heap<GenCollectedHeap, MarkSweepPolicy>();
} else {
- GenCollectorPolicy *gc_policy;
+ ShouldNotReachHere();
+ }
- if (UseSerialGC) {
- gc_policy = new MarkSweepPolicy();
- } 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);
+ if (status != JNI_OK) {
+ return status;
}
ThreadLocalAllocBuffer::set_max_size(Universe::heap()->max_tlab_size());
- jint status = Universe::heap()->initialize();
- if (status != JNI_OK) {
- return status;
- }
-
#ifdef _LP64
if (UseCompressedOops) {
// Subtract a page because something can get allocated at heap base.
@@ -1063,7 +1057,7 @@
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
--- a/hotspot/src/share/vm/memory/universe.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/memory/universe.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -214,6 +214,7 @@
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);
--- a/hotspot/src/share/vm/oops/oop.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -201,7 +201,6 @@
// 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);
--- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -284,11 +284,6 @@
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);
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -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
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -1560,12 +1560,15 @@
} else {
FLAG_SET_ERGO(bool, UseParallelGC, true);
}
+ } else {
+ FLAG_SET_ERGO(bool, UseSerialGC, true);
}
}
void Arguments::select_gc() {
if (!gc_selected()) {
select_gc_ergonomically();
+ guarantee(gc_selected(), "No GC selected");
}
}
@@ -2091,10 +2094,8 @@
}
if (UseParNewGC && !UseConcMarkSweepGC) {
- // !UseConcMarkSweepGC means that we are using serial old gc. Unfortunately we don't
- // set up UseSerialGC properly, so that can't be used in the check here.
jio_fprintf(defaultStream::error_stream(),
- "It is not possible to combine the ParNew young collector with the Serial old collector.\n");
+ "It is not possible to combine the ParNew young collector with any collector other than CMS.\n");
return false;
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Mon Apr 27 14:41:49 2015 +0200
@@ -1954,7 +1954,7 @@
"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)") \
\
@@ -2284,9 +2284,6 @@
"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)") \
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Apr 27 14:41:49 2015 +0200
@@ -555,7 +555,6 @@
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*) \
\
--- a/hotspot/test/Makefile Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/test/Makefile Mon Apr 27 14:41:49 2015 +0200
@@ -346,6 +346,34 @@
################################################################
+# 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestSelectDefaultGC.java Mon Apr 27 14:41:49 2015 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSelectDefaultGC
+ * @summary Test selection of GC when no GC option is specified
+ * @bug 8068582
+ * @key gc
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ * java.management
+ * @run driver TestSelectDefaultGC
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.util.regex.*;
+
+public class TestSelectDefaultGC {
+ public static boolean versionStringContains(OutputAnalyzer output, String pattern) {
+ Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStderr());
+ return matcher.find();
+ }
+
+ public static void assertVMOption(OutputAnalyzer output, String option, boolean value) {
+ output.shouldMatch(" " + option + " .*=.* " + value + " ");
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Start VM without specifying GC
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+PrintFlagsFinal", "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldHaveExitValue(0);
+
+ boolean isServerVM = versionStringContains(output, "Server VM");
+
+ // Verify GC selection
+ assertVMOption(output, "UseParallelGC", isServerVM);
+ assertVMOption(output, "UseParallelOldGC", isServerVM);
+ assertVMOption(output, "UseSerialGC", !isServerVM);
+ assertVMOption(output, "UseConcMarkSweepGC", false);
+ assertVMOption(output, "UseG1GC", false);
+ assertVMOption(output, "UseParNewGC", false);
+ }
+}
--- a/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java Thu Apr 23 12:47:23 2015 -0700
+++ b/hotspot/test/gc/startup_warnings/TestParNewSerialOld.java Mon Apr 27 14:41:49 2015 +0200
@@ -40,7 +40,7 @@
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
- output.shouldContain("It is not possible to combine the ParNew young collector with the Serial old collector.");
+ output.shouldContain("It is not possible to combine the ParNew young collector with any collector other than CMS.");
output.shouldContain("Error");
output.shouldHaveExitValue(1);
}