提交 273152dc 编写于 作者: K kvn

Merge

......@@ -364,3 +364,7 @@ c9dd82da51ed34a28f7c6b3245163ee962e94572 hs25-b40
5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100
46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43
f6921c876db192bba389cec062855a66372da01c jdk8-b101
530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44
c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102
7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45
6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103
......@@ -29,11 +29,10 @@ public interface JVMTIThreadState {
public static final int JVMTI_THREAD_STATE_ALIVE = 0x0001;
public static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
public static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
public static final int JVMTI_THREAD_STATE_WAITING = 0x0008;
public static final int JVMTI_THREAD_STATE_WAITING = 0x0080;
public static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
public static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
public static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040;
public static final int JVMTI_THREAD_STATE_WAITING_FOR_NOTIFICATION = 0x0080;
public static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100;
public static final int JVMTI_THREAD_STATE_PARKED = 0x0200;
public static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
......
......@@ -32,7 +32,7 @@ import sun.jvm.hotspot.types.*;
// to the sys_thread_t structure of the classic JVM implementation.
public class OSThread extends VMObject {
private static JIntField interruptedField;
private static JIntField threadIdField;
private static Field threadIdField;
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
......@@ -44,7 +44,7 @@ public class OSThread extends VMObject {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("OSThread");
interruptedField = type.getJIntField("_interrupted");
threadIdField = type.getJIntField("_thread_id");
threadIdField = type.getField("_thread_id");
}
public OSThread(Address addr) {
......@@ -56,7 +56,7 @@ public class OSThread extends VMObject {
}
public int threadId() {
return (int)threadIdField.getValue(addr);
return threadIdField.getJInt(addr);
}
}
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, 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
......@@ -74,23 +74,24 @@ public class ClassDump extends Tool {
public void run() {
// Ready to go with the database...
try {
// The name of the filter always comes from a System property.
// If we have a pkgList, pass it, otherwise let the filter read
// its own System property for the list of classes.
String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
"sun.jvm.hotspot.tools.jcore.PackageNameFilter");
try {
Class filterClass = Class.forName(filterClassName);
if (pkgList == null) {
classFilter = (ClassFilter) filterClass.newInstance();
} else {
Constructor con = filterClass.getConstructor(String.class);
classFilter = (ClassFilter) con.newInstance(pkgList);
if (classFilter == null) {
// If not already set, the name of the filter comes from a System property.
// If we have a pkgList, pass it, otherwise let the filter read
// its own System property for the list of classes.
String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
"sun.jvm.hotspot.tools.jcore.PackageNameFilter");
try {
Class filterClass = Class.forName(filterClassName);
if (pkgList == null) {
classFilter = (ClassFilter) filterClass.newInstance();
} else {
Constructor con = filterClass.getConstructor(String.class);
classFilter = (ClassFilter) con.newInstance(pkgList);
}
} catch(Exception exp) {
System.err.println("Warning: Can not create class filter!");
}
} catch(Exception exp) {
System.err.println("Warning: Can not create class filter!");
}
String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
setOutputDirectory(outputDirectory);
......
......@@ -24,16 +24,20 @@
TYPE=MINIMAL1
INCLUDE_JVMTI ?= false
INCLUDE_FPROF ?= false
INCLUDE_VM_STRUCTS ?= false
INCLUDE_JNI_CHECK ?= false
INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
INCLUDE_TRACE ?= false
INCLUDE_CDS ?= false
# Force all variables to false, overriding any other
# setting that may have occurred in the makefiles. These
# can still be overridden by passing the variable as an
# argument to 'make'
INCLUDE_JVMTI := false
INCLUDE_FPROF := false
INCLUDE_VM_STRUCTS := false
INCLUDE_JNI_CHECK := false
INCLUDE_SERVICES := false
INCLUDE_MANAGEMENT := false
INCLUDE_ALL_GCS := false
INCLUDE_NMT := false
INCLUDE_TRACE := false
INCLUDE_CDS := false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
......
......@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
HS_BUILD_NUMBER=43
HS_BUILD_NUMBER=45
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
......
......@@ -24,16 +24,20 @@
TYPE=MINIMAL1
INCLUDE_JVMTI ?= false
INCLUDE_FPROF ?= false
INCLUDE_VM_STRUCTS ?= false
INCLUDE_JNI_CHECK ?= false
INCLUDE_SERVICES ?= false
INCLUDE_MANAGEMENT ?= false
INCLUDE_ALL_GCS ?= false
INCLUDE_NMT ?= false
INCLUDE_TRACE ?= false
INCLUDE_CDS ?= false
# Force all variables to false, overriding any other
# setting that may have occurred in the makefiles. These
# can still be overridden by passing the variable as an
# argument to 'make'
INCLUDE_JVMTI := false
INCLUDE_FPROF := false
INCLUDE_VM_STRUCTS := false
INCLUDE_JNI_CHECK := false
INCLUDE_SERVICES := false
INCLUDE_MANAGEMENT := false
INCLUDE_ALL_GCS := false
INCLUDE_NMT := false
INCLUDE_TRACE := false
INCLUDE_CDS := false
CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
......
......@@ -42,7 +42,7 @@ define_pd_global(bool, ProfileInterpreter, false);
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
define_pd_global(bool, TieredCompilation, false);
define_pd_global(bool, TieredCompilation, trueInTiered);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 140000);
......
......@@ -44,7 +44,7 @@ define_pd_global(bool, ProfileInterpreter, false);
#else
define_pd_global(bool, ProfileInterpreter, true);
#endif // CC_INTERP
define_pd_global(bool, TieredCompilation, false);
define_pd_global(bool, TieredCompilation, trueInTiered);
define_pd_global(intx, CompileThreshold, 10000);
define_pd_global(intx, BackEdgeThreshold, 100000);
......
......@@ -2295,7 +2295,7 @@ void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
if (gen_type_check) {
// We have determined that offset == referent_offset && src != null.
// if (src->_klass->_reference_type == REF_NONE) -> continue
__ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), UseCompressedKlassPointers ? T_OBJECT : T_ADDRESS), src_klass);
__ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
LIR_Opr reference_type = new_register(T_INT);
__ move(reference_type_addr, reference_type);
......
......@@ -299,7 +299,7 @@ class CompileReplay : public StackObj {
Symbol* method_signature = parse_symbol(CHECK_NULL);
Method* m = k->find_method(method_name, method_signature);
if (m == NULL) {
report_error("can't find method");
report_error("Can't find method");
}
return m;
}
......@@ -398,8 +398,8 @@ class CompileReplay : public StackObj {
// compile <klass> <name> <signature> <entry_bci> <comp_level>
void process_compile(TRAPS) {
// methodHandle method;
Method* method = parse_method(CHECK);
if (had_error()) return;
int entry_bci = parse_int("entry_bci");
const char* comp_level_label = "comp_level";
int comp_level = parse_int(comp_level_label);
......@@ -440,6 +440,7 @@ class CompileReplay : public StackObj {
//
void process_ciMethod(TRAPS) {
Method* method = parse_method(CHECK);
if (had_error()) return;
ciMethodRecord* rec = new_ciMethod(method);
rec->invocation_counter = parse_int("invocation_counter");
rec->backedge_counter = parse_int("backedge_counter");
......@@ -451,6 +452,7 @@ class CompileReplay : public StackObj {
// ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
void process_ciMethodData(TRAPS) {
Method* method = parse_method(CHECK);
if (had_error()) return;
/* jsut copied from Method, to build interpret data*/
if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
return;
......
......@@ -878,7 +878,7 @@ objArrayOop ClassLoader::get_system_packages(TRAPS) {
instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
ResourceMark rm(THREAD);
EventMark m("loading class " INTPTR_FORMAT, (address)h_name);
EventMark m("loading class %s", h_name->as_C_string());
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st;
......
......@@ -122,6 +122,22 @@ class MarkRefsIntoClosure: public CMSOopsInGenClosure {
}
};
class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure {
private:
const MemRegion _span;
CMSBitMap* _bitMap;
protected:
DO_OOP_WORK_DEFN
public:
Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
Prefetch::style prefetch_style() {
return Prefetch::do_read;
}
};
// A variant of the above used in certain kinds of CMS
// marking verification.
class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
......
......@@ -569,6 +569,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_restart_addr(NULL),
_overflow_list(NULL),
_stats(cmsGen),
_eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)),
_eden_chunk_array(NULL), // may be set in ctor body
_eden_chunk_capacity(0), // -- ditto --
_eden_chunk_index(0), // -- ditto --
......@@ -732,7 +733,7 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
// Support for parallelizing survivor space rescan
if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
const size_t max_plab_samples =
((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
......@@ -2137,6 +2138,39 @@ void CMSCollector::do_mark_sweep_work(bool clear_all_soft_refs,
}
void CMSCollector::print_eden_and_survivor_chunk_arrays() {
DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
EdenSpace* eden_space = dng->eden();
ContiguousSpace* from_space = dng->from();
ContiguousSpace* to_space = dng->to();
// Eden
if (_eden_chunk_array != NULL) {
gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
eden_space->bottom(), eden_space->top(),
eden_space->end(), eden_space->capacity());
gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", "
"_eden_chunk_capacity=" SIZE_FORMAT,
_eden_chunk_index, _eden_chunk_capacity);
for (size_t i = 0; i < _eden_chunk_index; i++) {
gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
i, _eden_chunk_array[i]);
}
}
// Survivor
if (_survivor_chunk_array != NULL) {
gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
from_space->bottom(), from_space->top(),
from_space->end(), from_space->capacity());
gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", "
"_survivor_chunk_capacity=" SIZE_FORMAT,
_survivor_chunk_index, _survivor_chunk_capacity);
for (size_t i = 0; i < _survivor_chunk_index; i++) {
gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
i, _survivor_chunk_array[i]);
}
}
}
void CMSCollector::getFreelistLocks() const {
// Get locks for all free lists in all generations that this
// collector is responsible for
......@@ -3549,6 +3583,31 @@ CMSPhaseAccounting::~CMSPhaseAccounting() {
// CMS work
// The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
class CMSParMarkTask : public AbstractGangTask {
protected:
CMSCollector* _collector;
int _n_workers;
CMSParMarkTask(const char* name, CMSCollector* collector, int n_workers) :
AbstractGangTask(name),
_collector(collector),
_n_workers(n_workers) {}
// Work method in support of parallel rescan ... of young gen spaces
void do_young_space_rescan(uint worker_id, OopsInGenClosure* cl,
ContiguousSpace* space,
HeapWord** chunk_array, size_t chunk_top);
void work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl);
};
// Parallel initial mark task
class CMSParInitialMarkTask: public CMSParMarkTask {
public:
CMSParInitialMarkTask(CMSCollector* collector, int n_workers) :
CMSParMarkTask("Scan roots and young gen for initial mark in parallel",
collector, n_workers) {}
void work(uint worker_id);
};
// Checkpoint the roots into this generation from outside
// this generation. [Note this initial checkpoint need only
// be approximate -- we'll do a catch up phase subsequently.]
......@@ -3646,19 +3705,42 @@ void CMSCollector::checkpointRootsInitialWork(bool asynch) {
// the klasses. The claimed marks need to be cleared before marking starts.
ClassLoaderDataGraph::clear_claimed_marks();
CMKlassClosure klass_closure(&notOlder);
if (CMSPrintEdenSurvivorChunks) {
print_eden_and_survivor_chunk_arrays();
}
{
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
gch->gen_process_strong_roots(_cmsGen->level(),
true, // younger gens are roots
true, // activate StrongRootsScope
false, // not scavenging
SharedHeap::ScanningOption(roots_scanning_options()),
&notOlder,
true, // walk all of code cache if (so & SO_CodeCache)
NULL,
&klass_closure);
if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
// The parallel version.
FlexibleWorkGang* workers = gch->workers();
assert(workers != NULL, "Need parallel worker threads.");
int n_workers = workers->active_workers();
CMSParInitialMarkTask tsk(this, n_workers);
gch->set_par_threads(n_workers);
initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
if (n_workers > 1) {
GenCollectedHeap::StrongRootsScope srs(gch);
workers->run_task(&tsk);
} else {
GenCollectedHeap::StrongRootsScope srs(gch);
tsk.work(0);
}
gch->set_par_threads(0);
} else {
// The serial version.
CMKlassClosure klass_closure(&notOlder);
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
gch->gen_process_strong_roots(_cmsGen->level(),
true, // younger gens are roots
true, // activate StrongRootsScope
false, // not scavenging
SharedHeap::ScanningOption(roots_scanning_options()),
&notOlder,
true, // walk all of code cache if (so & SO_CodeCache)
NULL,
&klass_closure);
}
}
// Clear mod-union table; it will be dirtied in the prologue of
......@@ -4417,7 +4499,9 @@ void CMSCollector::preclean() {
verify_overflow_empty();
_abort_preclean = false;
if (CMSPrecleaningEnabled) {
_eden_chunk_index = 0;
if (!CMSEdenChunksRecordAlways) {
_eden_chunk_index = 0;
}
size_t used = get_eden_used();
size_t capacity = get_eden_capacity();
// Don't start sampling unless we will get sufficiently
......@@ -4526,7 +4610,9 @@ void CMSCollector::sample_eden() {
if (!_start_sampling) {
return;
}
if (_eden_chunk_array) {
// When CMSEdenChunksRecordAlways is true, the eden chunk array
// is populated by the young generation.
if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) {
if (_eden_chunk_index < _eden_chunk_capacity) {
_eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample
assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
......@@ -5010,6 +5096,10 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
// Update the saved marks which may affect the root scans.
gch->save_marks();
if (CMSPrintEdenSurvivorChunks) {
print_eden_and_survivor_chunk_arrays();
}
{
COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
......@@ -5116,10 +5206,53 @@ void CMSCollector::checkpointRootsFinalWork(bool asynch,
}
}
void CMSParInitialMarkTask::work(uint worker_id) {
elapsedTimer _timer;
ResourceMark rm;
HandleMark hm;
// ---------- scan from roots --------------
_timer.start();
GenCollectedHeap* gch = GenCollectedHeap::heap();
Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
CMKlassClosure klass_closure(&par_mri_cl);
// ---------- young gen roots --------------
{
work_on_young_gen_roots(worker_id, &par_mri_cl);
_timer.stop();
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr(
"Finished young gen initial mark scan work in %dth thread: %3.3f sec",
worker_id, _timer.seconds());
}
}
// ---------- remaining roots --------------
_timer.reset();
_timer.start();
gch->gen_process_strong_roots(_collector->_cmsGen->level(),
false, // yg was scanned above
false, // this is parallel code
false, // not scavenging
SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
&par_mri_cl,
true, // walk all of code cache if (so & SO_CodeCache)
NULL,
&klass_closure);
assert(_collector->should_unload_classes()
|| (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
"if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
_timer.stop();
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr(
"Finished remaining root initial mark scan work in %dth thread: %3.3f sec",
worker_id, _timer.seconds());
}
}
// Parallel remark task
class CMSParRemarkTask: public AbstractGangTask {
CMSCollector* _collector;
int _n_workers;
class CMSParRemarkTask: public CMSParMarkTask {
CompactibleFreeListSpace* _cms_space;
// The per-thread work queues, available here for stealing.
......@@ -5133,10 +5266,9 @@ class CMSParRemarkTask: public AbstractGangTask {
CompactibleFreeListSpace* cms_space,
int n_workers, FlexibleWorkGang* workers,
OopTaskQueueSet* task_queues):
AbstractGangTask("Rescan roots and grey objects in parallel"),
_collector(collector),
CMSParMarkTask("Rescan roots and grey objects in parallel",
collector, n_workers),
_cms_space(cms_space),
_n_workers(n_workers),
_task_queues(task_queues),
_term(n_workers, task_queues) { }
......@@ -5150,11 +5282,6 @@ class CMSParRemarkTask: public AbstractGangTask {
void work(uint worker_id);
private:
// Work method in support of parallel rescan ... of young gen spaces
void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
ContiguousSpace* space,
HeapWord** chunk_array, size_t chunk_top);
// ... of dirty cards in old space
void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
Par_MarkRefsIntoAndScanClosure* cl);
......@@ -5186,6 +5313,25 @@ class RemarkKlassClosure : public KlassClosure {
}
};
void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
EdenSpace* eden_space = dng->eden();
ContiguousSpace* from_space = dng->from();
ContiguousSpace* to_space = dng->to();
HeapWord** eca = _collector->_eden_chunk_array;
size_t ect = _collector->_eden_chunk_index;
HeapWord** sca = _collector->_survivor_chunk_array;
size_t sct = _collector->_survivor_chunk_index;
assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
do_young_space_rescan(worker_id, cl, to_space, NULL, 0);
do_young_space_rescan(worker_id, cl, from_space, sca, sct);
do_young_space_rescan(worker_id, cl, eden_space, eca, ect);
}
// work_queue(i) is passed to the closure
// Par_MarkRefsIntoAndScanClosure. The "i" parameter
// also is passed to do_dirty_card_rescan_tasks() and to
......@@ -5210,23 +5356,7 @@ void CMSParRemarkTask::work(uint worker_id) {
// work first.
// ---------- young gen roots --------------
{
DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
EdenSpace* eden_space = dng->eden();
ContiguousSpace* from_space = dng->from();
ContiguousSpace* to_space = dng->to();
HeapWord** eca = _collector->_eden_chunk_array;
size_t ect = _collector->_eden_chunk_index;
HeapWord** sca = _collector->_survivor_chunk_array;
size_t sct = _collector->_survivor_chunk_index;
assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0);
do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct);
do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect);
work_on_young_gen_roots(worker_id, &par_mrias_cl);
_timer.stop();
if (PrintCMSStatistics != 0) {
gclog_or_tty->print_cr(
......@@ -5334,8 +5464,8 @@ void CMSParRemarkTask::work(uint worker_id) {
// Note that parameter "i" is not used.
void
CMSParRemarkTask::do_young_space_rescan(int i,
Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
CMSParMarkTask::do_young_space_rescan(uint worker_id,
OopsInGenClosure* cl, ContiguousSpace* space,
HeapWord** chunk_array, size_t chunk_top) {
// Until all tasks completed:
// . claim an unclaimed task
......@@ -5530,6 +5660,32 @@ CMSParRemarkTask::do_work_steal(int i, Par_MarkRefsIntoAndScanClosure* cl,
"Else our work is not yet done");
}
// Record object boundaries in _eden_chunk_array by sampling the eden
// top in the slow-path eden object allocation code path and record
// the boundaries, if CMSEdenChunksRecordAlways is true. If
// CMSEdenChunksRecordAlways is false, we use the other asynchronous
// sampling in sample_eden() that activates during the part of the
// preclean phase.
void CMSCollector::sample_eden_chunk() {
if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) {
if (_eden_chunk_lock->try_lock()) {
// Record a sample. This is the critical section. The contents
// of the _eden_chunk_array have to be non-decreasing in the
// address order.
_eden_chunk_array[_eden_chunk_index] = *_top_addr;
assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
"Unexpected state of Eden");
if (_eden_chunk_index == 0 ||
((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) &&
(pointer_delta(_eden_chunk_array[_eden_chunk_index],
_eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) {
_eden_chunk_index++; // commit sample
}
_eden_chunk_lock->unlock();
}
}
}
// Return a thread-local PLAB recording array, as appropriate.
void* CMSCollector::get_data_recorder(int thr_num) {
if (_survivor_plab_array != NULL &&
......@@ -5553,12 +5709,13 @@ void CMSCollector::reset_survivor_plab_arrays() {
// Merge the per-thread plab arrays into the global survivor chunk
// array which will provide the partitioning of the survivor space
// for CMS rescan.
// for CMS initial scan and rescan.
void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
int no_of_gc_threads) {
assert(_survivor_plab_array != NULL, "Error");
assert(_survivor_chunk_array != NULL, "Error");
assert(_collectorState == FinalMarking, "Error");
assert(_collectorState == FinalMarking ||
(CMSParallelInitialMarkEnabled && _collectorState == InitialMarking), "Error");
for (int j = 0; j < no_of_gc_threads; j++) {
_cursor[j] = 0;
}
......@@ -5621,7 +5778,7 @@ void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
}
// Set up the space's par_seq_tasks structure for work claiming
// for parallel rescan of young gen.
// for parallel initial scan and rescan of young gen.
// See ParRescanTask where this is currently used.
void
CMSCollector::
......@@ -6748,6 +6905,28 @@ void MarkRefsIntoClosure::do_oop(oop obj) {
void MarkRefsIntoClosure::do_oop(oop* p) { MarkRefsIntoClosure::do_oop_work(p); }
void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
Par_MarkRefsIntoClosure::Par_MarkRefsIntoClosure(
MemRegion span, CMSBitMap* bitMap):
_span(span),
_bitMap(bitMap)
{
assert(_ref_processor == NULL, "deliberately left NULL");
assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
}
void Par_MarkRefsIntoClosure::do_oop(oop obj) {
// if p points into _span, then mark corresponding bit in _markBitMap
assert(obj->is_oop(), "expected an oop");
HeapWord* addr = (HeapWord*)obj;
if (_span.contains(addr)) {
// this should be made more efficient
_bitMap->par_mark(addr);
}
}
void Par_MarkRefsIntoClosure::do_oop(oop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
void Par_MarkRefsIntoClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
// A variant of the above, used for CMS marking verification.
MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
......@@ -9305,7 +9484,6 @@ void ASConcurrentMarkSweepGeneration::shrink_by(size_t desired_bytes) {
return;
}
}
// Transfer some number of overflown objects to usual marking
// stack. Return true if some objects were transferred.
bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
......@@ -9377,4 +9555,3 @@ TraceCMSMemoryManagerStats::TraceCMSMemoryManagerStats(CMSCollector::CollectorSt
ShouldNotReachHere();
}
}
......@@ -515,6 +515,8 @@ class CMSCollector: public CHeapObj<mtGC> {
friend class ConcurrentMarkSweepThread;
friend class ConcurrentMarkSweepGeneration;
friend class CompactibleFreeListSpace;
friend class CMSParMarkTask;
friend class CMSParInitialMarkTask;
friend class CMSParRemarkTask;
friend class CMSConcMarkingTask;
friend class CMSRefProcTaskProxy;
......@@ -749,6 +751,7 @@ class CMSCollector: public CHeapObj<mtGC> {
Generation* _young_gen; // the younger gen
HeapWord** _top_addr; // ... Top of Eden
HeapWord** _end_addr; // ... End of Eden
Mutex* _eden_chunk_lock;
HeapWord** _eden_chunk_array; // ... Eden partitioning array
size_t _eden_chunk_index; // ... top (exclusive) of array
size_t _eden_chunk_capacity; // ... max entries in array
......@@ -950,6 +953,7 @@ class CMSCollector: public CHeapObj<mtGC> {
// Support for parallel remark of survivor space
void* get_data_recorder(int thr_num);
void sample_eden_chunk();
CMSBitMap* markBitMap() { return &_markBitMap; }
void directAllocated(HeapWord* start, size_t size);
......@@ -1027,6 +1031,8 @@ class CMSCollector: public CHeapObj<mtGC> {
// Initialization errors
bool completed_initialization() { return _completed_initialization; }
void print_eden_and_survivor_chunk_arrays();
};
class CMSExpansionCause : public AllStatic {
......@@ -1317,6 +1323,10 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
//Delegate to collector
return collector()->get_data_recorder(thr_num);
}
void sample_eden_chunk() {
//Delegate to collector
return collector()->sample_eden_chunk();
}
// Printing
const char* name() const;
......
......@@ -96,11 +96,6 @@
"the buffer will be enqueued for processing. A value of 0 " \
"specifies that mutator threads should not do such filtering.") \
\
develop(intx, G1ExtraRegionSurvRate, 33, \
"If the young survival rate is S, and there's room left in " \
"to-space, we will allow regions whose survival rate is up to " \
"S + (1 - S)*X, where X is this parameter (as a fraction.)") \
\
develop(bool, G1SATBPrintStubs, false, \
"If true, print generated stubs for the SATB barrier") \
\
......@@ -110,9 +105,6 @@
develop(bool, G1RSBarrierRegionFilter, true, \
"If true, generate region filtering code in RS barrier") \
\
develop(bool, G1RSBarrierNullFilter, true, \
"If true, generate null-pointer filtering code in RS barrier") \
\
develop(bool, G1DeferredRSUpdate, true, \
"If true, use deferred RS updates") \
\
......@@ -120,9 +112,6 @@
"If true, verify that no dirty cards remain after RS log " \
"processing.") \
\
develop(bool, G1RSCountHisto, false, \
"If true, print a histogram of RS occupancies after each pause") \
\
diagnostic(bool, G1PrintRegionLivenessInfo, false, \
"Prints the liveness information for all regions in the heap " \
"at the end of a marking cycle.") \
......@@ -169,9 +158,6 @@
product(uintx, G1ConcRSHotCardLimit, 4, \
"The threshold that defines (>=) a hot card.") \
\
develop(bool, G1PrintOopAppls, false, \
"When true, print applications of closures to external locs.") \
\
develop(intx, G1RSetRegionEntriesBase, 256, \
"Max number of regions in a fine-grain table per MB.") \
\
......
......@@ -314,6 +314,11 @@ void HeapRegion::setup_heap_region_size(uintx min_heap_size) {
region_size = MAX_REGION_SIZE;
}
if (region_size != G1HeapRegionSize) {
// Update the flag to make sure that PrintFlagsFinal logs the correct value
FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size);
}
// And recalculate the log.
region_size_log = log2_long((jlong) region_size);
......
......@@ -1033,6 +1033,9 @@ HeapWord* DefNewGeneration::allocate(size_t word_size,
// have to use it here, as well.
HeapWord* result = eden()->par_allocate(word_size);
if (result != NULL) {
if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
_next_gen->sample_eden_chunk();
}
return result;
}
do {
......@@ -1063,13 +1066,19 @@ HeapWord* DefNewGeneration::allocate(size_t word_size,
// circular dependency at compile time.
if (result == NULL) {
result = allocate_from_space(word_size);
} else if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
_next_gen->sample_eden_chunk();
}
return result;
}
HeapWord* DefNewGeneration::par_allocate(size_t word_size,
bool is_tlab) {
return eden()->par_allocate(word_size);
HeapWord* res = eden()->par_allocate(word_size);
if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
_next_gen->sample_eden_chunk();
}
return res;
}
void DefNewGeneration::gc_prologue(bool full) {
......
......@@ -455,6 +455,7 @@ class Generation: public CHeapObj<mtGC> {
// expected to be GC worker thread-local, with the worker index
// indicated by "thr_num".
virtual void* get_data_recorder(int thr_num) { return NULL; }
virtual void sample_eden_chunk() {}
// Some generations may require some cleanup actions before allowing
// a verification.
......
......@@ -2254,10 +2254,11 @@ ChunkIndex ChunkManager::list_index(size_t size) {
void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
assert_lock_strong(_lock);
size_t raw_word_size = get_raw_word_size(word_size);
size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
assert(word_size >= min_size,
assert(raw_word_size >= min_size,
err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
block_freelists()->return_block(p, word_size);
block_freelists()->return_block(p, raw_word_size);
}
// Adds a chunk to the list of chunks in use.
......
......@@ -65,7 +65,8 @@ SharedHeap::SharedHeap(CollectorPolicy* policy_) :
}
_sh = this; // ch is static, should be set only once.
if ((UseParNewGC ||
(UseConcMarkSweepGC && CMSParallelRemarkEnabled) ||
(UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
CMSParallelRemarkEnabled)) ||
UseG1GC) &&
ParallelGCThreads > 0) {
_workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
......
......@@ -60,6 +60,28 @@
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
#define DEFAULT_JAVA_LAUNCHER "generic"
// Disable options not supported in this release, with a warning if they
// were explicitly requested on the command-line
#define UNSUPPORTED_OPTION(opt, description) \
do { \
if (opt) { \
if (FLAG_IS_CMDLINE(opt)) { \
warning(description " is disabled in this release."); \
} \
FLAG_SET_DEFAULT(opt, false); \
} \
} while(0)
#define UNSUPPORTED_GC_OPTION(gc) \
do { \
if (gc) { \
if (FLAG_IS_CMDLINE(gc)) { \
warning(#gc " is not supported in this VM. Using Serial GC."); \
} \
FLAG_SET_DEFAULT(gc, false); \
} \
} while(0)
char** Arguments::_jvm_flags_array = NULL;
int Arguments::_num_jvm_flags = 0;
char** Arguments::_jvm_args_array = NULL;
......@@ -1891,6 +1913,10 @@ void Arguments::check_deprecated_gc_flags() {
warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
"and will likely be removed in future release");
}
if (FLAG_IS_CMDLINE(DefaultMaxRAMFraction)) {
warning("DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. "
"Use MaxRAMFraction instead.");
}
}
// Check stack pages settings
......@@ -3124,14 +3150,17 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
FLAG_SET_DEFAULT(UseLargePages, false);
}
// Tiered compilation is undefined with C1.
TieredCompilation = false;
#else
if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
}
#endif
#ifndef TIERED
// Tiered compilation is undefined.
UNSUPPORTED_OPTION(TieredCompilation, "TieredCompilation");
#endif
// If we are running in a headless jre, force java.awt.headless property
// to be true unless the property has already been set.
// Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
......@@ -3274,29 +3303,6 @@ void Arguments::set_shared_spaces_flags() {
}
}
// Disable options not supported in this release, with a warning if they
// were explicitly requested on the command-line
#define UNSUPPORTED_OPTION(opt, description) \
do { \
if (opt) { \
if (FLAG_IS_CMDLINE(opt)) { \
warning(description " is disabled in this release."); \
} \
FLAG_SET_DEFAULT(opt, false); \
} \
} while(0)
#define UNSUPPORTED_GC_OPTION(gc) \
do { \
if (gc) { \
if (FLAG_IS_CMDLINE(gc)) { \
warning(#gc " is not supported in this VM. Using Serial GC."); \
} \
FLAG_SET_DEFAULT(gc, false); \
} \
} while(0)
#if !INCLUDE_ALL_GCS
static void force_serial_gc() {
FLAG_SET_DEFAULT(UseSerialGC, true);
......
......@@ -1688,6 +1688,9 @@ class CommandLineFlags {
product(bool, CMSAbortSemantics, false, \
"Whether abort-on-overflow semantics is implemented") \
\
product(bool, CMSParallelInitialMarkEnabled, true, \
"Use the parallel initial mark.") \
\
product(bool, CMSParallelRemarkEnabled, true, \
"Whether parallel remark enabled (only if ParNewGC)") \
\
......@@ -1699,6 +1702,14 @@ class CommandLineFlags {
"Whether to always record survivor space PLAB bdries" \
" (effective only if CMSParallelSurvivorRemarkEnabled)") \
\
product(bool, CMSEdenChunksRecordAlways, true, \
"Whether to always record eden chunks used for " \
"the parallel initial mark or remark of eden" ) \
\
product(bool, CMSPrintEdenSurvivorChunks, false, \
"Print the eden and the survivor chunks used for the parallel " \
"initial mark or remark of the eden/survivor spaces") \
\
product(bool, CMSConcurrentMTEnabled, true, \
"Whether multi-threaded concurrent work enabled (if ParNewGC)") \
\
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, 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
......@@ -211,9 +211,9 @@ void GCNotifier::sendNotificationInternal(TRAPS) {
NotificationMark nm(request);
Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK);
Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK);
Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK);
Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
Handle objCause = java_lang_String::create_from_str(request->gcCause, CHECK);
Klass* k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
instanceKlassHandle gc_mbean_klass(THREAD, k);
......
......@@ -1831,13 +1831,13 @@ class ThreadTimesClosure: public ThreadClosure {
private:
objArrayHandle _names_strings;
char **_names_chars;
typeArrayOop _times;
typeArrayHandle _times;
int _names_len;
int _times_len;
int _count;
public:
ThreadTimesClosure(objArrayHandle names, typeArrayOop times);
ThreadTimesClosure(objArrayHandle names, typeArrayHandle times);
~ThreadTimesClosure();
virtual void do_thread(Thread* thread);
void do_unlocked();
......@@ -1845,9 +1845,9 @@ class ThreadTimesClosure: public ThreadClosure {
};
ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
typeArrayOop times) {
typeArrayHandle times) {
assert(names() != NULL, "names was NULL");
assert(times != NULL, "times was NULL");
assert(times() != NULL, "times was NULL");
_names_strings = names;
_names_len = names->length();
_names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
......@@ -1925,7 +1925,7 @@ JVM_ENTRY(jint, jmm_GetInternalThreadTimes(JNIEnv *env,
typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
typeArrayHandle times_ah(THREAD, ta);
ThreadTimesClosure ttc(names_ah, times_ah());
ThreadTimesClosure ttc(names_ah, times_ah);
{
MutexLockerEx ml(Threads_lock);
Threads::threads_do(&ttc);
......
......@@ -125,13 +125,13 @@ void Exceptions::_throw_oop(Thread* thread, const char* file, int line, oop exce
}
void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
ResourceMark rm;
assert(h_exception() != NULL, "exception should not be NULL");
// tracing (do this up front - so it works during boot strapping)
if (TraceExceptions) {
ttyLocker ttyl;
ResourceMark rm;
tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n"
tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
"thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
h_exception->print_value_string(),
message ? ": " : "", message ? message : "",
......@@ -141,7 +141,9 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc
NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
// Check for special boot-strapping/vm-thread handling
if (special_exception(thread, file, line, h_exception)) return;
if (special_exception(thread, file, line, h_exception)) {
return;
}
assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
......@@ -149,7 +151,9 @@ void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exc
thread->set_pending_exception(h_exception(), file, line);
// vm log
Events::log_exception(thread, "Threw " INTPTR_FORMAT " at %s:%d", (address)h_exception(), file, line);
Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
h_exception->print_value_string(), message ? ": " : "", message ? message : "",
(address)h_exception(), file, line);
}
......
......@@ -395,7 +395,13 @@ bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
template<class E, MEMFLAGS F, unsigned int N>
bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
Age oldAge = _age.get();
uint localBot = _bottom;
// Architectures with weak memory model require a barrier here
// to guarantee that bottom is not older than age,
// which is crucial for the correctness of the algorithm.
#if !(defined SPARC || defined IA32 || defined AMD64)
OrderAccess::fence();
#endif
uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
uint n_elems = size(localBot, oldAge.top());
if (n_elems == 0) {
return false;
......@@ -644,7 +650,7 @@ public:
template<class E, MEMFLAGS F, unsigned int N> inline bool
GenericTaskQueue<E, F, N>::push(E t) {
uint localBot = _bottom;
assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
assert(localBot < N, "_bottom out of range.");
idx_t top = _age.top();
uint dirty_n_elems = dirty_size(localBot, top);
assert(dirty_n_elems < N, "n_elems out of range.");
......
......@@ -35,10 +35,6 @@ public class CheckUpperLimit {
ProcessBuilder pb;
OutputAnalyzer out;
pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2048m", "-version");
out = new OutputAnalyzer(pb.start());
out.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2049m", "-version");
out = new OutputAnalyzer(pb.start());
out.shouldContain("Invalid ReservedCodeCacheSize=");
......
/*
* Copyright (c) 2013, 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
* @bug 8016474
* @summary The bug only happens with C1 and G1 using a different ObjectAlignmentInBytes than KlassAlignmentInBytes (which is 8)
* @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 GetUnsafeObjectG1PreBarrier
*/
import java.lang.reflect.Field;
import sun.misc.Unsafe;
public class GetUnsafeObjectG1PreBarrier {
private static final Unsafe unsafe;
private static final int N = 100_000;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
unsafe = (Unsafe) theUnsafe.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
public Object a;
public static void main(String[] args) throws Throwable {
new GetUnsafeObjectG1PreBarrier();
}
public GetUnsafeObjectG1PreBarrier() throws Throwable {
doit();
}
private void doit() throws Throwable {
Field field = GetUnsafeObjectG1PreBarrier.class.getField("a");
long fieldOffset = unsafe.objectFieldOffset(field);
for (int i = 0; i < N; i++) {
readField(this, fieldOffset);
}
}
private void readField(Object o, long fieldOffset) {
unsafe.getObject(o, fieldOffset);
}
}
/*
* Copyright (c) 2013, 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 TestG1HeapRegionSize
* @key gc
* @bug 8021879
* @summary Verify that the flag G1HeapRegionSize is updated properly
* @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
* @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
* @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
* @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
*/
import sun.management.ManagementFactoryHelper;
import com.sun.management.HotSpotDiagnosticMXBean;
import com.sun.management.VMOption;
public class TestG1HeapRegionSize {
public static void main(String[] args) {
HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
VMOption option = diagnostic.getVMOption("UseG1GC");
if (option.getValue().equals("false")) {
System.out.println("Skipping this test. It is only a G1 test.");
return;
}
String expectedValue = getExpectedValue(args);
option = diagnostic.getVMOption("G1HeapRegionSize");
if (!expectedValue.equals(option.getValue())) {
throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue());
}
}
private static String getExpectedValue(String[] args) {
if (args.length != 1) {
throw new RuntimeException("Wrong number of arguments. Expected 1 but got " + args.length);
}
return args[0];
}
}
......@@ -27,7 +27,7 @@
* @bug 8014240
* @summary Test output of G1PrintRegionRememberedSetInfo
* @library /testlibrary
* @build TestPrintRegionRememberedSetInfo
* @run main TestPrintRegionRememberedSetInfo
* @author thomas.schatzl@oracle.com
*/
......
/*
* Copyright (c) 2013, 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 TestDefaultMaxRAMFraction
* @key gc
* @bug 8021967
* @summary Test that the deprecated TestDefaultMaxRAMFraction flag print a warning message
* @library /testlibrary
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
public class TestDefaultMaxRAMFraction {
public static void main(String[] args) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:DefaultMaxRAMFraction=4", "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("warning: DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. Use MaxRAMFraction instead.");
output.shouldNotContain("error");
output.shouldHaveExitValue(0);
}
}
......@@ -3,6 +3,7 @@
##
## @test Test6929067.sh
## @bug 6929067
## @bug 8021296
## @summary Stack guard pages should be removed when thread is detached
## @compile T.java
## @run shell Test6929067.sh
......@@ -21,6 +22,11 @@ echo "TESTSRC=${TESTSRC}"
OS=`uname -s`
case "$OS" in
Linux)
gcc_cmd=`which gcc`
if [ "x$gcc_cmd" == "x" ]; then
echo "WARNING: gcc not found. Cannot execute test." 2>&1
exit 0;
fi
NULL=/dev/null
PS=":"
FS="/"
......@@ -119,10 +125,10 @@ echo "VM type: ${VMTYPE}"
# Check to ensure you have a /usr/lib/libpthread.so if you don't please look
# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
gcc -DLINUX ${COMP_FLAG} -o invoke \
-I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
-L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-ljvm -lpthread invoke.c
$gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \
-I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
-L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-ljvm -lpthread invoke.c
./invoke
exit $?
......@@ -27,6 +27,7 @@
##
## @test Test7107135.sh
## @bug 7107135
## @bug 8021296
## @summary Stack guard pages lost after loading library with executable stack.
## @run shell Test7107135.sh
##
......@@ -45,6 +46,11 @@ OS=`uname -s`
case "$OS" in
Linux)
echo "Testing on Linux"
gcc_cmd=`which gcc`
if [ "x$gcc_cmd" == "x" ]; then
echo "WARNING: gcc not found. Cannot execute test." 2>&1
exit 0;
fi
;;
*)
NULL=NUL
......@@ -62,7 +68,10 @@ THIS_DIR=.
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
${TESTJAVA}${FS}bin${FS}javac *.java
gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
$gcc_cmd -fPIC -shared -c -o test.o \
-I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \
${TESTSRC}${FS}test.c
ld -shared -z execstack -o libtest-rwx.so test.o
ld -shared -z noexecstack -o libtest-rw.so test.o
......
#
# Copyright (c) 2013, 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 Test8000968.sh
# @bug 8000968
# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
# @run shell Test8000968.sh
#
if [ "${TESTJAVA}" = "" ]
then
PARENT=`dirname \`which java\``
TESTJAVA=`dirname ${PARENT}`
printf "TESTJAVA not set, selecting " ${TESTJAVA}
printf " If this is incorrect, try setting the variable manually.\n"
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
NULL=NUL
;;
* )
FS="/"
NULL=/dev/null
;;
esac
JAVA=${TESTJAVA}${FS}bin${FS}java
#
# See if platform has 64 bit java.
#
${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
if [ "$?" != "1" ]
then
printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
printf "Passed.\n"
exit 0
fi
#
# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
#
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
exit 1
fi
${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
if [ "$?" != "0" ]
then
printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
exit 1
fi
printf "Passed.\n"
exit 0
/*
* Copyright (c) 2013, 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
* @bug 8000968
* @key regression
* @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
* @library /testlibrary
*/
import com.oracle.java.testlibrary.*;
public class CompressedKlassPointerAndOops {
public static void main(String[] args) throws Exception {
if (!Platform.is64bit()) {
// Can't test this on 32 bit, just pass
System.out.println("Skipping test on 32bit");
return;
}
runWithAlignment(16);
runWithAlignment(32);
runWithAlignment(64);
runWithAlignment(128);
}
private static void runWithAlignment(int alignment) throws Exception {
ProcessBuilder pb;
OutputAnalyzer output;
pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UseCompressedKlassPointers",
"-XX:+UseCompressedOops",
"-XX:ObjectAlignmentInBytes=" + alignment,
"-version");
output = new OutputAnalyzer(pb.start());
output.shouldHaveExitValue(0);
}
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2013, 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
......@@ -25,8 +25,9 @@
/*
* @test
* @bug 7196045
* @bug 8014294
* @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
* @run main/othervm -XX:+UsePerfData Test7196045
* @run main/othervm -XX:+UsePerfData -Xmx32m ThreadCpuTimesDeadlock
*/
import java.lang.management.ManagementFactory;
......@@ -35,9 +36,10 @@ import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
public class Test7196045 {
public class ThreadCpuTimesDeadlock {
public static long duration = 1000 * 60 * 2;
public static byte[] dummy;
public static long duration = 10 * 1000;
private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
public static void main(String[] args) {
......@@ -57,6 +59,18 @@ public class Test7196045 {
throw new RuntimeException("Bad object name" + e1);
}
// Thread that allocs memory to generate GC's
Thread allocThread = new Thread() {
public void run() {
while (true) {
dummy = new byte[4096];
}
}
};
allocThread.setDaemon(true);
allocThread.start();
long endTime = System.currentTimeMillis() + duration;
long i = 0;
while (true) {
......
......@@ -27,6 +27,7 @@
## @test Test8017498.sh
## @bug 8017498
## @bug 8020791
## @bug 8021296
## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
## @run shell/timeout=30 Test8017498.sh
##
......@@ -45,6 +46,11 @@ OS=`uname -s`
case "$OS" in
Linux)
echo "Testing on Linux"
gcc_cmd=`which gcc`
if [ "x$gcc_cmd" == "x" ]; then
echo "WARNING: gcc not found. Cannot execute test." 2>&1
exit 0;
fi
if [ "$VM_BITS" = "64" ]
then
MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so
......@@ -64,15 +70,11 @@ THIS_DIR=.
cp ${TESTSRC}${FS}*.java ${THIS_DIR}
${TESTJAVA}${FS}bin${FS}javac *.java
gcc -DLINUX -fPIC -shared \
$gcc_cmd -DLINUX -fPIC -shared \
-o ${TESTSRC}${FS}libTestJNI.so \
-I${TESTJAVA}${FS}include \
-I${TESTJAVA}${FS}include${FS}linux \
${TESTSRC}${FS}TestJNI.c
if [ $? != 0 ]
then
echo "WARNING: the gcc command failed." 2>&1
fi
# run the java test in the background
cmd="LD_PRELOAD=$MY_LD_PRELOAD \
......
......@@ -21,7 +21,6 @@
* questions.
*/
#define _GNU_SOURCE // for the definition of REG_RIP in ucontext.h
#include <stdio.h>
#include <jni.h>
#include <signal.h>
......@@ -32,11 +31,8 @@ extern "C" {
#endif
void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
int thrNum;
printf( " HANDLER (1) " );
// Move forward RIP to skip failing instruction
context->uc_mcontext.gregs[REG_RIP] += 6;
}
JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {
......
/*
* Copyright (c) 2013, 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
* @summary Test the OutputAnalyzer reporting functionality,
* such as printing additional diagnostic info
* (exit code, stdout, stderr, command line, etc.)
* @library /testlibrary
*/
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
public class OutputAnalyzerReportingTest {
public static void main(String[] args) throws Exception {
// Create the output analyzer under test
String stdout = "aaaaaa";
String stderr = "bbbbbb";
OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
// Expected summary values should be the same for all cases,
// since the outputAnalyzer object is the same
String expectedExitValue = "-1";
String expectedSummary =
" stdout: [" + stdout + "];\n" +
" stderr: [" + stderr + "]\n" +
" exitValue = " + expectedExitValue + "\n";
DiagnosticSummaryTestRunner testRunner =
new DiagnosticSummaryTestRunner();
// should have exit value
testRunner.init(expectedSummary);
int unexpectedExitValue = 2;
try {
output.shouldHaveExitValue(unexpectedExitValue);
} catch (RuntimeException e) { }
testRunner.closeAndCheckResults();
// should not contain
testRunner.init(expectedSummary);
try {
output.shouldNotContain(stdout);
} catch (RuntimeException e) { }
testRunner.closeAndCheckResults();
// should contain
testRunner.init(expectedSummary);
try {
output.shouldContain("unexpected-stuff");
} catch (RuntimeException e) { }
testRunner.closeAndCheckResults();
// should not match
testRunner.init(expectedSummary);
try {
output.shouldNotMatch("[a]");
} catch (RuntimeException e) { }
testRunner.closeAndCheckResults();
// should match
testRunner.init(expectedSummary);
try {
output.shouldMatch("[qwerty]");
} catch (RuntimeException e) { }
testRunner.closeAndCheckResults();
}
private static class DiagnosticSummaryTestRunner {
private ByteArrayOutputStream byteStream =
new ByteArrayOutputStream(10000);
private String expectedSummary = "";
private PrintStream errStream;
public void init(String expectedSummary) {
this.expectedSummary = expectedSummary;
byteStream.reset();
errStream = new PrintStream(byteStream);
System.setErr(errStream);
}
public void closeAndCheckResults() {
// check results
errStream.close();
String stdErrStr = byteStream.toString();
if (!stdErrStr.contains(expectedSummary)) {
throw new RuntimeException("The output does not contain "
+ "the diagnostic message, or the message is incorrect");
}
}
}
}
......@@ -76,7 +76,8 @@ public final class OutputAnalyzer {
*/
public void shouldContain(String expectedString) {
if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
}
}
......@@ -88,7 +89,8 @@ public final class OutputAnalyzer {
*/
public void stdoutShouldContain(String expectedString) {
if (!stdout.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
}
}
......@@ -100,7 +102,8 @@ public final class OutputAnalyzer {
*/
public void stderrShouldContain(String expectedString) {
if (!stderr.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
}
}
......@@ -112,10 +115,12 @@ public final class OutputAnalyzer {
*/
public void shouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
}
if (stderr.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
}
}
......@@ -127,7 +132,8 @@ public final class OutputAnalyzer {
*/
public void stdoutShouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
}
}
......@@ -139,7 +145,8 @@ public final class OutputAnalyzer {
*/
public void stderrShouldNotContain(String notExpectedString) {
if (stderr.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
reportDiagnosticSummary();
throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
}
}
......@@ -154,9 +161,9 @@ public final class OutputAnalyzer {
Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
if (!stdoutMatcher.find() && !stderrMatcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' missing from stdout/stderr: [" + stdout + stderr
+ "]\n");
+ "' missing from stdout/stderr \n");
}
}
......@@ -170,8 +177,9 @@ public final class OutputAnalyzer {
public void stdoutShouldMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
if (!matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' missing from stdout: [" + stdout + "]\n");
+ "' missing from stdout \n");
}
}
......@@ -185,8 +193,9 @@ public final class OutputAnalyzer {
public void stderrShouldMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
if (!matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' missing from stderr: [" + stderr + "]\n");
+ "' missing from stderr \n");
}
}
......@@ -200,13 +209,15 @@ public final class OutputAnalyzer {
public void shouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' found in stdout: [" + stdout + "]\n");
+ "' found in stdout \n");
}
matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' found in stderr: [" + stderr + "]\n");
+ "' found in stderr \n");
}
}
......@@ -220,8 +231,9 @@ public final class OutputAnalyzer {
public void stdoutShouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' found in stdout: [" + stdout + "]\n");
+ "' found in stdout \n");
}
}
......@@ -235,23 +247,45 @@ public final class OutputAnalyzer {
public void stderrShouldNotMatch(String pattern) {
Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
if (matcher.find()) {
reportDiagnosticSummary();
throw new RuntimeException("'" + pattern
+ "' found in stderr: [" + stderr + "]\n");
+ "' found in stderr \n");
}
}
/**
* Verifiy the exit value of the process
* Verify the exit value of the process
*
* @param expectedExitValue Expected exit value from process
* @throws RuntimeException If the exit value from the process did not match the expected value
*/
public void shouldHaveExitValue(int expectedExitValue) {
if (getExitValue() != expectedExitValue) {
throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
reportDiagnosticSummary();
throw new RuntimeException("Expected to get exit value of ["
+ expectedExitValue + "]\n");
}
}
/**
* Report summary that will help to diagnose the problem
* Currently includes:
* - standard input produced by the process under test
* - standard output
* - exit code
* Note: the command line is printed by the ProcessTools
*/
private void reportDiagnosticSummary() {
String msg =
" stdout: [" + stdout + "];\n" +
" stderr: [" + stderr + "]\n" +
" exitValue = " + getExitValue() + "\n";
System.err.println(msg);
}
/**
* Get the contents of the output buffer (stdout and stderr)
*
......
......@@ -27,6 +27,7 @@ public class Platform {
private static final String osName = System.getProperty("os.name");
private static final String dataModel = System.getProperty("sun.arch.data.model");
private static final String vmVersion = System.getProperty("java.vm.version");
private static final String osArch = System.getProperty("os.arch");
public static boolean is64bit() {
return dataModel.equals("64");
......@@ -59,4 +60,14 @@ public class Platform {
public static String getVMVersion() {
return vmVersion;
}
// Returns true for sparc and sparcv9.
public static boolean isSparc() {
return osArch.toLowerCase().startsWith("sparc");
}
public static String getOsArch() {
return osArch;
}
}
......@@ -31,6 +31,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import sun.management.VMManagement;
......@@ -106,6 +107,22 @@ public final class ProcessTools {
return pid;
}
/**
* Get the string containing input arguments passed to the VM
*
* @return arguments
*/
public static String getVmInputArguments() {
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
List<String> args = runtime.getInputArguments();
StringBuilder result = new StringBuilder();
for (String arg : args)
result.append(arg).append(' ');
return result.toString();
}
/**
* Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
*
......@@ -132,8 +149,13 @@ public final class ProcessTools {
Collections.addAll(args, getPlatformSpecificVMArgs());
Collections.addAll(args, command);
return new ProcessBuilder(args.toArray(new String[args.size()]));
// Reporting
StringBuilder cmdLine = new StringBuilder();
for (String cmd : args)
cmdLine.append(cmd).append(' ');
System.out.println("Command line: [" + cmdLine.toString() + "]");
return new ProcessBuilder(args.toArray(new String[args.size()]));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册