This commit is contained in:
Lana Steuck 2015-02-12 16:39:35 -08:00
commit 25db70d299
72 changed files with 3293 additions and 460 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,15 +44,22 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("SymbolTable");
theTableField = type.getAddressField("_the_table");
sharedTableField = type.getAddressField("_shared_table");
}
// Fields
private static AddressField theTableField;
private static AddressField sharedTableField;
private CompactHashTable sharedTable;
// Accessors
public static SymbolTable getTheTable() {
Address tmp = theTableField.getValue();
return (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
SymbolTable table = (SymbolTable) VMObjectFactory.newObject(SymbolTable.class, tmp);
Address shared = sharedTableField.getStaticFieldAddress();
table.sharedTable = (CompactHashTable)VMObjectFactory.newObject(CompactHashTable.class, shared);
return table;
}
public SymbolTable(Address addr) {
@ -73,8 +80,9 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
/** Clone of VM's "temporary" probe routine, as the SA currently
does not support mutation so lookup() would have no effect
anyway. Returns null if the given string is not in the symbol
table. */
anyway. Searches the regular symbol table and the shared symbol
table. Null is returned if the given name is not found in both
tables. */
public Symbol probe(byte[] name) {
long hashValue = hashSymbol(name);
for (HashtableEntry e = (HashtableEntry) bucket(hashToIndex(hashValue)); e != null; e = (HashtableEntry) e.next()) {
@ -85,7 +93,8 @@ public class SymbolTable extends sun.jvm.hotspot.utilities.Hashtable {
}
}
}
return null;
return sharedTable.probe(name, hashValue);
}
public interface SymbolVisitor {

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2015, 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.
*
*/
package sun.jvm.hotspot.utilities;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.utilities.*;
public class CompactHashTable extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("SymbolCompactHashTable");
baseAddressField = type.getAddressField("_base_address");
bucketCountField = type.getCIntegerField("_bucket_count");
tableEndOffsetField = type.getCIntegerField("_table_end_offset");
bucketsField = type.getAddressField("_buckets");
uintSize = db.lookupType("juint").getSize();
}
// Fields
private static CIntegerField bucketCountField;
private static CIntegerField tableEndOffsetField;
private static AddressField baseAddressField;
private static AddressField bucketsField;
private static long uintSize;
private static int BUCKET_OFFSET_MASK = 0x3FFFFFFF;
private static int BUCKET_TYPE_SHIFT = 30;
private static int COMPACT_BUCKET_TYPE = 1;
public CompactHashTable(Address addr) {
super(addr);
}
private int bucketCount() {
return (int)bucketCountField.getValue(addr);
}
private int tableEndOffset() {
return (int)tableEndOffsetField.getValue(addr);
}
private boolean isCompactBucket(int bucket_info) {
return (bucket_info >> BUCKET_TYPE_SHIFT) == COMPACT_BUCKET_TYPE;
}
private int bucketOffset(int bucket_info) {
return bucket_info & BUCKET_OFFSET_MASK;
}
public Symbol probe(byte[] name, long hash) {
long symOffset;
Symbol sym;
Address baseAddress = baseAddressField.getValue(addr);
Address bucket = bucketsField.getValue(addr);
Address bucketEnd = bucket;
long index = hash % bucketCount();
int bucketInfo = (int)bucket.getCIntegerAt(index * uintSize, uintSize, true);
int bucketOffset = bucketOffset(bucketInfo);
int nextBucketInfo = (int)bucket.getCIntegerAt((index+1) * uintSize, uintSize, true);
int nextBucketOffset = bucketOffset(nextBucketInfo);
bucket = bucket.addOffsetTo(bucketOffset * uintSize);
if (isCompactBucket(bucketInfo)) {
symOffset = bucket.getCIntegerAt(0, uintSize, true);
sym = Symbol.create(baseAddress.addOffsetTo(symOffset));
if (sym.equals(name)) {
return sym;
}
} else {
bucketEnd = bucket.addOffsetTo(nextBucketOffset * uintSize);
while (bucket.lessThan(bucketEnd)) {
long symHash = bucket.getCIntegerAt(0, uintSize, true);
if (symHash == hash) {
symOffset = bucket.getCIntegerAt(uintSize, uintSize, true);
Address symAddr = baseAddress.addOffsetTo(symOffset);
sym = Symbol.create(symAddr);
if (sym.equals(name)) {
return sym;
}
}
bucket = bucket.addOffsetTo(2 * uintSize);
}
}
return null;
}
}

View File

@ -143,7 +143,6 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
ShouldNotReachHere();
break;
default:

View File

@ -115,7 +115,6 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
ShouldNotReachHere();
break;
default :

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -123,7 +123,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
intptr_t* sender_sp = NULL;
intptr_t* sender_unextended_sp = NULL;
address sender_pc = NULL;
intptr_t* saved_fp = NULL;
if (is_interpreted_frame()) {
// fp must be safe
@ -132,7 +134,12 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
sender_pc = (address) this->fp()[return_addr_offset];
// for interpreted frames, the value below is the sender "raw" sp,
// which can be different from the sender unextended sp (the sp seen
// by the sender) because of current frame local variables
sender_sp = (intptr_t*) addr_at(sender_sp_offset);
sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
saved_fp = (intptr_t*) this->fp()[link_offset];
} else {
// must be some sort of compiled/runtime frame
@ -144,8 +151,11 @@ bool frame::safe_for_sender(JavaThread *thread) {
}
sender_sp = _unextended_sp + _cb->frame_size();
sender_unextended_sp = sender_sp;
// On Intel the return_address is always the word on the stack
sender_pc = (address) *(sender_sp-1);
// Note: frame::sender_sp_offset is only valid for compiled frame
saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
}
@ -156,7 +166,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
// is really a frame pointer.
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@ -165,7 +174,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
return sender.is_interpreted_frame_valid(thread);
@ -194,7 +203,6 @@ bool frame::safe_for_sender(JavaThread *thread) {
// Could be the call_stub
if (StubRoutines::returns_to_call_stub(sender_pc)) {
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
if (!saved_fp_safe) {
@ -203,7 +211,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
// construct the potential sender
frame sender(sender_sp, saved_fp, sender_pc);
frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
// Validate the JavaCallWrapper an entry frame must have
address jcw = (address)sender.entry_frame_call_wrapper();
@ -568,8 +576,11 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
if (!m->is_valid_method()) return false;
// stack frames shouldn't be much larger than max_stack elements
if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
// this test requires the use the unextended_sp which is the sp as seen by
// the current frame, and not sp which is the "raw" pc which could point
// further because of local variables of the callee method inserted after
// method arguments
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
return false;
}

View File

@ -185,7 +185,6 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
if (val == noreg) {
__ movptr(obj, NULL_WORD);
} else {

View File

@ -189,7 +189,6 @@ static void do_oop_store(InterpreterMacroAssembler* _masm,
}
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
if (val == noreg) {
__ store_heap_oop_null(obj);
} else {

View File

@ -1432,7 +1432,6 @@ void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
// No pre barriers
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
// No pre barriers
break;
default :
@ -1454,7 +1453,6 @@ void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
CardTableModRef_post_barrier(addr, new_val);
break;
case BarrierSet::ModRef:
case BarrierSet::Other:
// No post barriers
break;
default :

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -62,6 +62,7 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "utilities/resourceHash.hpp"
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
@ -693,7 +694,6 @@ void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Hand
}
class NameSigHash: public ResourceObj {
public:
Symbol* _name; // name
@ -1370,6 +1370,33 @@ void ClassFileParser::parse_linenumber_table(
}
class LVT_Hash : public AllStatic {
public:
static bool equals(LocalVariableTableElement const& e0, LocalVariableTableElement const& e1) {
/*
* 3-tuple start_bci/length/slot has to be unique key,
* so the following comparison seems to be redundant:
* && elem->name_cp_index == entry->_elem->name_cp_index
*/
return (e0.start_bci == e1.start_bci &&
e0.length == e1.length &&
e0.name_cp_index == e1.name_cp_index &&
e0.slot == e1.slot);
}
static unsigned int hash(LocalVariableTableElement const& e0) {
unsigned int raw_hash = e0.start_bci;
raw_hash = e0.length + raw_hash * 37;
raw_hash = e0.name_cp_index + raw_hash * 37;
raw_hash = e0.slot + raw_hash * 37;
return raw_hash;
}
};
// Class file LocalVariableTable elements.
class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
public:
@ -1380,88 +1407,6 @@ class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
u2 slot;
};
class LVT_Hash: public CHeapObj<mtClass> {
public:
LocalVariableTableElement *_elem; // element
LVT_Hash* _next; // Next entry in hash table
};
unsigned int hash(LocalVariableTableElement *elem) {
unsigned int raw_hash = elem->start_bci;
raw_hash = elem->length + raw_hash * 37;
raw_hash = elem->name_cp_index + raw_hash * 37;
raw_hash = elem->slot + raw_hash * 37;
return raw_hash % HASH_ROW_SIZE;
}
void initialize_hashtable(LVT_Hash** table) {
for (int i = 0; i < HASH_ROW_SIZE; i++) {
table[i] = NULL;
}
}
void clear_hashtable(LVT_Hash** table) {
for (int i = 0; i < HASH_ROW_SIZE; i++) {
LVT_Hash* current = table[i];
LVT_Hash* next;
while (current != NULL) {
next = current->_next;
current->_next = NULL;
delete(current);
current = next;
}
table[i] = NULL;
}
}
LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) {
LVT_Hash* entry = table[index];
/*
* 3-tuple start_bci/length/slot has to be unique key,
* so the following comparison seems to be redundant:
* && elem->name_cp_index == entry->_elem->name_cp_index
*/
while (entry != NULL) {
if (elem->start_bci == entry->_elem->start_bci
&& elem->length == entry->_elem->length
&& elem->name_cp_index == entry->_elem->name_cp_index
&& elem->slot == entry->_elem->slot
) {
return entry;
}
entry = entry->_next;
}
return NULL;
}
// Return false if the local variable is found in table.
// Return true if no duplicate is found.
// And local variable is added as a new entry in table.
bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) {
// First lookup for duplicates
int index = hash(elem);
LVT_Hash* entry = LVT_lookup(elem, index, table);
if (entry != NULL) {
return false;
}
// No duplicate is found, allocate a new entry and fill it.
if ((entry = new LVT_Hash()) == NULL) {
return false;
}
entry->_elem = elem;
// Insert into hash table
entry->_next = table[index];
table[index] = entry;
return true;
}
void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *lvt) {
lvt->start_bci = Bytes::get_Java_u2((u1*) &src->start_bci);
lvt->length = Bytes::get_Java_u2((u1*) &src->length);
@ -1861,8 +1806,12 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
u2** localvariable_type_table_start,
TRAPS) {
LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
initialize_hashtable(lvt_Hash);
ResourceMark rm(THREAD);
typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
&LVT_Hash::hash, &LVT_Hash::equals> LVT_HashTable;
LVT_HashTable* table = new LVT_HashTable();
// To fill LocalVariableTable in
Classfile_LVT_Element* cf_lvt;
@ -1872,11 +1821,10 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
copy_lvt_element(&cf_lvt[idx], lvt);
// If no duplicates, add LVT elem in hashtable lvt_Hash.
if (LVT_put_after_lookup(lvt, lvt_Hash) == false
// If no duplicates, add LVT elem in hashtable.
if (table->put(*lvt, lvt) == false
&& _need_verify
&& _major_version >= JAVA_1_5_VERSION) {
clear_hashtable(lvt_Hash);
classfile_parse_error("Duplicated LocalVariableTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvt->name_cp_index)->as_utf8(),
@ -1893,29 +1841,25 @@ void ClassFileParser::copy_localvariable_table(ConstMethod* cm,
cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
int index = hash(&lvtt_elem);
LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
LocalVariableTableElement** entry = table->get(lvtt_elem);
if (entry == NULL) {
if (_need_verify) {
clear_hashtable(lvt_Hash);
classfile_parse_error("LVTT entry for '%s' in class file %s "
"does not match any LVT entry",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
}
} else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
clear_hashtable(lvt_Hash);
} else if ((*entry)->signature_cp_index != 0 && _need_verify) {
classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
"entry for '%s' in class file %s",
_cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
CHECK);
} else {
// to add generic signatures into LocalVariableTable
entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
(*entry)->signature_cp_index = lvtt_elem.descriptor_cp_index;
}
}
}
clear_hashtable(lvt_Hash);
}

View File

@ -188,6 +188,7 @@ public:
// dump time.
//
template <class T, class N> class CompactHashtable VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
uintx _base_address;
juint _entry_count;
juint _bucket_count;

View File

@ -3525,9 +3525,14 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
size_t card_index;
while (hrrs.has_next(card_index)) {
jbyte* card_ptr = (jbyte*)bs->byte_for_index(card_index);
if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
*card_ptr = CardTableModRefBS::dirty_card_val();
_dcq.enqueue(card_ptr);
// The remembered set might contain references to already freed
// regions. Filter out such entries to avoid failing card table
// verification.
if (!g1h->heap_region_containing(bs->addr_for(card_ptr))->is_free()) {
if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
*card_ptr = CardTableModRefBS::dirty_card_val();
_dcq.enqueue(card_ptr);
}
}
}
r->rem_set()->clear_locked();

View File

@ -139,6 +139,8 @@ G1CollectorPolicy::G1CollectorPolicy() :
_survivor_cset_region_length(0),
_old_cset_region_length(0),
_sigma(G1ConfidencePercent / 100.0),
_collection_set(NULL),
_collection_set_bytes_used_before(0),
@ -161,17 +163,8 @@ G1CollectorPolicy::G1CollectorPolicy() :
_gc_overhead_perc(0.0) {
uintx confidence_perc = G1ConfidencePercent;
// Put an artificial ceiling on this so that it's not set to a silly value.
if (confidence_perc > 100) {
confidence_perc = 100;
warning("G1ConfidencePercent is set to a value that is too large, "
"it's been updated to %u", confidence_perc);
}
// '_sigma' must be initialized before the SurvRateGroups below because they
// indirecty access '_sigma' trough the 'this' pointer in their constructor.
_sigma = (double) confidence_perc / 100.0;
// SurvRateGroups below must be initialized after '_sigma' because they
// indirectly access '_sigma' through this object passed to their constructor.
_short_lived_surv_rate_group =
new SurvRateGroup(this, "Short Lived", G1YoungSurvRateNumRegionsSummary);
_survivor_surv_rate_group =

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
@ -36,11 +36,10 @@ void G1HotCardCache::initialize(G1RegionToSpaceMapper* card_counts_storage) {
if (default_use_cache()) {
_use_cache = true;
_hot_cache_size = (1 << G1ConcRSLogCacheSize);
_hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
_hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size, mtGC);
_n_hot = 0;
_hot_cache_idx = 0;
reset_hot_cache_internal();
// For refining the cards in the hot cache in parallel
_hot_cache_par_chunk_size = ClaimChunkSize;
@ -64,26 +63,21 @@ jbyte* G1HotCardCache::insert(jbyte* card_ptr) {
// return it for immediate refining.
return card_ptr;
}
// Otherwise, the card is hot.
jbyte* res = NULL;
MutexLockerEx x(HotCardCache_lock, Mutex::_no_safepoint_check_flag);
if (_n_hot == _hot_cache_size) {
res = _hot_cache[_hot_cache_idx];
_n_hot--;
}
size_t index = Atomic::add(1, &_hot_cache_idx) - 1;
size_t masked_index = index & (_hot_cache_size - 1);
jbyte* current_ptr = _hot_cache[masked_index];
// Now _n_hot < _hot_cache_size, and we can insert at _hot_cache_idx.
_hot_cache[_hot_cache_idx] = card_ptr;
_hot_cache_idx++;
if (_hot_cache_idx == _hot_cache_size) {
// Wrap around
_hot_cache_idx = 0;
}
_n_hot++;
return res;
// Try to store the new card pointer into the cache. Compare-and-swap to guard
// against the unlikely event of a race resulting in another card pointer to
// have already been written to the cache. In this case we will return
// card_ptr in favor of the other option, which would be starting over. This
// should be OK since card_ptr will likely be the older card already when/if
// this ever happens.
jbyte* previous_ptr = (jbyte*)Atomic::cmpxchg_ptr(card_ptr,
&_hot_cache[masked_index],
current_ptr);
return (previous_ptr == current_ptr) ? previous_ptr : card_ptr;
}
void G1HotCardCache::drain(uint worker_i,
@ -96,38 +90,38 @@ void G1HotCardCache::drain(uint worker_i,
assert(_hot_cache != NULL, "Logic");
assert(!use_cache(), "cache should be disabled");
int start_idx;
while ((start_idx = _hot_cache_par_claimed_idx) < _n_hot) { // read once
int end_idx = start_idx + _hot_cache_par_chunk_size;
while (_hot_cache_par_claimed_idx < _hot_cache_size) {
size_t end_idx = Atomic::add(_hot_cache_par_chunk_size,
&_hot_cache_par_claimed_idx);
size_t start_idx = end_idx - _hot_cache_par_chunk_size;
// The current worker has successfully claimed the chunk [start_idx..end_idx)
end_idx = MIN2(end_idx, _hot_cache_size);
for (size_t i = start_idx; i < end_idx; i++) {
jbyte* card_ptr = _hot_cache[i];
if (card_ptr != NULL) {
if (g1rs->refine_card(card_ptr, worker_i, true)) {
// The part of the heap spanned by the card contains references
// that point into the current collection set.
// We need to record the card pointer in the DirtyCardQueueSet
// that we use for such cards.
//
// The only time we care about recording cards that contain
// references that point into the collection set is during
// RSet updating while within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
assert(worker_i < ParallelGCThreads,
err_msg("incorrect worker id: %u", worker_i));
if (start_idx ==
Atomic::cmpxchg(end_idx, &_hot_cache_par_claimed_idx, start_idx)) {
// The current worker has successfully claimed the chunk [start_idx..end_idx)
end_idx = MIN2(end_idx, _n_hot);
for (int i = start_idx; i < end_idx; i++) {
jbyte* card_ptr = _hot_cache[i];
if (card_ptr != NULL) {
if (g1rs->refine_card(card_ptr, worker_i, true)) {
// The part of the heap spanned by the card contains references
// that point into the current collection set.
// We need to record the card pointer in the DirtyCardQueueSet
// that we use for such cards.
//
// The only time we care about recording cards that contain
// references that point into the collection set is during
// RSet updating while within an evacuation pause.
// In this case worker_i should be the id of a GC worker thread
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
assert(worker_i < ParallelGCThreads,
err_msg("incorrect worker id: %u", worker_i));
into_cset_dcq->enqueue(card_ptr);
}
into_cset_dcq->enqueue(card_ptr);
}
} else {
break;
}
}
}
// The existing entries in the hot card cache, which were just refined
// above, are discarded prior to re-enabling the cache near the end of the GC.
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 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
@ -54,21 +54,30 @@ class HeapRegion;
// code, increasing throughput.
class G1HotCardCache: public CHeapObj<mtGC> {
G1CollectedHeap* _g1h;
G1CollectedHeap* _g1h;
bool _use_cache;
G1CardCounts _card_counts;
// The card cache table
jbyte** _hot_cache;
jbyte** _hot_cache;
int _hot_cache_size;
int _n_hot;
int _hot_cache_idx;
size_t _hot_cache_size;
int _hot_cache_par_chunk_size;
volatile int _hot_cache_par_claimed_idx;
int _hot_cache_par_chunk_size;
bool _use_cache;
// Avoids false sharing when concurrently updating _hot_cache_idx or
// _hot_cache_par_claimed_idx. These are never updated at the same time
// thus it's not necessary to separate them as well
char _pad_before[DEFAULT_CACHE_LINE_SIZE];
G1CardCounts _card_counts;
volatile size_t _hot_cache_idx;
volatile size_t _hot_cache_par_claimed_idx;
char _pad_after[DEFAULT_CACHE_LINE_SIZE];
// The number of cached cards a thread claims when flushing the cache
static const int ClaimChunkSize = 32;
@ -113,16 +122,25 @@ class G1HotCardCache: public CHeapObj<mtGC> {
void reset_hot_cache() {
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
assert(Thread::current()->is_VM_thread(), "Current thread should be the VMthread");
_hot_cache_idx = 0; _n_hot = 0;
if (default_use_cache()) {
reset_hot_cache_internal();
}
}
bool hot_cache_is_empty() { return _n_hot == 0; }
// Zeros the values in the card counts table for entire committed heap
void reset_card_counts();
// Zeros the values in the card counts table for the given region
void reset_card_counts(HeapRegion* hr);
private:
void reset_hot_cache_internal() {
assert(_hot_cache != NULL, "Logic");
_hot_cache_idx = 0;
for (size_t i = 0; i < _hot_cache_size; i++) {
_hot_cache[i] = NULL;
}
}
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1HOTCARDCACHE_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -32,11 +32,8 @@
#include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp"
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) :
CardTableModRefBS(whole_heap)
{
_kind = G1SATBCT;
}
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
CardTableModRefBS(whole_heap, kind) { }
void G1SATBCardTableModRefBS::enqueue(oop pre_val) {
// Nulls should have been already filtered.
@ -132,11 +129,10 @@ void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, si
G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
G1SATBCardTableModRefBS(whole_heap),
G1SATBCardTableModRefBS(whole_heap, BarrierSet::G1SATBCTLogging),
_dcqs(JavaThread::dirty_card_queue_set()),
_listener()
{
_kind = G1SATBCTLogging;
_listener.set_card_table(this);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -43,6 +43,9 @@ protected:
g1_young_gen = CT_MR_BS_last_reserved << 1
};
G1SATBCardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
~G1SATBCardTableModRefBS() { }
public:
static int g1_young_card_val() { return g1_young_gen; }
@ -50,8 +53,6 @@ public:
// pre-marking object graph.
static void enqueue(oop pre_val);
G1SATBCardTableModRefBS(MemRegion whole_heap);
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -420,7 +420,7 @@ oops_on_card_seq_iterate_careful(MemRegion mr,
oop obj;
HeapWord* next = cur;
while (next <= start) {
do {
cur = next;
obj = oop(cur);
if (obj->klass_or_null() == NULL) {
@ -429,45 +429,38 @@ oops_on_card_seq_iterate_careful(MemRegion mr,
}
// Otherwise...
next = cur + block_size(cur);
}
} while (next <= start);
// If we finish the above loop...We have a parseable object that
// begins on or before the start of the memory region, and ends
// inside or spans the entire region.
assert(obj == oop(cur), "sanity");
assert(cur <= start, "Loop postcondition");
assert(obj->klass_or_null() != NULL, "Loop postcondition");
assert((cur + block_size(cur)) > start, "Loop postcondition");
if (!g1h->is_obj_dead(obj)) {
obj->oop_iterate(cl, mr);
}
while (cur < end) {
do {
obj = oop(cur);
assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
if (obj->klass_or_null() == NULL) {
// Ran into an unparseable point.
return cur;
};
}
// Otherwise:
next = cur + block_size(cur);
// Advance the current pointer. "obj" still points to the object to iterate.
cur = cur + block_size(cur);
if (!g1h->is_obj_dead(obj)) {
if (next < end || !obj->is_objArray()) {
// This object either does not span the MemRegion
// boundary, or if it does it's not an array.
// Apply closure to whole object.
// Non-objArrays are sometimes marked imprecise at the object start. We
// always need to iterate over them in full.
// We only iterate over object arrays in full if they are completely contained
// in the memory region.
if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) {
obj->oop_iterate(cl);
} else {
// This obj is an array that spans the boundary.
// Stop at the boundary.
obj->oop_iterate(cl, mr);
}
}
cur = next;
}
} while (cur < end);
return NULL;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2010, 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
@ -54,7 +54,7 @@ class CardTableExtension : public CardTableModRefBS {
};
CardTableExtension(MemRegion whole_heap) :
CardTableModRefBS(whole_heap) { }
CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) { }
// Too risky for the 4/10/02 putback
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }

View File

@ -103,6 +103,9 @@ const char* GCCause::to_string(GCCause::Cause cause) {
case _last_ditch_collection:
return "Last ditch collection";
case _dcmd_gc_run:
return "Diagnostic Command";
case _last_gc_cause:
return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";

View File

@ -74,6 +74,9 @@ class GCCause : public AllStatic {
_g1_humongous_allocation,
_last_ditch_collection,
_dcmd_gc_run,
_last_gc_cause
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -39,9 +39,7 @@ public:
CardTableModRef,
CardTableExtension,
G1SATBCT,
G1SATBCTLogging,
Other,
Uninit
G1SATBCTLogging
};
enum Flags {
@ -57,9 +55,11 @@ protected:
static const int _max_covered_regions = 2;
Name _kind;
BarrierSet(Name kind) : _kind(kind) { }
~BarrierSet() { }
public:
BarrierSet() { _kind = Uninit; }
// To get around prohibition on RTTI.
BarrierSet::Name kind() { return _kind; }
virtual bool is_a(BarrierSet::Name bsn) = 0;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -53,8 +53,8 @@ size_t CardTableModRefBS::compute_byte_map_size()
return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
}
CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
ModRefBarrierSet(),
CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind) :
ModRefBarrierSet(kind),
_whole_heap(whole_heap),
_guard_index(0),
_guard_region(),
@ -72,8 +72,6 @@ CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
_lowest_non_clean_base_chunk_index(NULL),
_last_LNC_resizing_collection(NULL)
{
_kind = BarrierSet::CardTableModRef;
assert((uintptr_t(_whole_heap.start()) & (card_size - 1)) == 0, "heap must start at card boundary");
assert((uintptr_t(_whole_heap.end()) & (card_size - 1)) == 0, "heap must end at card boundary");

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -284,20 +284,22 @@ public:
return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
}
CardTableModRefBS(MemRegion whole_heap);
~CardTableModRefBS();
virtual void initialize();
// *** Barrier set functions.
bool has_write_ref_pre_barrier() { return false; }
protected:
CardTableModRefBS(MemRegion whole_heap, BarrierSet::Name kind);
~CardTableModRefBS();
// Record a reference update. Note that these versions are precise!
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
// these functions here for performance.
protected:
void write_ref_field_work(oop obj, size_t offset, oop newVal);
virtual void write_ref_field_work(void* field, oop newVal, bool release = false);
public:
@ -478,7 +480,7 @@ protected:
bool card_may_have_been_dirty(jbyte cv);
public:
CardTableModRefBSForCTRS(MemRegion whole_heap) :
CardTableModRefBS(whole_heap) {}
CardTableModRefBS(whole_heap, BarrierSet::CardTableModRef) {}
void set_CTRS(CardTableRS* rs) { _rs = rs; }
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -37,8 +37,6 @@ class Generation;
class ModRefBarrierSet: public BarrierSet {
public:
ModRefBarrierSet() { _kind = BarrierSet::ModRef; }
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::ModRef;
}
@ -59,7 +57,12 @@ public:
void read_ref_field(void* field) {}
void read_prim_field(HeapWord* field, size_t bytes) {}
protected:
ModRefBarrierSet(BarrierSet::Name kind) : BarrierSet(kind) { }
~ModRefBarrierSet() { }
virtual void write_ref_field_work(void* field, oop new_val, bool release = false) = 0;
public:
void write_prim_field(HeapWord* field, size_t bytes,

View File

@ -1528,7 +1528,6 @@ void GraphKit::pre_barrier(bool do_load,
case BarrierSet::ModRef:
break;
case BarrierSet::Other:
default :
ShouldNotReachHere();
@ -1547,7 +1546,6 @@ bool GraphKit::can_move_pre_barrier() const {
case BarrierSet::ModRef:
return true; // There is no pre-barrier
case BarrierSet::Other:
default :
ShouldNotReachHere();
}
@ -1578,7 +1576,6 @@ void GraphKit::post_barrier(Node* ctl,
case BarrierSet::ModRef:
break;
case BarrierSet::Other:
default :
ShouldNotReachHere();

View File

@ -57,18 +57,6 @@
#define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.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) { \
@ -2316,6 +2304,7 @@ bool Arguments::check_vm_args_consistency() {
status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
status = status && verify_percentage(G1ConfidencePercent, "G1ConfidencePercent");
status = status && verify_percentage(InitiatingHeapOccupancyPercent,
"InitiatingHeapOccupancyPercent");
status = status && verify_min_value(G1RefProcDrainInterval, 1,
@ -3853,6 +3842,8 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
#endif
#endif
ArgumentsExt::report_unsupported_options();
#ifndef PRODUCT
if (TraceBytecodesAt != 0) {
TraceBytecodes = true;

View File

@ -632,4 +632,16 @@ bool Arguments::check_gc_consistency_ergo() {
return check_gc_consistency_user();
}
// 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)
#endif // SHARE_VM_RUNTIME_ARGUMENTS_HPP

View File

@ -37,6 +37,7 @@ public:
// no additional parsing needed in Arguments::parse() for the option.
// Otherwise returns false.
static inline bool process_options(const JavaVMOption *option) { return false; }
static inline void report_unsupported_options() { }
};
void ArgumentsExt::select_gc_ergonomically() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -120,7 +120,6 @@ Monitor* SecondaryFreeList_lock = NULL;
Mutex* OldSets_lock = NULL;
Monitor* RootRegionScan_lock = NULL;
Mutex* MMUTracker_lock = NULL;
Mutex* HotCardCache_lock = NULL;
Monitor* GCTaskManager_lock = NULL;
@ -199,7 +198,6 @@ void mutex_init() {
def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never);
def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never);
def(HotCardCache_lock , Mutex , special , true, Monitor::_safepoint_check_never);
def(EvacFailureStack_lock , Mutex , nonleaf , true, Monitor::_safepoint_check_never);
def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
@ -122,7 +122,6 @@ extern Mutex* OldSets_lock; // protects the old region sets
extern Monitor* RootRegionScan_lock; // used to notify that the CM threads have finished scanning the IM snapshot regions
extern Mutex* MMUTracker_lock; // protects the MMU
// tracker data structures
extern Mutex* HotCardCache_lock; // protects the hot card cache
extern Mutex* Management_lock; // a lock used to serialize JVM management
extern Monitor* Service_lock; // a lock used for service thread operation

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
@ -27,6 +27,7 @@
#include "classfile/javaClasses.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/compactHashtable.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "ci/ciField.hpp"
@ -243,6 +244,7 @@ typedef TwoOopHashtable<Klass*, mtClass> KlassTwoOopHashtable;
typedef Hashtable<Klass*, mtClass> KlassHashtable;
typedef HashtableEntry<Klass*, mtClass> KlassHashtableEntry;
typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
//--------------------------------------------------------------------------------
// VM_STRUCTS
@ -624,6 +626,7 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
/***************/ \
\
static_field(SymbolTable, _the_table, SymbolTable*) \
static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
\
/***************/ \
/* StringTable */ \
@ -632,6 +635,16 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
static_field(StringTable, _the_table, StringTable*) \
\
/********************/ \
/* CompactHashTable */ \
/********************/ \
\
nonstatic_field(SymbolCompactHashTable, _base_address, uintx) \
nonstatic_field(SymbolCompactHashTable, _entry_count, juint) \
nonstatic_field(SymbolCompactHashTable, _bucket_count, juint) \
nonstatic_field(SymbolCompactHashTable, _table_end_offset, juint) \
nonstatic_field(SymbolCompactHashTable, _buckets, juint*) \
\
/********************/ \
/* SystemDictionary */ \
/********************/ \
\
@ -1580,6 +1593,8 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
declare_type(ResourceArea, Arena) \
declare_toplevel_type(Chunk) \
\
declare_toplevel_type(SymbolCompactHashTable) \
\
/***********************************************************/ \
/* Thread hierarchy (needed for run-time type information) */ \
/***********************************************************/ \
@ -2213,7 +2228,6 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
declare_constant(BarrierSet::CardTableExtension) \
declare_constant(BarrierSet::G1SATBCT) \
declare_constant(BarrierSet::G1SATBCTLogging) \
declare_constant(BarrierSet::Other) \
\
declare_constant(BlockOffsetSharedArray::LogN) \
declare_constant(BlockOffsetSharedArray::LogN_words) \

View File

@ -267,7 +267,7 @@ int VMUptimeDCmd::num_arguments() {
void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
if (!DisableExplicitGC) {
Universe::heap()->collect(GCCause::_java_lang_system_gc);
Universe::heap()->collect(GCCause::_dcmd_gc_run);
} else {
output()->print_cr("Explicit GC is disabled, no GC has been performed.");
}

View File

@ -97,7 +97,7 @@ needs_jdk = \
runtime/XCheckJniJsig/XCheckJSig.java \
serviceability/attach/AttachWithStalePidFile.java \
serviceability/sa/jmap-hprof/JMapHProfLargeHeapTest.java \
serviceability/dcmd/DynLibDcmdTest.java
serviceability/dcmd/vm/DynLibsTest.java
# JRE adds further tests to compact3
@ -145,7 +145,8 @@ needs_compact3 = \
gc/survivorAlignment \
runtime/InternalApi/ThreadCpuTimesDeadlock.java \
serviceability/threads/TestFalseDeadLock.java \
compiler/codecache/jmx
compiler/codecache/jmx \
serviceability/dcmd
# Compact 2 adds full VM tests
compact2 = \
@ -224,6 +225,7 @@ needs_g1gc = \
gc/arguments/TestAlignmentToUseLargePages.java \
gc/arguments/TestG1HeapRegionSize.java \
gc/arguments/TestG1HeapSizeFlags.java \
gc/arguments/TestG1PercentageOptions.java \
gc/arguments/TestMaxHeapSizeTools.java \
gc/arguments/TestMaxNewSize.java \
gc/arguments/TestParallelGCThreads.java \

View File

@ -0,0 +1,89 @@
/*
* 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 TestG1PercentageOptions
* @key gc
* @bug 8068942
* @summary Test argument processing of various percentage options
* @library /testlibrary
* @run driver TestG1PercentageOptions
*/
import com.oracle.java.testlibrary.*;
public class TestG1PercentageOptions {
private static final class OptionDescription {
public final String name;
public final String[] valid;
public final String[] invalid;
OptionDescription(String name_, String[] valid_, String[] invalid_) {
name = name_;
valid = valid_;
invalid = invalid_;
}
}
private static final String[] defaultValid = new String[] {
"0", "1", "50", "95", "100" };
private static final String[] defaultInvalid = new String[] {
"-10", "110", "bad" };
// All of the G1 product arguments that are percentages.
private static final OptionDescription[] percentOptions = new OptionDescription[] {
new OptionDescription("G1ConfidencePercent", defaultValid, defaultInvalid)
// Other percentage options are not yet validated by argument processing.
};
private static void check(String flag, boolean is_valid) throws Exception {
String[] flags = new String[] { "-XX:+UseG1GC", flag, "-version" };
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(flags);
OutputAnalyzer output = new OutputAnalyzer(pb.start());
if (is_valid) {
output.shouldHaveExitValue(0);
} else {
output.shouldHaveExitValue(1);
}
}
private static
void check(String name, String value, boolean is_valid) throws Exception {
check("-XX:" + name + "=" + value, is_valid);
}
public static void main(String args[]) throws Exception {
for (OptionDescription option : percentOptions) {
for (String value : option.valid) {
check(option.name, value, true);
}
for (String value : option.invalid) {
check(option.name, value, false);
}
check("-XX:" + option.name, false);
check("-XX:+" + option.name, false);
check("-XX:-" + option.name, false);
}
}
}

View File

@ -0,0 +1,293 @@
/*
* 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.
*/
// This creates a duplicate LVT entry
class DuplicateLVT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LDuplicateLVT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "DuplicateLVT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "DuplicateLVT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
39 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class DuplicateLVT

View File

@ -0,0 +1,293 @@
/*
* 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.
*/
// There's a duplicate LVTT entry below.
class DuplicateLVTT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LDuplicateLVTT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "DuplicateLVTT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "DuplicateLVTT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
39 240 62 65 11;
39 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class DuplicateLVTT

View File

@ -0,0 +1,292 @@
/*
* 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.
*/
// The LVTT entry points to a non-existant LVT entry
class NotFoundLVTT {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #34 #68; // #1
double 0x3FF199999999999A;; // #2
float 0x3F99999A; // #4
long 0xFFFFFFFFCAFEBABE;; // #5
class #69; // #7
Method #7 #68; // #8
String #70; // #9
Method #7 #71; // #10
Field #72 #73; // #11
class #74; // #12
Method #12 #68; // #13
String #75; // #14
Method #12 #76; // #15
Method #12 #77; // #16
Method #12 #78; // #17
Method #79 #80; // #18
String #81; // #19
Method #12 #82; // #20
String #83; // #21
Method #12 #84; // #22
String #85; // #23
Method #12 #86; // #24
String #87; // #25
Method #12 #88; // #26
String #89; // #27
String #90; // #28
Method #12 #91; // #29
String #92; // #30
String #93; // #31
Method #12 #94; // #32
class #95; // #33
class #96; // #34
Utf8 "<init>"; // #35
Utf8 "()V"; // #36
Utf8 "Code"; // #37
Utf8 "LineNumberTable"; // #38
Utf8 "LocalVariableTable"; // #39
Utf8 "this"; // #40
Utf8 "LNotFoundLVTT;"; // #41
Utf8 "main"; // #42
Utf8 "([Ljava/lang/String;)V"; // #43
Utf8 "args"; // #44
Utf8 "[Ljava/lang/String;"; // #45
Utf8 "b"; // #46
Utf8 "Z"; // #47
Utf8 "by"; // #48
Utf8 "B"; // #49
Utf8 "c"; // #50
Utf8 "C"; // #51
Utf8 "d"; // #52
Utf8 "D"; // #53
Utf8 "f"; // #54
Utf8 "F"; // #55
Utf8 "i"; // #56
Utf8 "I"; // #57
Utf8 "l"; // #58
Utf8 "J"; // #59
Utf8 "s"; // #60
Utf8 "S"; // #61
Utf8 "list"; // #62
Utf8 "Ljava/util/ArrayList;"; // #63
Utf8 "LocalVariableTypeTable"; // #64
Utf8 "Ljava/util/ArrayList<Ljava/lang/String;>;"; // #65
Utf8 "SourceFile"; // #66
Utf8 "NotFoundLVTT.java"; // #67
NameAndType #35 #36; // #68
Utf8 "java/util/ArrayList"; // #69
Utf8 "me"; // #70
NameAndType #97 #98; // #71
class #99; // #72
NameAndType #100 #101; // #73
Utf8 "java/lang/StringBuilder"; // #74
Utf8 "b="; // #75
NameAndType #102 #103; // #76
NameAndType #102 #104; // #77
NameAndType #105 #106; // #78
class #107; // #79
NameAndType #108 #109; // #80
Utf8 "by="; // #81
NameAndType #102 #110; // #82
Utf8 "c="; // #83
NameAndType #102 #111; // #84
Utf8 "d="; // #85
NameAndType #102 #112; // #86
Utf8 "f="; // #87
NameAndType #102 #113; // #88
Utf8 "i="; // #89
Utf8 "l="; // #90
NameAndType #102 #114; // #91
Utf8 "s="; // #92
Utf8 "ArrayList<String>="; // #93
NameAndType #102 #115; // #94
Utf8 "NotFoundLVTT"; // #95
Utf8 "java/lang/Object"; // #96
Utf8 "add"; // #97
Utf8 "(Ljava/lang/Object;)Z"; // #98
Utf8 "java/lang/System"; // #99
Utf8 "out"; // #100
Utf8 "Ljava/io/PrintStream;"; // #101
Utf8 "append"; // #102
Utf8 "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; // #103
Utf8 "(Z)Ljava/lang/StringBuilder;"; // #104
Utf8 "toString"; // #105
Utf8 "()Ljava/lang/String;"; // #106
Utf8 "java/io/PrintStream"; // #107
Utf8 "println"; // #108
Utf8 "(Ljava/lang/String;)V"; // #109
Utf8 "(I)Ljava/lang/StringBuilder;"; // #110
Utf8 "(C)Ljava/lang/StringBuilder;"; // #111
Utf8 "(D)Ljava/lang/StringBuilder;"; // #112
Utf8 "(F)Ljava/lang/StringBuilder;"; // #113
Utf8 "(J)Ljava/lang/StringBuilder;"; // #114
Utf8 "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"; // #115
} // Constant Pool
0x0021; // access
#33;// this_cpx
#34;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0001; // access
#35; // name_cpx
#36; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 26;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 5 40 41 0;
}
} // end LocalVariableTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0009; // access
#42; // name_cpx
#43; // sig_cpx
[] { // Attributes
Attr(#37) { // Code
4; // max_stack
12; // max_locals
Bytes[]{
0x043C10423D10583E;
0x1400023904120438;
0x06102A3607140005;
0x37081058360ABB00;
0x0759B700083A0B19;
0x0B1209B6000A57B2;
0x000BBB000C59B700;
0x0D120EB6000F1BB6;
0x0010B60011B60012;
0xB2000BBB000C59B7;
0x000D1213B6000F1C;
0xB60014B60011B600;
0x12B2000BBB000C59;
0xB7000D1215B6000F;
0x1DB60016B60011B6;
0x0012B2000BBB000C;
0x59B7000D1217B600;
0x0F1804B60018B600;
0x11B60012B2000BBB;
0x000C59B7000D1219;
0xB6000F1706B6001A;
0xB60011B60012B200;
0x0BBB000C59B7000D;
0x121BB6000F1507B6;
0x0014B60011B60012;
0xB2000BBB000C59B7;
0x000D121CB6000F16;
0x08B6001DB60011B6;
0x0012B2000BBB000C;
0x59B7000D121EB600;
0x0F150AB60014B600;
0x11B60012B2000BBB;
0x000C59B7000D121F;
0xB6000F190BB60020;
0xB60011B60012B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#38) { // LineNumberTable
[] { // LineNumberTable
0 28;
2 29;
5 30;
8 31;
13 32;
17 33;
21 34;
26 35;
30 36;
39 37;
47 39;
72 40;
97 41;
122 42;
148 43;
174 44;
200 45;
226 46;
252 47;
278 48;
}
} // end LineNumberTable
;
Attr(#39) { // LocalVariableTable
[] { // LocalVariableTable
0 279 44 45 0;
2 277 46 47 1;
5 274 48 49 2;
8 271 50 51 3;
13 266 52 53 4;
17 262 54 55 6;
21 258 56 57 7;
26 253 58 59 8;
30 249 60 61 10;
39 240 62 63 11;
}
} // end LocalVariableTable
;
Attr(#64) { // LocalVariableTypeTable
[] { // LocalVariableTypeTable
38 240 62 65 11;
}
} // end LocalVariableTypeTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#66) { // SourceFile
#67;
} // end SourceFile
} // Attributes
} // end class NotFoundLVTT

View File

@ -0,0 +1,83 @@
/*
* 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
* @bug 8049632
* @summary Test ClassFileParser::copy_localvariable_table cases
* @library /testlibrary
* @compile -g -XDignore.symbol.file TestLVT.java
* @run main TestLVT
*/
import com.oracle.java.testlibrary.*;
import java.util.*;
public class TestLVT {
public static void main(String[] args) throws Exception {
test(); // Test good LVT in this test
String jarFile = System.getProperty("test.src") + "/testcase.jar";
// java -cp $testSrc/testcase.jar DuplicateLVT
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVT");
new OutputAnalyzer(pb.start())
.shouldContain("Duplicated LocalVariableTable attribute entry for 'by' in class file DuplicateLVT")
.shouldHaveExitValue(1);
// java -cp $testclasses/testcase.jar DuplicateLVTT
pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "DuplicateLVTT");
new OutputAnalyzer(pb.start())
.shouldContain("Duplicated LocalVariableTypeTable attribute entry for 'list' in class file DuplicateLVTT")
.shouldHaveExitValue(1);
// java -cp $testclasses/testcase.jar NotFoundLVTT
pb = ProcessTools.createJavaProcessBuilder("-cp", jarFile, "NotFoundLVTT");
new OutputAnalyzer(pb.start())
.shouldContain("LVTT entry for 'list' in class file NotFoundLVTT does not match any LVT entry")
.shouldHaveExitValue(1);
}
public static void test() {
boolean b = true;
byte by = 0x42;
char c = 'X';
double d = 1.1;
float f = (float) 1.2;
int i = 42;
long l = 0xCAFEBABE;
short s = 88;
ArrayList<String> list = new ArrayList<String>();
list.add("me");
System.out.println("b=" + b);
System.out.println("by=" + by);
System.out.println("c=" + c);
System.out.println("d=" + d);
System.out.println("f=" + f);
System.out.println("i=" + i);
System.out.println("l=" + l);
System.out.println("s=" + s);
System.out.println("ArrayList<String>=" + list);
}
}

Binary file not shown.

View File

@ -25,7 +25,7 @@
* @test
* @summary Verifies behaviour of Unsafe.allocateMemory
* @library /testlibrary
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=20m AllocateMemory
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:MallocMaxTestWords=100m AllocateMemory
*/
import com.oracle.java.testlibrary.*;
@ -56,7 +56,7 @@ public class AllocateMemory {
// allocateMemory() should throw an OutOfMemoryError when the underlying malloc fails,
// we test this by limiting the malloc using -XX:MallocMaxTestWords
try {
address = unsafe.allocateMemory(20 * 1024 * 1024 * 8);
address = unsafe.allocateMemory(100 * 1024 * 1024 * 8);
} catch (OutOfMemoryError e) {
// Expected
return;

View File

@ -26,6 +26,7 @@
* @bug 7162400
* @key regression
* @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues
* @ignore 8024055
* @library /testlibrary
* @build com.oracle.java.testlibrary.* AttachWithStalePidFileTarget
* @run main AttachWithStalePidFile

View File

@ -1,73 +0,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.
*/
import sun.management.ManagementFactoryHelper;
import com.sun.management.DiagnosticCommandMBean;
public class DcmdUtil
{
public static String executeDcmd(String cmd, String ... args) {
DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
Object[] dcmdArgs = {args};
String[] signature = {String[].class.getName()};
try {
System.out.print("> " + cmd + " ");
for (String s : args) {
System.out.print(s + " ");
}
System.out.println(":");
String result = (String) dcmd.invoke(transform(cmd), dcmdArgs, signature);
System.out.println(result);
return result;
} catch(Exception ex) {
ex.printStackTrace();
}
return null;
}
private static String transform(String name) {
StringBuilder sb = new StringBuilder();
boolean toLower = true;
boolean toUpper = false;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '.' || c == '_') {
toLower = false;
toUpper = true;
} else {
if (toUpper) {
toUpper = false;
sb.append(Character.toUpperCase(c));
} else if(toLower) {
sb.append(Character.toLowerCase(c));
} else {
sb.append(c);
}
}
}
return sb.toString();
}
}

View File

@ -24,17 +24,23 @@
/*
* @test CodeCacheTest
* @bug 8054889
* @library ..
* @build DcmdUtil CodeCacheTest
* @run main/othervm -XX:+SegmentedCodeCache CodeCacheTest
* @run main/othervm -XX:-SegmentedCodeCache CodeCacheTest
* @run main/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+SegmentedCodeCache CodeCacheTest
* @run testng/othervm -XX:-SegmentedCodeCache CodeCacheTest
* @run testng/othervm -Xint -XX:+SegmentedCodeCache CodeCacheTest
* @summary Test of diagnostic command Compiler.codecache
*/
import java.io.BufferedReader;
import java.io.StringReader;
import java.lang.reflect.Method;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -72,7 +78,7 @@ public class CodeCacheTest {
private static boolean getFlagBool(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?= (true|false)").matcher(where);
if (!m.find()) {
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
Assert.fail("Could not find value for flag " + flag + " in output string");
}
return m.group(1).equals("true");
}
@ -80,16 +86,16 @@ public class CodeCacheTest {
private static int getFlagInt(String flag, String where) {
Matcher m = Pattern.compile(flag + "\\s+:?=\\s+\\d+").matcher(where);
if (!m.find()) {
throw new RuntimeException("Could not find value for flag " + flag + " in output string");
Assert.fail("Could not find value for flag " + flag + " in output string");
}
String match = m.group();
return Integer.parseInt(match.substring(match.lastIndexOf(" ") + 1, match.length()));
}
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
// Get number of code cache segments
int segmentsCount = 0;
String flags = DcmdUtil.executeDcmd("VM.flags", "-all");
String flags = executor.execute("VM.flags -all").getOutput();
if (!getFlagBool("SegmentedCodeCache", flags) || !getFlagBool("UseCompiler", flags)) {
// No segmentation
segmentsCount = 1;
@ -102,29 +108,29 @@ public class CodeCacheTest {
}
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.codecache");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.codecache");
Iterator<String> lines = output.asLines().iterator();
// Validate code cache segments
String line;
Matcher m;
for (int s = 0; s < segmentsCount; ++s) {
// Validate first line
line = r.readLine();
line = lines.next();
m = line1.matcher(line);
if (m.matches()) {
for (int i = 2; i <= 5; i++) {
int val = Integer.parseInt(m.group(i));
if (val < 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
}
} else {
throw new Exception("Regexp 1 failed");
Assert.fail("Regexp 1 failed to match line: " + line);
}
// Validate second line
line = r.readLine();
line = lines.next();
m = line2.matcher(line);
if (m.matches()) {
String start = m.group(1);
@ -133,44 +139,49 @@ public class CodeCacheTest {
// Lexical compare of hex numbers to check that they look sane.
if (start.compareTo(mark) > 1) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
if (mark.compareTo(top) > 1) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
} else {
throw new Exception("Regexp 2 failed line: " + line);
Assert.fail("Regexp 2 failed to match line: " + line);
}
}
// Validate third line
line = r.readLine();
line = lines.next();
m = line3.matcher(line);
if (m.matches()) {
int blobs = Integer.parseInt(m.group(1));
if (blobs <= 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
int nmethods = Integer.parseInt(m.group(2));
if (nmethods < 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
int adapters = Integer.parseInt(m.group(3));
if (adapters <= 0) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
if (blobs < (nmethods + adapters)) {
throw new Exception("Failed parsing dcmd codecache output");
Assert.fail("Failed parsing dcmd codecache output");
}
} else {
throw new Exception("Regexp 3 failed");
Assert.fail("Regexp 3 failed to match line: " + line);
}
// Validate fourth line
line = r.readLine();
line = lines.next();
m = line4.matcher(line);
if (!m.matches()) {
throw new Exception("Regexp 4 failed");
Assert.fail("Regexp 4 failed to match line: " + line);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,14 +24,21 @@
/*
* @test CodelistTest
* @bug 8054889
* @library ..
* @build DcmdUtil MethodIdentifierParser CodelistTest
* @run main CodelistTest
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build MethodIdentifierParser
* @run testng CodelistTest
* @summary Test of diagnostic command Compiler.codelist
*/
import java.io.BufferedReader;
import java.io.StringReader;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.lang.reflect.Method;
public class CodelistTest {
@ -51,19 +58,17 @@ public class CodelistTest {
*
*/
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
int ok = 0;
int fail = 0;
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.codelist");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.codelist");
// Grab a method name from the output
String line;
int count = 0;
while((line = r.readLine()) != null) {
for (String line : output.asLines()) {
count++;
String[] parts = line.split(" ");
@ -83,14 +88,16 @@ public class CodelistTest {
}
MethodIdentifierParser mf = new MethodIdentifierParser(methodPrintedInLogFormat);
Method m;
Method m = null;
try {
m = mf.getMethod();
} catch (NoSuchMethodException e) {
m = null;
} catch (ClassNotFoundException e) {
Assert.fail("Test error: Caught unexpected exception", e);
}
if (m == null) {
throw new Exception("Test failed on: " + methodPrintedInLogFormat);
Assert.fail("Test failed on: " + methodPrintedInLogFormat);
}
if (count > 10) {
// Testing 10 entries is enough. Lets not waste time.
@ -98,4 +105,9 @@ public class CodelistTest {
}
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,17 +24,22 @@
/*
* @test CompilerQueueTest
* @bug 8054889
* @library ..
* @library /testlibrary
* @ignore 8069160
* @build DcmdUtil CompilerQueueTest
* @run main CompilerQueueTest
* @run main/othervm -XX:-TieredCompilation CompilerQueueTest
* @run main/othervm -Xint CompilerQueueTest
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng CompilerQueueTest
* @run testng/othervm -XX:-TieredCompilation CompilerQueueTest
* @run testng/othervm -Xint CompilerQueueTest
* @summary Test of diagnostic command Compiler.queue
*/
import java.io.BufferedReader;
import java.io.StringReader;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
import java.util.Iterator;
public class CompilerQueueTest {
@ -60,52 +65,55 @@ public class CompilerQueueTest {
*
**/
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) {
// Get output from dcmd (diagnostic command)
String result = DcmdUtil.executeDcmd("Compiler.queue");
BufferedReader r = new BufferedReader(new StringReader(result));
OutputAnalyzer output = executor.execute("Compiler.queue");
Iterator<String> lines = output.asLines().iterator();
String str = r.readLine();
while (str != null) {
while (lines.hasNext()) {
String str = lines.next();
if (str.startsWith("Contents of C")) {
match(r.readLine(), "----------------------------");
str = r.readLine();
match(lines.next(), "----------------------------");
str = lines.next();
if (!str.equals("Empty")) {
while (str.charAt(0) != '-') {
validateMethodLine(str);
str = r.readLine();
str = lines.next();
}
} else {
str = r.readLine();
str = lines.next();
}
match(str,"----------------------------");
str = r.readLine();
} else {
throw new Exception("Failed parsing dcmd queue, line: " + str);
Assert.fail("Failed parsing dcmd queue, line: " + str);
}
}
}
private static void validateMethodLine(String str) throws Exception {
private static void validateMethodLine(String str) {
// Skip until package/class name begins. Trim to remove whitespace that
// may differ.
String name = str.substring(14).trim();
int sep = name.indexOf("::");
if (sep == -1) {
throw new Exception("Failed dcmd queue, didn't find separator :: in: " + name);
Assert.fail("Failed dcmd queue, didn't find separator :: in: " + name);
}
try {
Class.forName(name.substring(0, sep));
} catch (ClassNotFoundException e) {
throw new Exception("Failed dcmd queue, Class for name: " + str);
Assert.fail("Failed dcmd queue, Class for name: " + str);
}
}
public static void match(String line, String str) throws Exception {
public static void match(String line, String str) {
if (!line.equals(str)) {
throw new Exception("String equals: " + line + ", " + str);
Assert.fail("String equals: " + line + ", " + str);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -51,11 +51,11 @@ public class MethodIdentifierParser {
// Add sanity check for extracted fields
}
public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException, Exception {
public Method getMethod() throws NoSuchMethodException, SecurityException, ClassNotFoundException {
try {
return Class.forName(className).getDeclaredMethod(methodName, getParamenterDescriptorArray());
} catch (UnexpectedTokenException e) {
throw new Exception("Parse failed");
throw new RuntimeException("Parse failed");
}
}

View File

@ -0,0 +1,69 @@
/*
* 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.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command help (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData HelpTest
*/
public class HelpTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("help");
output.shouldContain("The following commands are available");
output.shouldContain("help");
output.shouldContain("VM.version");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of invalid diagnostic command (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData InvalidCommandTest
*/
public class InvalidCommandTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("asdf");
output.shouldContain("Unknown diagnostic command");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,66 @@
/*
* 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.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.MainClassJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.FileJcmdExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command VM.version (tests all DCMD executors)
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+UsePerfData VMVersionTest
*/
public class VMVersionTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.version");
output.shouldMatch(".*(?:HotSpot|OpenJDK).*VM.*");
}
@Test
public void pid() {
run(new PidJcmdExecutor());
}
@Test
public void mainClass() {
run(new MainClassJcmdExecutor());
}
@Test
public void file() {
run(new FileJcmdExecutor());
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,40 @@
/*
* 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
* @summary Test of diagnostic command GC.class_histogram -all=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build ClassHistogramTest
* @run testng ClassHistogramAllTest
*/
public class ClassHistogramAllTest extends ClassHistogramTest {
public ClassHistogramAllTest() {
super();
classHistogramArgs = "-all=true";
}
/* See ClassHistogramTest for test cases */
}

View File

@ -0,0 +1,89 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import java.util.regex.Pattern;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.class_histogram
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng ClassHistogramTest
*/
public class ClassHistogramTest {
public static class TestClass {}
public static TestClass[] instances = new TestClass[1024];
protected String classHistogramArgs = "";
static {
for (int i = 0; i < instances.length; ++i) {
instances[i] = new TestClass();
}
}
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("GC.class_histogram " + classHistogramArgs);
/*
* example output:
* num #instances #bytes class name
* ----------------------------------------------
* 1: 1647 1133752 [B
* 2: 6198 383168 [C
* 3: 1464 165744 java.lang.Class
* 4: 6151 147624 java.lang.String
* 5: 2304 73728 java.util.concurrent.ConcurrentHashMap$Node
* 6: 1199 64280 [Ljava.lang.Object;
* ...
*/
/* Require at least one java.lang.Class */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Class\\s*$");
/* Require at least one java.lang.String */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.String\\s*$");
/* Require at least one java.lang.Object */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Object\\s*$");
/* Require at exactly one TestClass[] */
output.shouldMatch("^\\s+\\d+:\\s+1\\s+\\d+\\s+" +
Pattern.quote(TestClass[].class.getName()) + "\\s*$");
/* Require at exactly 1024 TestClass */
output.shouldMatch("^\\s+\\d+:\\s+1024\\s+\\d+\\s+" +
Pattern.quote(TestClass.class.getName()) + "\\s*$");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,41 @@
/*
* 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
* @summary Test of diagnostic command GC.heap_dump -all=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build HeapDumpTest
* @run testng HeapDumpAllTest
*/
public class HeapDumpAllTest extends HeapDumpTest {
public HeapDumpAllTest() {
super();
heapDumpArgs = "-all=true";
}
/* See HeapDumpTest for test cases */
}

View File

@ -0,0 +1,90 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.io.IOException;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.PidJcmdExecutor;
/*
* @test
* @summary Test of diagnostic command GC.heap_dump
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng HeapDumpTest
*/
public class HeapDumpTest {
protected String heapDumpArgs = "";
public void run(CommandExecutor executor) {
String fileName = "jcmd.gc.heap_dump." + System.currentTimeMillis() + ".hprof";
String cmd = "GC.heap_dump " + heapDumpArgs + " " + fileName;
executor.execute(cmd);
verifyHeapDump(fileName);
}
private void verifyHeapDump(String fileName) {
String jhat = JDKToolFinder.getJDKTool("jhat");
String[] cmd = { jhat, "-parseonly", "true", fileName };
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = null;
OutputAnalyzer output = null;
try {
p = pb.start();
output = new OutputAnalyzer(p);
/*
* Some hprof dumps of all objects contain constantPoolOop references that cannot be resolved, so we ignore
* failures about resolving constantPoolOop fields using a negative lookahead
*/
output.shouldNotMatch(".*WARNING(?!.*Failed to resolve object.*constantPoolOop.*).*");
} catch (IOException e) {
Assert.fail("Test error: Caught exception while reading stdout/err of jhat", e);
} finally {
if (p != null) {
p.destroy();
}
}
if (output.getExitValue() != 0) {
Assert.fail("Test error: jhat exit code was nonzero");
}
}
/* GC.heap_dump is not available over JMX, running jcmd pid executor instead */
@Test
public void pid() {
run(new PidJcmdExecutor());
}
}

View File

@ -0,0 +1,98 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.run_finalization
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng RunFinalizationTest
*/
public class RunFinalizationTest {
static ReentrantLock lock = new ReentrantLock();
static Condition cond = lock.newCondition();
static volatile boolean wasFinalized = false;
static volatile boolean wasInitialized = false;
class MyObject {
public MyObject() {
/* Make sure object allocation/deallocation is not optimized out */
wasInitialized = true;
}
protected void finalize() {
lock.lock();
wasFinalized = true;
cond.signalAll();
lock.unlock();
}
}
public static MyObject o;
public void run(CommandExecutor executor) {
lock.lock();
o = new MyObject();
o = null;
System.gc();
executor.execute("GC.run_finalization");
int waited = 0;
int waitTime = 15;
try {
System.out.println("Waiting for signal from finalizer");
while (!cond.await(waitTime, TimeUnit.SECONDS)) {
waited += waitTime;
System.out.println(String.format("Waited %d seconds", waited));
}
System.out.println("Received signal");
} catch (InterruptedException e) {
Assert.fail("Test error: Interrupted while waiting for signal from finalizer", e);
} finally {
lock.unlock();
}
if (!wasFinalized) {
Assert.fail("Test failure: Object was not finalized");
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command GC.run
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+PrintGCDetails -Xloggc:RunGC.gclog RunGCTest
*/
public class RunGCTest {
public void run(CommandExecutor executor) {
executor.execute("GC.run");
Path gcLogPath = Paths.get("RunGC.gclog").toAbsolutePath();
String gcLog = null;
try {
gcLog = new String(Files.readAllBytes(gcLogPath));
} catch (IOException e) {
Assert.fail("Test error: Could not read GC log file: " + gcLogPath, e);
}
OutputAnalyzer output = new OutputAnalyzer(gcLog, "");
output.shouldMatch(".*\\[Full GC \\(System(\\.gc\\(\\))?.*");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,39 @@
/*
* 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
* @summary Test of diagnostic command Thread.print -l=true
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @build PrintTest
* @run testng PrintConcurrentLocksTest
*/
public class PrintConcurrentLocksTest extends PrintTest {
public PrintConcurrentLocksTest() {
jucLocks = true;
}
/* See PrintTest for test cases */
}

View File

@ -0,0 +1,174 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
/*
* @test
* @summary Test of diagnostic command Thread.print
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng PrintTest
*/
public class PrintTest {
protected boolean jucLocks = false;
CyclicBarrier readyBarrier = new CyclicBarrier(3);
CyclicBarrier doneBarrier = new CyclicBarrier(3);
private void waitForBarrier(CyclicBarrier b) {
try {
b.await();
} catch (InterruptedException | BrokenBarrierException e) {
Assert.fail("Test error: Caught unexpected exception:", e);
}
}
class MonitorThread extends Thread {
Object lock = new Object();
public void run() {
/* Hold lock on "lock" to show up in thread dump */
synchronized (lock) {
/* Signal that we're ready for thread dump */
waitForBarrier(readyBarrier);
/* Released when the thread dump has been taken */
waitForBarrier(doneBarrier);
}
}
}
class LockThread extends Thread {
ReentrantLock lock = new ReentrantLock();
public void run() {
/* Hold lock "lock" to show up in thread dump */
lock.lock();
/* Signal that we're ready for thread dump */
waitForBarrier(readyBarrier);
/* Released when the thread dump has been taken */
waitForBarrier(doneBarrier);
lock.unlock();
}
}
public void run(CommandExecutor executor) {
MonitorThread mThread = new MonitorThread();
mThread.start();
LockThread lThread = new LockThread();
lThread.start();
/* Wait for threads to get ready */
waitForBarrier(readyBarrier);
/* Execute */
OutputAnalyzer output = executor.execute("Thread.print" + (jucLocks ? " -l=true" : ""));
/* Signal that we've got the thread dump */
waitForBarrier(doneBarrier);
/*
* Example output (trimmed) with arrows indicating the rows we are looking for:
*
* ...
* "Thread-2" #24 prio=5 os_prio=0 tid=0x00007f913411f800 nid=0x4fc9 waiting on condition [0x00007f91fbffe000]
* java.lang.Thread.State: WAITING (parking)
* at sun.misc.Unsafe.park(Native Method)
* - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
* at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
* at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
* at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
* at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
* at Print.waitForBarrier(Print.java:26)
* at Print.access$000(Print.java:18)
* at Print$LockThread.run(Print.java:58)
*
* --> Locked ownable synchronizers:
* --> - <0x000000071a294930> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
*
* "Thread-1" #23 prio=5 os_prio=0 tid=0x00007f913411e800 nid=0x4fc8 waiting on condition [0x00007f9200113000]
* java.lang.Thread.State: WAITING (parking)
* at sun.misc.Unsafe.park(Native Method)
* - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
* at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
* at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
* at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234)
* at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
* at Print.waitForBarrier(Print.java:26)
* at Print.access$000(Print.java:18)
* at Print$MonitorThread.run(Print.java:42)
* --> - locked <0x000000071a294390> (a java.lang.Object)
*
* Locked ownable synchronizers:
* - None
*
* "MainThread" #22 prio=5 os_prio=0 tid=0x00007f923015b000 nid=0x4fc7 in Object.wait() [0x00007f9200840000]
* java.lang.Thread.State: WAITING (on object monitor)
* at java.lang.Object.wait(Native Method)
* - waiting on <0x000000071a70ad98> (a java.lang.UNIXProcess)
* at java.lang.Object.wait(Object.java:502)
* at java.lang.UNIXProcess.waitFor(UNIXProcess.java:397)
* - locked <0x000000071a70ad98> (a java.lang.UNIXProcess)
* at com.oracle.java.testlibrary.dcmd.JcmdExecutor.executeImpl(JcmdExecutor.java:32)
* at com.oracle.java.testlibrary.dcmd.CommandExecutor.execute(CommandExecutor.java:24)
* --> at Print.run(Print.java:74)
* at Print.file(Print.java:112)
* ...
*/
output.shouldMatch(".*at " + Pattern.quote(PrintTest.class.getName()) + "\\.run.*");
output.shouldMatch(".*- locked <0x\\p{XDigit}+> \\(a " + Pattern.quote(mThread.lock.getClass().getName()) + "\\).*");
String jucLockPattern1 = ".*Locked ownable synchronizers:.*";
String jucLockPattern2 = ".*- <0x\\p{XDigit}+> \\(a " + Pattern.quote(lThread.lock.getClass().getName()) + ".*";
if (jucLocks) {
output.shouldMatch(jucLockPattern1);
output.shouldMatch(jucLockPattern2);
} else {
output.shouldNotMatch(jucLockPattern1);
output.shouldNotMatch(jucLockPattern2);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -23,18 +23,26 @@
/*
* @test
*
* @build ClassLoaderStatsTest DcmdUtil
* @run main ClassLoaderStatsTest
* @summary Test of diagnostic command VM.classloader_stats
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng ClassLoaderStatsTest
*/
import java.io.BufferedReader;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -57,36 +65,36 @@ public class ClassLoaderStatsTest {
public static DummyClassLoader dummyloader;
public static void main(String arg[]) throws Exception {
public void run(CommandExecutor executor) throws ClassNotFoundException {
// create a classloader and load our special class
dummyloader = new DummyClassLoader();
Class<?> c = Class.forName("TestClass", true, dummyloader);
if (c.getClassLoader() != dummyloader) {
throw new RuntimeException("TestClass defined by wrong classloader: " + c.getClassLoader());
Assert.fail("TestClass defined by wrong classloader: " + c.getClassLoader());
}
String result = DcmdUtil.executeDcmd("VM.classloader_stats");
BufferedReader r = new BufferedReader(new StringReader(result));
String line;
while((line = r.readLine()) != null) {
OutputAnalyzer output = executor.execute("VM.classloader_stats");
Iterator<String> lines = output.asLines().iterator();
while (lines.hasNext()) {
String line = lines.next();
Matcher m = clLine.matcher(line);
if (m.matches()) {
// verify that DummyClassLoader has loaded 1 class and 1 anonymous class
if (m.group(4).equals("ClassLoaderStatsTest$DummyClassLoader")) {
System.out.println("line: " + line);
if (!m.group(1).equals("1")) {
throw new Exception("Should have loaded 1 class: " + line);
Assert.fail("Should have loaded 1 class: " + line);
}
checkPositiveInt(m.group(2));
checkPositiveInt(m.group(3));
String next = r.readLine();
String next = lines.next();
System.out.println("next: " + next);
Matcher m1 = anonLine.matcher(next);
m1.matches();
if (!m1.group(1).equals("1")) {
throw new Exception("Should have loaded 1 anonymous class, but found : " + m1.group(1));
Assert.fail("Should have loaded 1 anonymous class, but found : " + m1.group(1));
}
checkPositiveInt(m1.group(2));
checkPositiveInt(m1.group(3));
@ -95,9 +103,9 @@ public class ClassLoaderStatsTest {
}
}
private static void checkPositiveInt(String s) throws Exception {
private static void checkPositiveInt(String s) {
if (Integer.parseInt(s) <= 0) {
throw new Exception("Value should have been > 0: " + s);
Assert.fail("Value should have been > 0: " + s);
}
}
@ -114,8 +122,11 @@ public class ClassLoaderStatsTest {
{
return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
} catch (IOException e) {
throw new RuntimeException("Can't open file: " + name, e);
Assert.fail("Can't open file: " + name, e);
}
/* Will not reach here as Assert.fail() throws exception */
return null;
}
protected Class<?> loadClass(String name, boolean resolve)
@ -144,6 +155,10 @@ public class ClassLoaderStatsTest {
}
} /* DummyClassLoader */
@Test
public void jmx() throws ClassNotFoundException {
run(new JMXExecutor());
}
}
class TestClass {

View File

@ -0,0 +1,49 @@
/*
* 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.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import org.testng.annotations.Test;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command VM.command_line
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis CommandLineTest
*/
public class CommandLineTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.command_line");
output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
output.shouldContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -1,6 +1,10 @@
import java.util.HashSet;
import java.util.Set;
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.Platform;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
@ -29,14 +33,15 @@ import com.oracle.java.testlibrary.Platform;
* @test
* @summary Test of VM.dynlib diagnostic command via MBean
* @library /testlibrary
* @build com.oracle.java.testlibrary.* DcmdUtil
* @run main DynLibDcmdTest
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng DynLibsTest
*/
public class DynLibDcmdTest {
public class DynLibsTest {
public static void main(String[] args) throws Exception {
String result = DcmdUtil.executeDcmd("VM.dynlibs");
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.dynlibs");
String osDependentBaseString = null;
if (Platform.isAix()) {
@ -52,18 +57,16 @@ public class DynLibDcmdTest {
}
if (osDependentBaseString == null) {
throw new Exception("Unsupported OS");
Assert.fail("Unsupported OS");
}
Set<String> expectedContent = new HashSet<>();
expectedContent.add(String.format(osDependentBaseString, "jvm"));
expectedContent.add(String.format(osDependentBaseString, "java"));
expectedContent.add(String.format(osDependentBaseString, "management"));
output.shouldContain(String.format(osDependentBaseString, "jvm"));
output.shouldContain(String.format(osDependentBaseString, "java"));
output.shouldContain(String.format(osDependentBaseString, "management"));
}
for(String expected : expectedContent) {
if (!result.contains(expected)) {
throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import org.testng.annotations.Test;
/*
* @test
* @summary Test of diagnostic command VM.flags
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng/othervm -Xmx129m -XX:+PrintGC -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right -XX:-TieredCompilation FlagsTest
*/
public class FlagsTest {
public void run(CommandExecutor executor) {
OutputAnalyzer output = executor.execute("VM.flags");
/* The following are interpreted by the JVM as actual "flags" */
output.shouldContain("-XX:+PrintGC");
output.shouldContain("-XX:+UnlockDiagnosticVMOptions");
output.shouldContain("-XX:+IgnoreUnrecognizedVMOptions");
output.shouldContain("-XX:-TieredCompilation");
/* The following are not */
output.shouldNotContain("-Xmx129m");
output.shouldNotContain("-XX:+ThereShouldNotBeAnyVMOptionNamedLikeThis_Right");
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
/*
* @test
* @summary Test of diagnostic command VM.system_properties
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng SystemPropertiesTest
*/
public class SystemPropertiesTest {
private final static String PROPERTY_NAME = "SystemPropertiesTestPropertyName";
private final static String PROPERTY_VALUE = "SystemPropertiesTestPropertyValue";
public void run(CommandExecutor executor) {
System.setProperty(PROPERTY_NAME, PROPERTY_VALUE);
OutputAnalyzer output = executor.execute("VM.system_properties");
output.shouldContain(PROPERTY_NAME + "=" + PROPERTY_VALUE);
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -0,0 +1,89 @@
/*
* 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.
*/
import org.testng.annotations.Test;
import org.testng.Assert;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.dcmd.CommandExecutor;
import com.oracle.java.testlibrary.dcmd.JMXExecutor;
import java.text.NumberFormat;
import java.text.ParseException;
/*
* @test
* @summary Test of diagnostic command VM.uptime
* @library /testlibrary
* @build com.oracle.java.testlibrary.*
* @build com.oracle.java.testlibrary.dcmd.*
* @run testng UptimeTest
*/
public class UptimeTest {
public void run(CommandExecutor executor) {
double someUptime = 1.0;
long startTime = System.currentTimeMillis();
try {
synchronized (this) {
/* Loop to guard against spurious wake ups */
while (System.currentTimeMillis() < (startTime + someUptime * 1000)) {
wait((int) someUptime * 1000);
}
}
} catch (InterruptedException e) {
Assert.fail("Test error: Exception caught when sleeping:", e);
}
OutputAnalyzer output = executor.execute("VM.uptime");
output.stderrShouldBeEmpty();
/*
* Output should be:
* [pid]:
* xx.yyy s
*
* If there is only one line in output there is no "[pid]:" printout;
* skip first line, split on whitespace and grab first half
*/
int index = output.asLines().size() == 1 ? 0 : 1;
String uptimeString = output.asLines().get(index).split("\\s+")[0];
try {
double uptime = NumberFormat.getNumberInstance().parse(uptimeString).doubleValue();
if (uptime < someUptime) {
Assert.fail(String.format(
"Test failure: Uptime was less than intended sleep time: %.3f s < %.3f s",
uptime, someUptime));
}
} catch (ParseException e) {
Assert.fail("Test failure: Could not parse uptime string: " +
uptimeString, e);
}
}
@Test
public void jmx() {
run(new JMXExecutor());
}
}

View File

@ -24,6 +24,8 @@
package com.oracle.java.testlibrary;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -69,6 +71,58 @@ public final class OutputAnalyzer {
}
/**
* Verify that the stdout contents of output buffer is empty
*
* @throws RuntimeException
* If stdout was not empty
*/
public void stdoutShouldBeEmpty() {
if (!getStdout().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stdout was not empty");
}
}
/**
* Verify that the stderr contents of output buffer is empty
*
* @throws RuntimeException
* If stderr was not empty
*/
public void stderrShouldBeEmpty() {
if (!getStderr().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stderr was not empty");
}
}
/**
* Verify that the stdout contents of output buffer is not empty
*
* @throws RuntimeException
* If stdout was empty
*/
public void stdoutShouldNotBeEmpty() {
if (getStdout().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stdout was empty");
}
}
/**
* Verify that the stderr contents of output buffer is not empty
*
* @throws RuntimeException
* If stderr was empty
*/
public void stderrShouldNotBeEmpty() {
if (getStderr().isEmpty()) {
reportDiagnosticSummary();
throw new RuntimeException("stderr was empty");
}
}
/**
* Verify that the stdout and stderr contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
@ -365,4 +419,18 @@ public final class OutputAnalyzer {
public int getExitValue() {
return exitValue;
}
/**
* Get the contents of the output buffer (stdout and stderr) as list of strings.
* Output will be split by newlines.
*
* @return Contents of the output buffer as list of strings
*/
public List<String> asLines() {
return asLines(getOutput());
}
private List<String> asLines(String buffer) {
return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)"));
}
}

View File

@ -184,23 +184,36 @@ public final class ProcessTools {
return executeProcess(pb);
}
/**
* Executes a process, waits for it to finish and returns the process output.
* @param pb The ProcessBuilder to execute.
* @return The output from the process.
*/
public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Throwable {
OutputAnalyzer output = null;
try {
output = new OutputAnalyzer(pb.start());
return output;
} catch (Throwable t) {
System.out.println("executeProcess() failed: " + t);
throw t;
} finally {
System.out.println(getProcessLog(pb, output));
/**
* Executes a process, waits for it to finish and returns the process output.
* The process will have exited before this method returns.
* @param pb The ProcessBuilder to execute.
* @return The {@linkplain OutputAnalyzer} instance wrapping the process.
*/
public static OutputAnalyzer executeProcess(ProcessBuilder pb) throws Exception {
OutputAnalyzer output = null;
Process p = null;
boolean failed = false;
try {
p = pb.start();
output = new OutputAnalyzer(p);
p.waitFor();
return output;
} catch (Throwable t) {
if (p != null) {
p.destroyForcibly().waitFor();
}
failed = true;
System.out.println("executeProcess() failed: " + t);
throw t;
} finally {
if (failed) {
System.err.println(getProcessLog(pb, output));
}
}
}
}
/**
* Executes a process, waits for it to finish and returns the process output.

View File

@ -0,0 +1,57 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.OutputAnalyzer;
/**
* Abstract base class for Diagnostic Command executors
*/
public abstract class CommandExecutor {
/**
* Execute a diagnostic command
*
* @param cmd The diagnostic command to execute
* @return an {@link jdk.testlibrary.OutputAnalyzer} encapsulating the output of the command
* @throws CommandExecutorException if there is an exception on the "calling side" while trying to execute the
* Diagnostic Command. Exceptions thrown on the remote side are available as textual representations in
* stderr, regardless of the specific executor used.
*/
public final OutputAnalyzer execute(String cmd) throws CommandExecutorException {
System.out.printf("Running DCMD '%s' through '%s'%n", cmd, this.getClass().getSimpleName());
OutputAnalyzer oa = executeImpl(cmd);
System.out.println("---------------- stdout ----------------");
System.out.println(oa.getStdout());
System.out.println("---------------- stderr ----------------");
System.out.println(oa.getStderr());
System.out.println("----------------------------------------");
System.out.println();
return oa;
}
protected abstract OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException;
}

View File

@ -0,0 +1,36 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
/**
* CommandExecutorException encapsulates exceptions thrown (on the "calling side") from the execution of Diagnostic
* Commands
*/
public class CommandExecutorException extends RuntimeException {
private static final long serialVersionUID = -7039597746579144280L;
public CommandExecutorException(String message, Throwable e) {
super(message, e);
}
}

View File

@ -0,0 +1,81 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool and its ability to read
* Diagnostic Commands from a file.
*/
public class FileJcmdExecutor extends PidJcmdExecutor {
/**
* Instantiates a new FileJcmdExecutor targeting the current VM
*/
public FileJcmdExecutor() {
super();
}
/**
* Instantiates a new FileJcmdExecutor targeting the VM indicated by the given pid
*
* @param target Pid of the target VM
*/
public FileJcmdExecutor(String target) {
super(target);
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
File cmdFile = createTempFile();
writeCommandToTemporaryFile(cmd, cmdFile);
return Arrays.asList(jcmdBinary, Integer.toString(pid),
"-f", cmdFile.getAbsolutePath());
}
private void writeCommandToTemporaryFile(String cmd, File cmdFile) {
try (PrintWriter pw = new PrintWriter(cmdFile)) {
pw.println(cmd);
} catch (IOException e) {
String message = "Could not write to file: " + cmdFile.getAbsolutePath();
throw new CommandExecutorException(message, e);
}
}
private File createTempFile() {
try {
File cmdFile = File.createTempFile("input", "jcmd");
cmdFile.deleteOnExit();
return cmdFile;
} catch (IOException e) {
throw new CommandExecutorException("Could not create temporary file", e);
}
}
}

View File

@ -0,0 +1,187 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.OutputAnalyzer;
import javax.management.*;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.util.HashMap;
/**
* Executes Diagnostic Commands on the target VM (specified by a host/port combination or a full JMX Service URL) using
* the JMX interface. If the target is not the current VM, the JMX Remote interface must be enabled beforehand.
*/
public class JMXExecutor extends CommandExecutor {
private final MBeanServerConnection mbs;
/**
* Instantiates a new JMXExecutor targeting the current VM
*/
public JMXExecutor() {
super();
mbs = ManagementFactory.getPlatformMBeanServer();
}
/**
* Instantiates a new JMXExecutor targeting the VM indicated by the given host/port combination or a full JMX
* Service URL
*
* @param target a host/port combination on the format "host:port" or a full JMX Service URL of the target VM
*/
public JMXExecutor(String target) {
String urlStr;
if (target.matches("^\\w[\\w\\-]*(\\.[\\w\\-]+)*:\\d+$")) {
/* Matches "hostname:port" */
urlStr = String.format("service:jmx:rmi:///jndi/rmi://%s/jmxrmi", target);
} else if (target.startsWith("service:")) {
urlStr = target;
} else {
throw new IllegalArgumentException("Could not recognize target string: " + target);
}
try {
JMXServiceURL url = new JMXServiceURL(urlStr);
JMXConnector c = JMXConnectorFactory.connect(url, new HashMap<>());
mbs = c.getMBeanServerConnection();
} catch (IOException e) {
throw new CommandExecutorException("Could not initiate connection to target: " + target, e);
}
}
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
String stdout = "";
String stderr = "";
String[] cmdParts = cmd.split(" ", 2);
String operation = commandToMethodName(cmdParts[0]);
Object[] dcmdArgs = produceArguments(cmdParts);
String[] signature = {String[].class.getName()};
ObjectName beanName = getMBeanName();
try {
stdout = (String) mbs.invoke(beanName, operation, dcmdArgs, signature);
}
/* Failures on the "local" side, the one invoking the command. */
catch (ReflectionException e) {
Throwable cause = e.getCause();
if (cause instanceof NoSuchMethodException) {
/* We want JMXExecutor to match the behavior of the other CommandExecutors */
String message = "Unknown diagnostic command: " + operation;
stderr = exceptionTraceAsString(new IllegalArgumentException(message, e));
} else {
rethrowExecutorException(operation, dcmdArgs, e);
}
}
/* Failures on the "local" side, the one invoking the command. */
catch (InstanceNotFoundException | IOException e) {
rethrowExecutorException(operation, dcmdArgs, e);
}
/* Failures on the remote side, the one executing the invoked command. */
catch (MBeanException e) {
stdout = exceptionTraceAsString(e);
}
return new OutputAnalyzer(stdout, stderr);
}
private void rethrowExecutorException(String operation, Object[] dcmdArgs,
Exception e) throws CommandExecutorException {
String message = String.format("Could not invoke: %s %s", operation,
String.join(" ", (String[]) dcmdArgs[0]));
throw new CommandExecutorException(message, e);
}
private ObjectName getMBeanName() throws CommandExecutorException {
String MBeanName = "com.sun.management:type=DiagnosticCommand";
try {
return new ObjectName(MBeanName);
} catch (MalformedObjectNameException e) {
String message = "MBean not found: " + MBeanName;
throw new CommandExecutorException(message, e);
}
}
private Object[] produceArguments(String[] cmdParts) {
Object[] dcmdArgs = {new String[0]}; /* Default: No arguments */
if (cmdParts.length == 2) {
dcmdArgs[0] = cmdParts[1].split(" ");
}
return dcmdArgs;
}
/**
* Convert from diagnostic command to MBean method name
*
* Examples:
* help --> help
* VM.version --> vmVersion
* VM.command_line --> vmCommandLine
*/
private static String commandToMethodName(String cmd) {
String operation = "";
boolean up = false; /* First letter is to be lower case */
/*
* If a '.' or '_' is encountered it is not copied,
* instead the next character will be converted to upper case
*/
for (char c : cmd.toCharArray()) {
if (('.' == c) || ('_' == c)) {
up = true;
} else if (up) {
operation = operation.concat(Character.toString(c).toUpperCase());
up = false;
} else {
operation = operation.concat(Character.toString(c).toLowerCase());
}
}
return operation;
}
private static String exceptionTraceAsString(Throwable cause) {
StringWriter sw = new StringWriter();
cause.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.JDKToolFinder;
import com.oracle.java.testlibrary.OutputAnalyzer;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.List;
/**
* Base class for Diagnostic Command Executors using the jcmd tool
*/
public abstract class JcmdExecutor extends CommandExecutor {
protected String jcmdBinary;
protected abstract List<String> createCommandLine(String cmd) throws CommandExecutorException;
protected JcmdExecutor() {
jcmdBinary = JDKToolFinder.getJDKTool("jcmd");
}
protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException {
List<String> commandLine = createCommandLine(cmd);
try {
System.out.printf("Executing command '%s'%n", commandLine);
OutputAnalyzer output = ProcessTools.executeProcess(new ProcessBuilder(commandLine));
System.out.printf("Command returned with exit code %d%n", output.getExitValue());
return output;
} catch (Exception e) {
String message = String.format("Caught exception while executing '%s'", commandLine);
throw new CommandExecutorException(message, e);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by main class) using the jcmd tool
*/
public class MainClassJcmdExecutor extends JcmdExecutor {
private final String mainClass;
/**
* Instantiates a new MainClassJcmdExecutor targeting the current VM
*/
public MainClassJcmdExecutor() {
super();
mainClass = System.getProperty("sun.java.command").split(" ")[0];
}
/**
* Instantiates a new MainClassJcmdExecutor targeting the VM indicated by the given main class
*
* @param target Main class of the target VM
*/
public MainClassJcmdExecutor(String target) {
super();
mainClass = target;
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
return Arrays.asList(jcmdBinary, mainClass, cmd);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.
*/
package com.oracle.java.testlibrary.dcmd;
import com.oracle.java.testlibrary.ProcessTools;
import java.util.Arrays;
import java.util.List;
/**
* Executes Diagnostic Commands on the target VM (specified by pid) using the jcmd tool
*/
public class PidJcmdExecutor extends JcmdExecutor {
protected final int pid;
/**
* Instantiates a new PidJcmdExecutor targeting the current VM
*/
public PidJcmdExecutor() {
super();
try {
pid = ProcessTools.getProcessId();
} catch (Exception e) {
throw new CommandExecutorException("Could not determine own pid", e);
}
}
/**
* Instantiates a new PidJcmdExecutor targeting the VM indicated by the given pid
*
* @param target Pid of the target VM
*/
public PidJcmdExecutor(String target) {
super();
pid = Integer.valueOf(target);
}
protected List<String> createCommandLine(String cmd) throws CommandExecutorException {
return Arrays.asList(jcmdBinary, Integer.toString(pid), cmd);
}
}