# HG changeset patch # User amurillo # Date 1423591771 28800 # Node ID 5b50f9ab11b8178b62298a767a8e83df796443cd # Parent 1550b2f6b63d1411fa84dc7bbc6f04809aedb43f# Parent 759e09099cd72ce9e041a5bd4faf4b388f6dcf23 Merge diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/SymbolTable.java Tue Feb 10 10:09:31 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 { diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/CompactHashTable.java Tue Feb 10 10:09:31 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; + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Tue Feb 10 10:09:31 2015 -0800 @@ -143,7 +143,6 @@ } break; case BarrierSet::ModRef: - case BarrierSet::Other: ShouldNotReachHere(); break; default: diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp Tue Feb 10 10:09:31 2015 -0800 @@ -115,7 +115,6 @@ } break; case BarrierSet::ModRef: - case BarrierSet::Other: ShouldNotReachHere(); break; default : diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/cpu/x86/vm/frame_x86.cpp --- a/hotspot/src/cpu/x86/vm/frame_x86.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp Tue Feb 10 10:09:31 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; } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp Tue Feb 10 10:09:31 2015 -0800 @@ -185,7 +185,6 @@ } break; case BarrierSet::ModRef: - case BarrierSet::Other: if (val == noreg) { __ movptr(obj, NULL_WORD); } else { diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp Tue Feb 10 10:09:31 2015 -0800 @@ -189,7 +189,6 @@ } break; case BarrierSet::ModRef: - case BarrierSet::Other: if (val == noreg) { __ store_heap_oop_null(obj); } else { diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/c1/c1_LIRGenerator.cpp --- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp Tue Feb 10 10:09:31 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 : diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Feb 10 10:09:31 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 { - 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 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); } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/classfile/compactHashtable.hpp --- a/hotspot/src/share/vm/classfile/compactHashtable.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/classfile/compactHashtable.hpp Tue Feb 10 10:09:31 2015 -0800 @@ -188,6 +188,7 @@ // dump time. // template class CompactHashtable VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; uintx _base_address; juint _entry_count; juint _bucket_count; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Feb 10 10:09:31 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(); diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Feb 10 10:09:31 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 = diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp Tue Feb 10 10:09:31 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. } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1HotCardCache.hpp Tue Feb 10 10:09:31 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 { - 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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Tue Feb 10 10:09:31 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); } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Tue Feb 10 10:09:31 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); } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Feb 10 10:09:31 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; } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp Tue Feb 10 10:09:31 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; } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_interface/gcCause.cpp --- a/hotspot/src/share/vm/gc_interface/gcCause.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_interface/gcCause.cpp Tue Feb 10 10:09:31 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"; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/gc_interface/gcCause.hpp --- a/hotspot/src/share/vm/gc_interface/gcCause.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp Tue Feb 10 10:09:31 2015 -0800 @@ -74,6 +74,9 @@ _g1_humongous_allocation, _last_ditch_collection, + + _dcmd_gc_run, + _last_gc_cause }; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/memory/barrierSet.hpp --- a/hotspot/src/share/vm/memory/barrierSet.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/memory/barrierSet.hpp Tue Feb 10 10:09:31 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; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/memory/cardTableModRefBS.cpp --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Tue Feb 10 10:09:31 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"); diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/memory/cardTableModRefBS.hpp --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp Tue Feb 10 10:09:31 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; } }; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/memory/modRefBarrierSet.hpp --- a/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/memory/modRefBarrierSet.hpp Tue Feb 10 10:09:31 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, diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Tue Feb 10 10:09:31 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(); diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Tue Feb 10 10:09:31 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; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/arguments.hpp --- a/hotspot/src/share/vm/runtime/arguments.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/arguments.hpp Tue Feb 10 10:09:31 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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/arguments_ext.hpp --- a/hotspot/src/share/vm/runtime/arguments_ext.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/arguments_ext.hpp Tue Feb 10 10:09:31 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() { diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Tue Feb 10 10:09:31 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); diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/mutexLocker.hpp --- a/hotspot/src/share/vm/runtime/mutexLocker.hpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp Tue Feb 10 10:09:31 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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Tue Feb 10 10:09:31 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 KlassHashtable; typedef HashtableEntry KlassHashtableEntry; typedef TwoOopHashtable SymbolTwoOopHashtable; +typedef CompactHashtable 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) \ diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/src/share/vm/services/diagnosticCommand.cpp --- a/hotspot/src/share/vm/services/diagnosticCommand.cpp Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp Tue Feb 10 10:09:31 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."); } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/TEST.groups Tue Feb 10 10:09:31 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 \ diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/gc/arguments/TestG1PercentageOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/arguments/TestG1PercentageOptions.java Tue Feb 10 10:09:31 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); + } + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/LocalVariableTable/DuplicateLVT.cod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVT.cod Tue Feb 10 10:09:31 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 ""; // #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;"; // #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="; // #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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/LocalVariableTable/DuplicateLVTT.cod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalVariableTable/DuplicateLVTT.cod Tue Feb 10 10:09:31 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 ""; // #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;"; // #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="; // #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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/LocalVariableTable/NotFoundLVTT.cod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalVariableTable/NotFoundLVTT.cod Tue Feb 10 10:09:31 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 ""; // #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;"; // #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="; // #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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/LocalVariableTable/TestLVT.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/LocalVariableTable/TestLVT.java Tue Feb 10 10:09:31 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 list = new ArrayList(); + 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=" + list); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/LocalVariableTable/testcase.jar Binary file hotspot/test/runtime/LocalVariableTable/testcase.jar has changed diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/runtime/Unsafe/AllocateMemory.java --- a/hotspot/test/runtime/Unsafe/AllocateMemory.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/runtime/Unsafe/AllocateMemory.java Tue Feb 10 10:09:31 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; diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/attach/AttachWithStalePidFile.java --- a/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java Tue Feb 10 10:09:31 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 diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java --- a/hotspot/test/serviceability/dcmd/ClassLoaderStatsTest.java Wed Jul 05 20:18:43 2017 +0200 +++ /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 - // 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(); - } -} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/DcmdUtil.java --- a/hotspot/test/serviceability/dcmd/DcmdUtil.java Wed Jul 05 20:18:43 2017 +0200 +++ /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(); - } - -} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/DynLibDcmdTest.java --- a/hotspot/test/serviceability/dcmd/DynLibDcmdTest.java Wed Jul 05 20:18:43 2017 +0200 +++ /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 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 + "'"); - } - } - } -} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java --- a/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/serviceability/dcmd/compiler/CodeCacheTest.java Tue Feb 10 10:09:31 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 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()); + } } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/compiler/CodelistTest.java --- a/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/serviceability/dcmd/compiler/CodelistTest.java Tue Feb 10 10:09:31 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()); + } } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java --- a/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/serviceability/dcmd/compiler/CompilerQueueTest.java Tue Feb 10 10:09:31 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 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()); + } } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java --- a/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/serviceability/dcmd/compiler/MethodIdentifierParser.java Tue Feb 10 10:09:31 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"); } } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/framework/HelpTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/framework/HelpTest.java Tue Feb 10 10:09:31 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()); + } + +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/framework/InvalidCommandTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/framework/VMVersionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/framework/VMVersionTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramAllTest.java Tue Feb 10 10:09:31 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 */ +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/ClassHistogramTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpAllTest.java Tue Feb 10 10:09:31 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 */ +} + diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/HeapDumpTest.java Tue Feb 10 10:09:31 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()); + } +} + diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/RunFinalizationTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/gc/RunGCTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/gc/RunGCTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/thread/PrintConcurrentLocksTest.java Tue Feb 10 10:09:31 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 */ +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/thread/PrintTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/thread/PrintTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/ClassLoaderStatsTest.java Tue Feb 10 10:09:31 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 + // 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 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(); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/CommandLineTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/CommandLineTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/DynLibsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/DynLibsTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/FlagsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/FlagsTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/SystemPropertiesTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/serviceability/dcmd/vm/UptimeTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/serviceability/dcmd/vm/UptimeTest.java Tue Feb 10 10:09:31 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()); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java Tue Feb 10 10:09:31 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 asLines() { + return asLines(getOutput()); + } + + private List asLines(String buffer) { + return Arrays.asList(buffer.split("(\\r\\n|\\n|\\r)")); + } } diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Wed Jul 05 20:18:43 2017 +0200 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java Tue Feb 10 10:09:31 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. diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutor.java Tue Feb 10 10:09:31 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; +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutorException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/CommandExecutorException.java Tue Feb 10 10:09:31 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); + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/FileJcmdExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/FileJcmdExecutor.java Tue Feb 10 10:09:31 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 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); + } + } + +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JMXExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JMXExecutor.java Tue Feb 10 10:09:31 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(); + } + +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JcmdExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/JcmdExecutor.java Tue Feb 10 10:09:31 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 createCommandLine(String cmd) throws CommandExecutorException; + + protected JcmdExecutor() { + jcmdBinary = JDKToolFinder.getJDKTool("jcmd"); + } + + protected OutputAnalyzer executeImpl(String cmd) throws CommandExecutorException { + List 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); + } + } +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/MainClassJcmdExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/MainClassJcmdExecutor.java Tue Feb 10 10:09:31 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 createCommandLine(String cmd) throws CommandExecutorException { + return Arrays.asList(jcmdBinary, mainClass, cmd); + } + +} diff -r 1550b2f6b63d -r 5b50f9ab11b8 hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/PidJcmdExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/dcmd/PidJcmdExecutor.java Tue Feb 10 10:09:31 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 createCommandLine(String cmd) throws CommandExecutorException { + return Arrays.asList(jcmdBinary, Integer.toString(pid), cmd); + } + +}