--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
/** 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 @@
}
}
}
- return null;
+
+ return sharedTable.probe(name, hashValue);
}
public interface SymbolVisitor {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Thu Feb 05 14:57:52 2015 -0800
@@ -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;
+ }
+}
--- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -143,7 +143,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
ShouldNotReachHere();
break;
default:
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -115,7 +115,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
ShouldNotReachHere();
break;
default :
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
}
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 @@
}
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 @@
}
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 @@
// 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 @@
// 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 @@
// 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 @@
// 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 @@
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;
}
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -185,7 +185,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
if (val == noreg) {
__ movptr(obj, NULL_WORD);
} else {
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -189,7 +189,6 @@
}
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
if (val == noreg) {
__ store_heap_oop_null(obj);
} else {
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -1432,7 +1432,6 @@
// No pre barriers
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
// No pre barriers
break;
default :
@@ -1454,7 +1453,6 @@
CardTableModRef_post_barrier(addr, new_val);
break;
case BarrierSet::ModRef:
- case BarrierSet::Other:
// No post barriers
break;
default :
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
}
-
class NameSigHash: public ResourceObj {
public:
Symbol* _name; // name
@@ -1370,6 +1370,33 @@
}
+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 @@
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 @@
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 @@
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 @@
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);
}
--- a/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -188,6 +188,7 @@
// 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;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -3525,9 +3525,14 @@
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();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -139,6 +139,8 @@
_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 @@
_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 =
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
// 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 @@
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;
- 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));
+ 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));
- 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.
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
// 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;
- int _hot_cache_par_chunk_size;
- volatile int _hot_cache_par_claimed_idx;
+ // 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];
- bool _use_cache;
+ volatile size_t _hot_cache_idx;
- G1CardCounts _card_counts;
+ 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 @@
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
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
// 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);
}
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
oop obj;
HeapWord* next = cur;
- while (next <= start) {
+ do {
cur = next;
obj = oop(cur);
if (obj->klass_or_null() == NULL) {
@@ -429,45 +429,38 @@
}
// 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;
}
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
};
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; }
--- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -103,6 +103,9 @@
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";
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -74,6 +74,9 @@
_g1_humongous_allocation,
_last_ditch_collection,
+
+ _dcmd_gc_run,
+
_last_gc_cause
};
--- a/hotspot/src/share/vm/memory/barrierSet.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
CardTableModRef,
CardTableExtension,
G1SATBCT,
- G1SATBCTLogging,
- Other,
- Uninit
+ G1SATBCTLogging
};
enum Flags {
@@ -57,9 +55,11 @@
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;
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
_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");
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
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; }
};
--- a/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 ModRefBarrierSet: public BarrierSet {
public:
- ModRefBarrierSet() { _kind = BarrierSet::ModRef; }
-
bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::ModRef;
}
@@ -59,7 +57,12 @@
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,
--- a/hotspot/src/share/vm/opto/graphKit.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -1528,7 +1528,6 @@
case BarrierSet::ModRef:
break;
- case BarrierSet::Other:
default :
ShouldNotReachHere();
@@ -1547,7 +1546,6 @@
case BarrierSet::ModRef:
return true; // There is no pre-barrier
- case BarrierSet::Other:
default :
ShouldNotReachHere();
}
@@ -1578,7 +1576,6 @@
case BarrierSet::ModRef:
break;
- case BarrierSet::Other:
default :
ShouldNotReachHere();
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
#endif
#endif
+ ArgumentsExt::report_unsupported_options();
+
#ifndef PRODUCT
if (TraceBytecodesAt != 0) {
TraceBytecodes = true;
--- a/hotspot/src/share/vm/runtime/arguments.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -632,4 +632,16 @@
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
--- a/hotspot/src/share/vm/runtime/arguments_ext.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/arguments_ext.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -37,6 +37,7 @@
// 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() {
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
Mutex* OldSets_lock = NULL;
Monitor* RootRegionScan_lock = NULL;
Mutex* MMUTracker_lock = NULL;
-Mutex* HotCardCache_lock = NULL;
Monitor* GCTaskManager_lock = NULL;
@@ -199,7 +198,6 @@
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);
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 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
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -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 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 @@
/***************/ \
\
static_field(SymbolTable, _the_table, SymbolTable*) \
+ static_field(SymbolTable, _shared_table, SymbolCompactHashTable) \
\
/***************/ \
/* StringTable */ \
@@ -632,6 +635,16 @@
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 @@
declare_type(ResourceArea, Arena) \
declare_toplevel_type(Chunk) \
\
+ declare_toplevel_type(SymbolCompactHashTable) \
+ \
/***********************************************************/ \
/* Thread hierarchy (needed for run-time type information) */ \
/***********************************************************/ \
@@ -2213,7 +2228,6 @@
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) \
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Thu Feb 05 14:57:52 2015 -0800
@@ -267,7 +267,7 @@
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.");
}
--- a/hotspot/test/TEST.groups Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/TEST.groups Thu Feb 05 14:57:52 2015 -0800
@@ -97,7 +97,7 @@
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 @@
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 @@
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 \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/arguments/TestG1PercentageOptions.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVT.cod Thu Feb 05 14:57:52 2015 -0800
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVTT.cod Thu Feb 05 14:57:52 2015 -0800
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/NotFoundLVTT.cod Thu Feb 05 14:57:52 2015 -0800
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/LocalVariableTable/TestLVT.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 hotspot/test/runtime/LocalVariableTable/testcase.jar has changed
--- a/hotspot/test/runtime/Unsafe/AllocateMemory.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
// 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;
--- a/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Thu Feb 05 14:57:52 2015 -0800
@@ -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
--- a/hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java Wed Feb 04 17:12:03 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- *
- * @build ClassLoaderStatsTest DcmdUtil
- * @run main ClassLoaderStatsTest
- */
-
-import java.io.BufferedReader;
-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.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class ClassLoaderStatsTest {
-
- // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
- // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
- // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
- // 455 1210368 672848 + unsafe anonymous classes
- // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
- // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
- // ...
-
- static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
- static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
-
- public static DummyClassLoader dummyloader;
-
- public static void main(String arg[]) throws Exception {
-
- // 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());
- }
-
- String result = DcmdUtil.executeDcmd("VM.classloader_stats");
- BufferedReader r = new BufferedReader(new StringReader(result));
- String line;
- while((line = r.readLine()) != null) {
- 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);
- }
- checkPositiveInt(m.group(2));
- checkPositiveInt(m.group(3));
-
- String next = r.readLine();
- 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));
- }
- checkPositiveInt(m1.group(2));
- checkPositiveInt(m1.group(3));
- }
- }
- }
- }
-
- private static void checkPositiveInt(String s) throws Exception {
- if (Integer.parseInt(s) <= 0) {
- throw new Exception("Value should have been > 0: " + s);
- }
- }
-
- public static class DummyClassLoader extends ClassLoader {
-
- public static final String CLASS_NAME = "TestClass";
-
- static ByteBuffer readClassFile(String name)
- {
- File f = new File(System.getProperty("test.classes", "."),
- name);
- try (FileInputStream fin = new FileInputStream(f);
- FileChannel fc = fin.getChannel())
- {
- return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
- } catch (IOException e) {
- throw new RuntimeException("Can't open file: " + name, e);
- }
- }
-
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- {
- Class<?> c;
- if (!"TestClass".equals(name)) {
- c = super.loadClass(name, resolve);
- } else {
- // should not delegate to the system class loader
- c = findClass(name);
- if (resolve) {
- resolveClass(c);
- }
- }
- return c;
- }
-
- protected Class<?> findClass(String name)
- throws ClassNotFoundException
- {
- if (!"TestClass".equals(name)) {
- throw new ClassNotFoundException("Unexpected class: " + name);
- }
- return defineClass(name, readClassFile(name + ".class"), null);
- }
- } /* DummyClassLoader */
-
-}
-
-class TestClass {
- static {
- // force creation of anonymous class (for the lambdaform)
- Runnable r = () -> System.out.println("Hello");
- r.run();
- }
-}
--- a/hotspot/test/serviceability/dcmd/DcmdUtil.java Wed Feb 04 17:12:03 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -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();
- }
-
-}
--- a/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Wed Feb 04 17:12:03 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-import java.util.HashSet;
-import java.util.Set;
-import com.oracle.java.testlibrary.Platform;
-
-/*
- * 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
- * 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 VM.dynlib diagnostic command via MBean
- * @library /testlibrary
- * @build com.oracle.java.testlibrary.* DcmdUtil
- * @run main DynLibDcmdTest
- */
-
-public class DynLibDcmdTest {
-
- public static void main(String[] args) throws Exception {
- String result = DcmdUtil.executeDcmd("VM.dynlibs");
-
- String osDependentBaseString = null;
- if (Platform.isAix()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isLinux()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isOSX()) {
- osDependentBaseString = "lib%s.dylib";
- } else if (Platform.isSolaris()) {
- osDependentBaseString = "lib%s.so";
- } else if (Platform.isWindows()) {
- osDependentBaseString = "%s.dll";
- }
-
- if (osDependentBaseString == null) {
- throw new Exception("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"));
-
- for(String expected : expectedContent) {
- if (!result.contains(expected)) {
- throw new Exception("Dynamic library list output did not contain the expected string: '" + expected + "'");
- }
- }
- }
-}
--- a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
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 @@
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 @@
}
// 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 @@
// 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());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 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 @@
}
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 @@
}
}
}
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 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));
-
- String str = r.readLine();
+ OutputAnalyzer output = executor.execute("Compiler.queue");
+ Iterator<String> lines = output.asLines().iterator();
- 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());
+ }
}
--- a/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Thu Feb 05 14:57:52 2015 -0800
@@ -51,11 +51,11 @@
// 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");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 */
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 */
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/thread/PrintTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @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 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.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassLoaderStatsTest {
+
+ // ClassLoader Parent CLD* Classes ChunkSz BlockSz Type
+ // 0x00000007c0215928 0x0000000000000000 0x0000000000000000 0 0 0 org.eclipse.osgi.baseadaptor.BaseAdaptor$1
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52aebcc80 1 6144 3768 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52b8916d0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x00000007c0038ba8 0x00007fc52afb8760 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x00000007c0009868 0x0000000000000000 0x00007fc52afbb1a0 1 6144 3688 sun.reflect.DelegatingClassLoader
+ // 0x0000000000000000 0x0000000000000000 0x00007fc523416070 5019 30060544 29956216 <boot classloader>
+ // 455 1210368 672848 + unsafe anonymous classes
+ // 0x00000007c016b5c8 0x00000007c0038ba8 0x00007fc52a995000 5 8192 5864 org.netbeans.StandardModule$OneModuleClassLoader
+ // 0x00000007c0009868 0x00000007c016b5c8 0x00007fc52ac13640 1 6144 3896 sun.reflect.DelegatingClassLoader
+ // ...
+
+ static Pattern clLine = Pattern.compile("0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*0x\\p{XDigit}*\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*(.*)");
+ static Pattern anonLine = Pattern.compile("\\s*(\\d*)\\s*(\\d*)\\s*(\\d*)\\s*.*");
+
+ public static DummyClassLoader dummyloader;
+
+ 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) {
+ Assert.fail("TestClass defined by wrong classloader: " + c.getClassLoader());
+ }
+
+ 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")) {
+ Assert.fail("Should have loaded 1 class: " + line);
+ }
+ checkPositiveInt(m.group(2));
+ checkPositiveInt(m.group(3));
+
+ String next = lines.next();
+ System.out.println("next: " + next);
+ Matcher m1 = anonLine.matcher(next);
+ m1.matches();
+ if (!m1.group(1).equals("1")) {
+ Assert.fail("Should have loaded 1 anonymous class, but found : " + m1.group(1));
+ }
+ checkPositiveInt(m1.group(2));
+ checkPositiveInt(m1.group(3));
+ }
+ }
+ }
+ }
+
+ private static void checkPositiveInt(String s) {
+ if (Integer.parseInt(s) <= 0) {
+ Assert.fail("Value should have been > 0: " + s);
+ }
+ }
+
+ public static class DummyClassLoader extends ClassLoader {
+
+ public static final String CLASS_NAME = "TestClass";
+
+ static ByteBuffer readClassFile(String name)
+ {
+ File f = new File(System.getProperty("test.classes", "."),
+ name);
+ try (FileInputStream fin = new FileInputStream(f);
+ FileChannel fc = fin.getChannel())
+ {
+ return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ } catch (IOException 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)
+ throws ClassNotFoundException
+ {
+ Class<?> c;
+ if (!"TestClass".equals(name)) {
+ c = super.loadClass(name, resolve);
+ } else {
+ // should not delegate to the system class loader
+ c = findClass(name);
+ if (resolve) {
+ resolveClass(c);
+ }
+ }
+ return c;
+ }
+
+ protected Class<?> findClass(String name)
+ throws ClassNotFoundException
+ {
+ if (!"TestClass".equals(name)) {
+ throw new ClassNotFoundException("Unexpected class: " + name);
+ }
+ return defineClass(name, readClassFile(name + ".class"), null);
+ }
+ } /* DummyClassLoader */
+
+ @Test
+ public void jmx() throws ClassNotFoundException {
+ run(new JMXExecutor());
+ }
+}
+
+class TestClass {
+ static {
+ // force creation of anonymous class (for the lambdaform)
+ Runnable r = () -> System.out.println("Hello");
+ r.run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -0,0 +1,72 @@
+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.
+ * 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 VM.dynlib diagnostic command via MBean
+ * @library /testlibrary
+ * @build com.oracle.java.testlibrary.*
+ * @build com.oracle.java.testlibrary.dcmd.*
+ * @run testng DynLibsTest
+ */
+
+public class DynLibsTest {
+
+ public void run(CommandExecutor executor) {
+ OutputAnalyzer output = executor.execute("VM.dynlibs");
+
+ String osDependentBaseString = null;
+ if (Platform.isAix()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isLinux()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isOSX()) {
+ osDependentBaseString = "lib%s.dylib";
+ } else if (Platform.isSolaris()) {
+ osDependentBaseString = "lib%s.so";
+ } else if (Platform.isWindows()) {
+ osDependentBaseString = "%s.dll";
+ }
+
+ if (osDependentBaseString == null) {
+ Assert.fail("Unsupported OS");
+ }
+
+ output.shouldContain(String.format(osDependentBaseString, "jvm"));
+ output.shouldContain(String.format(osDependentBaseString, "java"));
+ output.shouldContain(String.format(osDependentBaseString, "management"));
+ }
+
+ @Test
+ public void jmx() {
+ run(new JMXExecutor());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java Thu Feb 05 14:57:52 2015 -0800
@@ -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());
+ }
+}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Thu Feb 05 14:57:52 2015 -0800
@@ -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 @@
}
/**
+ * 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 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)"));
+ }
}
--- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Wed Feb 04 17:12:03 2015 +0100
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Thu Feb 05 14:57:52 2015 -0800
@@ -184,23 +184,36 @@
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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutorException.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/FileJcmdExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JMXExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JcmdExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/MainClassJcmdExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/PidJcmdExecutor.java Thu Feb 05 14:57:52 2015 -0800
@@ -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);
+ }
+
+}