# HG changeset patch # User twisti # Date 1400862121 25200 # Node ID 3cea99d662dc535a93d8c72c8db061440fcc239a # Parent 14439491d407dba0c80154666305755b5950904f# Parent de383df95d5cd1050109d784f21151fe2c9c99d8 Merge diff -r 14439491d407 -r 3cea99d662dc hotspot/make/excludeSrc.make --- a/hotspot/make/excludeSrc.make Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/make/excludeSrc.make Fri May 23 09:22:01 2014 -0700 @@ -77,30 +77,40 @@ CXXFLAGS += -DINCLUDE_ALL_GCS=0 CFLAGS += -DINCLUDE_ALL_GCS=0 - Src_Files_EXCLUDE += \ - cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \ - cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \ - concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \ - freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp \ - collectionSetChooser.cpp concurrentG1Refine.cpp concurrentG1RefineThread.cpp \ - concurrentMark.cpp concurrentMarkThread.cpp dirtyCardQueue.cpp g1AllocRegion.cpp \ - g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \ - g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \ - g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp g1OopClosures.cpp \ - g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1StringDedup.cpp g1StringDedupStat.cpp \ - g1StringDedupTable.cpp g1StringDedupThread.cpp g1StringDedupQueue.cpp g1_globals.cpp heapRegion.cpp \ - g1BiasedArray.cpp heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \ - ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp g1CodeCacheRemSet.cpp \ - adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \ - cardTableExtension.cpp gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp \ - parallelScavengeHeap.cpp parMarkBitMap.cpp pcTasks.cpp psAdaptiveSizePolicy.cpp \ - psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp psGenerationCounters.cpp \ - psMarkSweep.cpp psMarkSweepDecorator.cpp psMemoryPool.cpp psOldGen.cpp \ - psParallelCompact.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp \ - psTasks.cpp psVirtualspace.cpp psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp \ - parCardTableModRefBS.cpp parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp \ - gSpaceCounters.cpp allocationStats.cpp spaceCounters.cpp gcAdaptivePolicyCounters.cpp \ - mutableNUMASpace.cpp immutableSpace.cpp yieldingWorkGroup.cpp hSpaceCounters.cpp + gc_impl := $(GAMMADIR)/src/share/vm/gc_implementation + gc_exclude := \ + $(notdir $(wildcard $(gc_impl)/concurrentMarkSweep/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/g1/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parallelScavenge/*.cpp)) \ + $(notdir $(wildcard $(gc_impl)/parNew/*.cpp)) + Src_Files_EXCLUDE += $(gc_exclude) + + # Exclude everything in $(gc_impl)/shared except the files listed + # in $(gc_shared_keep). + gc_shared_all := $(notdir $(wildcard $(gc_impl)/shared/*.cpp)) + gc_shared_keep := \ + adaptiveSizePolicy.cpp \ + ageTable.cpp \ + collectorCounters.cpp \ + cSpaceCounters.cpp \ + gcPolicyCounters.cpp \ + gcStats.cpp \ + gcTimer.cpp \ + gcTrace.cpp \ + gcTraceSend.cpp \ + gcTraceTime.cpp \ + gcUtil.cpp \ + generationCounters.cpp \ + markSweep.cpp \ + objectCountEventSender.cpp \ + spaceDecorator.cpp \ + vmGCOperations.cpp + Src_Files_EXCLUDE += $(filter-out $(gc_shared_keep),$(gc_shared_all)) + + # src/share/vm/services + Src_Files_EXCLUDE += \ + g1MemoryPool.cpp \ + psMemoryPool.cpp endif ifeq ($(INCLUDE_NMT), false) diff -r 14439491d407 -r 3cea99d662dc hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp diff -r 14439491d407 -r 3cea99d662dc hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp diff -r 14439491d407 -r 3cea99d662dc hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp diff -r 14439491d407 -r 3cea99d662dc hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Fri May 23 09:22:01 2014 -0700 @@ -5005,7 +5005,11 @@ // wrong; at these points, eax contains the address of the offending block (I think). // To get to the exlicit error message(s) below, just continue twice. HANDLE heap = GetProcessHeap(); - { HeapLock(heap); + + // If we fail to lock the heap, then gflags.exe has been used + // or some other special heap flag has been set that prevents + // locking. We don't try to walk a heap we can't lock. + if (HeapLock(heap) != 0) { PROCESS_HEAP_ENTRY phe; phe.lpData = NULL; while (HeapWalk(heap, &phe) != 0) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri May 23 09:22:01 2014 -0700 @@ -158,6 +158,9 @@ void BCEscapeAnalyzer::set_method_escape(ArgumentMap vars) { clear_bits(vars, _arg_local); + if (vars.contains_allocated()) { + _allocated_escapes = true; + } } void BCEscapeAnalyzer::set_global_escape(ArgumentMap vars, bool merge) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri May 23 09:22:01 2014 -0700 @@ -2805,7 +2805,7 @@ "Short length on BootstrapMethods in class file %s", CHECK); - guarantee_property(attribute_byte_length > sizeof(u2), + guarantee_property(attribute_byte_length >= sizeof(u2), "Invalid BootstrapMethods attribute length %u in class file %s", attribute_byte_length, CHECK); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Fri May 23 09:22:01 2014 -0700 @@ -549,6 +549,8 @@ ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL; ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL; +bool ClassLoaderDataGraph::_should_purge = false; + // Add a new class loader data node to the list. Assign the newly created // ClassLoaderData into the java/lang/ClassLoader object as a hidden field ClassLoaderData* ClassLoaderDataGraph::add(Handle loader, bool is_anonymous, TRAPS) { @@ -675,32 +677,6 @@ return array; } -// For profiling and hsfind() only. Otherwise, this is unsafe (and slow). This -// is done lock free to avoid lock inversion problems. It is safe because -// new ClassLoaderData are added to the end of the CLDG, and only removed at -// safepoint. The _unloading list can be deallocated concurrently with CMS so -// this doesn't look in metaspace for classes that have been unloaded. -bool ClassLoaderDataGraph::contains(const void* x) { - if (DumpSharedSpaces) { - // There are only two metaspaces to worry about. - ClassLoaderData* ncld = ClassLoaderData::the_null_class_loader_data(); - return (ncld->ro_metaspace()->contains(x) || ncld->rw_metaspace()->contains(x)); - } - - if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(x)) { - return true; - } - - for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) { - if (cld->metaspace_or_null() != NULL && cld->metaspace_or_null()->contains(x)) { - return true; - } - } - - // Do not check unloading list because deallocation can be concurrent. - return false; -} - #ifndef PRODUCT bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) { for (ClassLoaderData* data = _head; data != NULL; data = data->next()) { @@ -759,6 +735,7 @@ } void ClassLoaderDataGraph::purge() { + assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint!"); ClassLoaderData* list = _unloading; _unloading = NULL; ClassLoaderData* next = list; diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/classLoaderData.hpp --- a/hotspot/src/share/vm/classfile/classLoaderData.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp Fri May 23 09:22:01 2014 -0700 @@ -66,6 +66,7 @@ static ClassLoaderData* _unloading; // CMS support. static ClassLoaderData* _saved_head; + static bool _should_purge; static ClassLoaderData* add(Handle class_loader, bool anonymous, TRAPS); static void post_class_unload_events(void); @@ -87,12 +88,20 @@ static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); } static GrowableArray* new_clds(); + static void set_should_purge(bool b) { _should_purge = b; } + static void purge_if_needed() { + // Only purge the CLDG for CMS if concurrent sweep is complete. + if (_should_purge) { + purge(); + // reset for next time. + set_should_purge(false); + } + } + static void dump_on(outputStream * const out) PRODUCT_RETURN; static void dump() { dump_on(tty); } static void verify(); - // expensive test for pointer in metaspace for debugging - static bool contains(const void* x); #ifndef PRODUCT static bool contains_loader_data(ClassLoaderData* loader_data); #endif diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/systemDictionary.cpp --- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri May 23 09:22:01 2014 -0700 @@ -604,7 +604,6 @@ Ticks class_load_start_time = Ticks::now(); - // UseNewReflection // Fix for 4474172; see evaluation for more details class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader())); ClassLoaderData *loader_data = register_loader(class_loader, CHECK_NULL); @@ -898,7 +897,6 @@ Handle protection_domain, TRAPS) { - // UseNewReflection // The result of this call should be consistent with the result // of the call to resolve_instance_class_or_null(). // See evaluation 6790209 and 4474172 for more details. diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/systemDictionary.hpp --- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Fri May 23 09:22:01 2014 -0700 @@ -390,7 +390,7 @@ return k; } static Klass* check_klass_Opt_Only_JDK14NewRef(Klass* k) { - assert(JDK_Version::is_gte_jdk14x_version() && UseNewReflection, "JDK 1.4 only"); + assert(JDK_Version::is_gte_jdk14x_version(), "JDK 1.4 only"); // despite the optional loading, if you use this it must be present: return check_klass(k); } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri May 23 09:22:01 2014 -0700 @@ -211,9 +211,9 @@ // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. // NOTE: this is called too early in the bootstrapping process to be - // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. + // guarded by Universe::is_gte_jdk14x_version(). // Also for lambda generated code, gte jdk8 - (!is_reflect || VerifyReflectionBytecodes)); + (!is_reflect)); } Symbol* Verifier::inference_verify( diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/compiler/disassembler.cpp --- a/hotspot/src/share/vm/compiler/disassembler.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/compiler/disassembler.cpp Fri May 23 09:22:01 2014 -0700 @@ -86,7 +86,7 @@ { // Match "jvm[^/]*" in jvm_path. const char* base = buf; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) lib_offset = p - base + 1; p = strstr(p ? p : base, "jvm"); if (p != NULL) jvm_offset = p - base; @@ -111,7 +111,7 @@ if (_library == NULL) { // 3. /jre/lib//hsdis-.so buf[lib_offset - 1] = '\0'; - const char* p = strrchr(buf, '/'); + const char* p = strrchr(buf, *os::file_separator()); if (p != NULL) { lib_offset = p - buf + 1; strcpy(&buf[lib_offset], hsdis_library_name); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri May 23 09:22:01 2014 -0700 @@ -6362,7 +6362,9 @@ verify_overflow_empty(); if (should_unload_classes()) { - ClassLoaderDataGraph::purge(); + // Delay purge to the beginning of the next safepoint. Metaspace::contains + // requires that the virtual spaces are stable and not deleted. + ClassLoaderDataGraph::set_should_purge(true); } _intra_sweep_timer.stop(); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri May 23 09:22:01 2014 -0700 @@ -820,7 +820,7 @@ // false before we start remark. At this point we should also be // in a STW phase. assert(!concurrent_marking_in_progress(), "invariant"); - assert(_finger == _heap_end, + assert(out_of_regions(), err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, p2i(_finger), p2i(_heap_end))); update_g1_committed(true); @@ -979,7 +979,9 @@ if (concurrent()) { SuspendibleThreadSet::leave(); } - _first_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_first_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } @@ -987,7 +989,17 @@ // more work if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted first barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving first barrier", worker_id); + } + } + + if (barrier_aborted) { + // If the barrier aborted we ignore the overflow condition and + // just abort the whole marking phase as quickly as possible. + return; } // If we're executing the concurrent phase of marking, reset the marking @@ -1027,14 +1039,20 @@ if (concurrent()) { SuspendibleThreadSet::leave(); } - _second_overflow_barrier_sync.enter(); + + bool barrier_aborted = !_second_overflow_barrier_sync.enter(); + if (concurrent()) { SuspendibleThreadSet::join(); } // at this point everything should be re-initialized and ready to go if (verbose_low()) { - gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + if (barrier_aborted) { + gclog_or_tty->print_cr("[%u] aborted second barrier", worker_id); + } else { + gclog_or_tty->print_cr("[%u] leaving second barrier", worker_id); + } } } @@ -3241,6 +3259,8 @@ for (uint i = 0; i < _max_worker_id; ++i) { _tasks[i]->clear_region_fields(); } + _first_overflow_barrier_sync.abort(); + _second_overflow_barrier_sync.abort(); _has_aborted = true; SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp Fri May 23 09:22:01 2014 -0700 @@ -542,8 +542,12 @@ // frequently. HeapRegion* claim_region(uint worker_id); - // It determines whether we've run out of regions to scan - bool out_of_regions() { return _finger == _heap_end; } + // It determines whether we've run out of regions to scan. Note that + // the finger can point past the heap end in case the heap was expanded + // to satisfy an allocation without doing a GC. This is fine, because all + // objects in those regions will be considered live anyway because of + // SATB guarantees (i.e. their TAMS will be equal to bottom). + bool out_of_regions() { return _finger >= _heap_end; } // Returns the task with the given id CMTask* task(int id) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri May 23 09:22:01 2014 -0700 @@ -5402,7 +5402,7 @@ if (_g1h->is_in_g1_reserved(p)) { _par_scan_state->push_on_queue(p); } else { - assert(!ClassLoaderDataGraph::contains((address)p), + assert(!Metaspace::contains((const void*)p), err_msg("Otherwise need to call _copy_metadata_obj_cl->do_oop(p) " PTR_FORMAT, p)); _copy_non_heap_obj_cl->do_oop(p); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Fri May 23 09:22:01 2014 -0700 @@ -96,7 +96,15 @@ jbyte *const first = byte_for(mr.start()); jbyte *const last = byte_after(mr.last()); - memset(first, g1_young_gen, last - first); + // Below we may use an explicit loop instead of memset() because on + // certain platforms memset() can give concurrent readers phantom zeros. + if (UseMemSetInBOT) { + memset(first, g1_young_gen, last - first); + } else { + for (jbyte* i = first; i < last; i++) { + *i = g1_young_gen; + } + } } #ifndef PRODUCT diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -194,23 +194,16 @@ } bool RSHashTable::get_cards(RegionIdx_t region_ind, CardIdx_t* cards) { - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); + SparsePRTEntry* entry = get_entry(region_ind); + if (entry == NULL) { + return false; } - - if (cur_ind == NullEntry) return false; // Otherwise... - assert(cur->r_ind() == region_ind, "Postcondition of loop + test above."); - assert(cur->num_valid_cards() > 0, "Inv"); - cur->copy_cards(cards); + entry->copy_cards(cards); return true; } -SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) { +SparsePRTEntry* RSHashTable::get_entry(RegionIdx_t region_ind) const { int ind = (int) (region_ind & capacity_mask()); int cur_ind = _buckets[ind]; SparsePRTEntry* cur; @@ -247,27 +240,8 @@ } SparsePRTEntry* -RSHashTable::entry_for_region_ind(RegionIdx_t region_ind) const { - assert(occupied_entries() < capacity(), "Precondition"); - int ind = (int) (region_ind & capacity_mask()); - int cur_ind = _buckets[ind]; - SparsePRTEntry* cur; - while (cur_ind != NullEntry && - (cur = entry(cur_ind))->r_ind() != region_ind) { - cur_ind = cur->next_index(); - } - - if (cur_ind != NullEntry) { - assert(cur->r_ind() == region_ind, "Loop postcondition + test"); - return cur; - } else { - return NULL; - } -} - -SparsePRTEntry* RSHashTable::entry_for_region_ind_create(RegionIdx_t region_ind) { - SparsePRTEntry* res = entry_for_region_ind(region_ind); + SparsePRTEntry* res = get_entry(region_ind); if (res == NULL) { int new_ind = alloc_entry(); assert(0 <= new_ind && (size_t)new_ind < capacity(), "There should be room."); @@ -365,7 +339,7 @@ } bool RSHashTable::contains_card(RegionIdx_t region_index, CardIdx_t card_index) const { - SparsePRTEntry* e = entry_for_region_ind(region_index); + SparsePRTEntry* e = get_entry(region_index); return (e != NULL && e->contains_card(card_index)); } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -122,12 +122,6 @@ // Requires that the caller hold a lock preventing parallel modifying // operations, and that the the table be less than completely full. If // an entry for "region_ind" is already in the table, finds it and - // returns its address; otherwise returns "NULL." - SparsePRTEntry* entry_for_region_ind(RegionIdx_t region_ind) const; - - // Requires that the caller hold a lock preventing parallel modifying - // operations, and that the the table be less than completely full. If - // an entry for "region_ind" is already in the table, finds it and // returns its address; otherwise allocates, initializes, inserts and // returns a new entry for "region_ind". SparsePRTEntry* entry_for_region_ind_create(RegionIdx_t region_ind); @@ -158,7 +152,7 @@ void add_entry(SparsePRTEntry* e); - SparsePRTEntry* get_entry(RegionIdx_t region_id); + SparsePRTEntry* get_entry(RegionIdx_t region_id) const; void clear(); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/interpreter/linkResolver.cpp --- a/hotspot/src/share/vm/interpreter/linkResolver.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp Fri May 23 09:22:01 2014 -0700 @@ -950,7 +950,6 @@ // reflection implementation, not just those associated with // sun/reflect/SerializationConstructorAccessor. bool is_reflect = JDK_Version::is_gte_jdk14x_version() && - UseNewReflection && klass_to_check->is_subclass_of( SystemDictionary::reflect_MagicAccessorImpl_klass()); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/memory/allocation.cpp --- a/hotspot/src/share/vm/memory/allocation.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/memory/allocation.cpp Fri May 23 09:22:01 2014 -0700 @@ -75,7 +75,7 @@ } bool MetaspaceObj::is_metaspace_object() const { - return ClassLoaderDataGraph::contains((void*)this); + return Metaspace::contains((void*)this); } void MetaspaceObj::print_address_on(outputStream* st) const { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Fri May 23 09:22:01 2014 -0700 @@ -316,6 +316,8 @@ MetaWord* bottom() const { return (MetaWord*) _virtual_space.low(); } MetaWord* end() const { return (MetaWord*) _virtual_space.high(); } + bool contains(const void* ptr) { return ptr >= low() && ptr < high(); } + size_t reserved_words() const { return _virtual_space.reserved_size() / BytesPerWord; } size_t committed_words() const { return _virtual_space.actual_committed_size() / BytesPerWord; } @@ -557,6 +559,8 @@ void inc_virtual_space_count(); void dec_virtual_space_count(); + bool contains(const void* ptr); + // Unlink empty VirtualSpaceNodes and free it. void purge(ChunkManager* chunk_manager); @@ -641,8 +645,6 @@ // Accessors Metachunk* chunks_in_use(ChunkIndex index) const { return _chunks_in_use[index]; } void set_chunks_in_use(ChunkIndex index, Metachunk* v) { - // ensure lock-free iteration sees fully initialized node - OrderAccess::storestore(); _chunks_in_use[index] = v; } @@ -757,8 +759,6 @@ void print_on(outputStream* st) const; void locked_print_chunks_in_use_on(outputStream* st) const; - bool contains(const void *ptr); - void verify(); void verify_chunk_size(Metachunk* chunk); NOT_PRODUCT(void mangle_freed_chunks();) @@ -1078,6 +1078,7 @@ // nodes with a 0 container_count. Remove Metachunks in // the node from their respective freelists. void VirtualSpaceList::purge(ChunkManager* chunk_manager) { + assert(SafepointSynchronize::is_at_safepoint(), "must be called at safepoint for contains to work"); assert_lock_strong(SpaceManager::expand_lock()); // Don't use a VirtualSpaceListIterator because this // list is being changed and a straightforward use of an iterator is not safe. @@ -1111,8 +1112,8 @@ } #ifdef ASSERT if (purged_vsl != NULL) { - // List should be stable enough to use an iterator here. - VirtualSpaceListIterator iter(virtual_space_list()); + // List should be stable enough to use an iterator here. + VirtualSpaceListIterator iter(virtual_space_list()); while (iter.repeat()) { VirtualSpaceNode* vsl = iter.get_next(); assert(vsl != purged_vsl, "Purge of vsl failed"); @@ -1121,6 +1122,23 @@ #endif } + +// This function looks at the mmap regions in the metaspace without locking. +// The chunks are added with store ordering and not deleted except for at +// unloading time during a safepoint. +bool VirtualSpaceList::contains(const void* ptr) { + // List should be stable enough to use an iterator here because removing virtual + // space nodes is only allowed at a safepoint. + VirtualSpaceListIterator iter(virtual_space_list()); + while (iter.repeat()) { + VirtualSpaceNode* vsn = iter.get_next(); + if (vsn->contains(ptr)) { + return true; + } + } + return false; +} + void VirtualSpaceList::retire_current_virtual_space() { assert_lock_strong(SpaceManager::expand_lock()); @@ -1210,6 +1228,8 @@ } else { assert(new_entry->reserved_words() == vs_word_size, "Reserved memory size differs from requested memory size"); + // ensure lock-free iteration sees fully initialized node + OrderAccess::storestore(); link_vs(new_entry); return true; } @@ -2434,21 +2454,6 @@ return result; } -// This function looks at the chunks in the metaspace without locking. -// The chunks are added with store ordering and not deleted except for at -// unloading time. -bool SpaceManager::contains(const void *ptr) { - for (ChunkIndex i = ZeroIndex; i < NumberOfInUseLists; i = next_chunk_index(i)) - { - Metachunk* curr = chunks_in_use(i); - while (curr != NULL) { - if (curr->contains(ptr)) return true; - curr = curr->next(); - } - } - return false; -} - void SpaceManager::verify() { // If there are blocks in the dictionary, then // verification of chunks does not work since @@ -3538,11 +3543,15 @@ } bool Metaspace::contains(const void* ptr) { - if (vsm()->contains(ptr)) return true; - if (using_class_space()) { - return class_vsm()->contains(ptr); + if (UseSharedSpaces && MetaspaceShared::is_in_shared_space(ptr)) { + return true; } - return false; + + if (using_class_space() && get_space_list(ClassType)->contains(ptr)) { + return true; + } + + return get_space_list(NonClassType)->contains(ptr); } void Metaspace::verify() { @@ -3787,5 +3796,4 @@ TestVirtualSpaceNodeTest::test(); TestVirtualSpaceNodeTest::test_is_available(); } - #endif diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/memory/metaspace.hpp --- a/hotspot/src/share/vm/memory/metaspace.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/memory/metaspace.hpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -232,7 +232,8 @@ MetaWord* expand_and_allocate(size_t size, MetadataType mdtype); - bool contains(const void* ptr); + static bool contains(const void* ptr); + void dump(outputStream* const out) const; // Free empty virtualspaces diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/oops/cpCache.cpp --- a/hotspot/src/share/vm/oops/cpCache.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/oops/cpCache.cpp Fri May 23 09:22:01 2014 -0700 @@ -498,9 +498,10 @@ // _f1 == NULL || !_f1->is_method() are OK here return true; } - // return false if _f1 refers to an old or an obsolete method + // return false if _f1 refers to a non-deleted old or obsolete method return (NOT_PRODUCT(_f1->is_valid() &&) _f1->is_method() && - !((Method*)_f1)->is_old() && !((Method*)_f1)->is_obsolete()); + (f1_as_method()->is_deleted() || + (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete()))); } bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/oops/klass.cpp --- a/hotspot/src/share/vm/oops/klass.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/oops/klass.cpp Fri May 23 09:22:01 2014 -0700 @@ -640,7 +640,7 @@ // This can be expensive, but it is worth checking that this klass is actually // in the CLD graph but not in production. - assert(ClassLoaderDataGraph::contains((address)this), "Should be"); + assert(Metaspace::contains((address)this), "Should be"); guarantee(this->is_klass(),"should be klass"); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/oops/method.cpp --- a/hotspot/src/share/vm/oops/method.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/oops/method.cpp Fri May 23 09:22:01 2014 -0700 @@ -1019,13 +1019,11 @@ * security related stack walks (like Reflection.getCallerClass). */ bool Method::is_ignored_by_security_stack_walk() const { - const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true; } - if (use_new_reflection && + if (JDK_Version::is_gte_jdk14x_version() && method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { // This is an auxilary frame -- ignore it return true; @@ -1868,6 +1866,14 @@ loader_data->jmethod_ids()->clear_all_methods(); } +bool Method::has_method_vptr(const void* ptr) { + Method m; + // This assumes that the vtbl pointer is the first word of a C++ object. + // This assumption is also in universe.cpp patch_klass_vtble + void* vtbl2 = dereference_vptr((const void*)&m); + void* this_vtbl = dereference_vptr(ptr); + return vtbl2 == this_vtbl; +} // Check that this pointer is valid by checking that the vtbl pointer matches bool Method::is_valid_method() const { @@ -1876,12 +1882,7 @@ } else if (!is_metaspace_object()) { return false; } else { - Method m; - // This assumes that the vtbl pointer is the first word of a C++ object. - // This assumption is also in universe.cpp patch_klass_vtble - void* vtbl2 = dereference_vptr((void*)&m); - void* this_vtbl = dereference_vptr((void*)this); - return vtbl2 == this_vtbl; + return has_method_vptr((const void*)this); } } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/oops/method.hpp --- a/hotspot/src/share/vm/oops/method.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/oops/method.hpp Fri May 23 09:22:01 2014 -0700 @@ -684,6 +684,8 @@ void set_is_old() { _access_flags.set_is_old(); } bool is_obsolete() const { return access_flags().is_obsolete(); } void set_is_obsolete() { _access_flags.set_is_obsolete(); } + bool is_deleted() const { return access_flags().is_deleted(); } + void set_is_deleted() { _access_flags.set_is_deleted(); } bool on_stack() const { return access_flags().on_stack(); } void set_on_stack(const bool value); @@ -876,6 +878,7 @@ const char* internal_name() const { return "{method}"; } // Check for valid method pointer + static bool has_method_vptr(const void* ptr); bool is_valid_method() const; // Verify diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/opto/library_call.cpp --- a/hotspot/src/share/vm/opto/library_call.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/opto/library_call.cpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -420,7 +420,6 @@ return NULL; case vmIntrinsics::_getCallerClass: - if (!UseNewReflection) return NULL; if (!InlineReflectionGetCallerClass) return NULL; if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) return NULL; break; diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/prims/jni.cpp Fri May 23 09:22:01 2014 -0700 @@ -544,7 +544,7 @@ if (m->is_initializer()) { reflection_method = Reflection::new_constructor(m, CHECK_NULL); } else { - reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL); + reflection_method = Reflection::new_method(m, false, CHECK_NULL); } ret = JNIHandles::make_local(env, reflection_method); return ret; @@ -2272,7 +2272,7 @@ found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd); } assert(found, "bad fieldID passed into jni_ToReflectedField"); - oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop reflected = Reflection::new_field(&fd, CHECK_NULL); ret = JNIHandles::make_local(env, reflected); return ret; JNI_END diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/prims/jvm.cpp Fri May 23 09:22:01 2014 -0700 @@ -1854,7 +1854,7 @@ if (!publicOnly || fs.access_flags().is_public()) { fd.reinitialize(k(), fs.index()); - oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); result->obj_at_put(out_idx, field); ++out_idx; } @@ -1932,7 +1932,7 @@ if (want_constructor) { m = Reflection::new_constructor(method, CHECK_NULL); } else { - m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); + m = Reflection::new_method(method, false, CHECK_NULL); } result->obj_at_put(i, m); } @@ -2055,7 +2055,7 @@ } oop method; if (!m->is_initializer() || m->is_static()) { - method = Reflection::new_method(m, true, true, CHECK_NULL); + method = Reflection::new_method(m, true, CHECK_NULL); } else { method = Reflection::new_constructor(m, CHECK_NULL); } @@ -2105,7 +2105,7 @@ if (target_klass == NULL) { THROW_MSG_0(vmSymbols::java_lang_RuntimeException(), "Unable to look up field in target class"); } - oop field = Reflection::new_field(&fd, true, CHECK_NULL); + oop field = Reflection::new_field(&fd, CHECK_NULL); return JNIHandles::make_local(field); } @@ -3521,7 +3521,6 @@ JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { - // UseNewReflection vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection oop loader = vfst.method()->method_holder()->class_loader(); if (loader != NULL) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri May 23 09:22:01 2014 -0700 @@ -2970,7 +2970,8 @@ assert(!old_method->has_vtable_index(), "cannot delete methods with vtable entries");; - // Mark all deleted methods as old and obsolete + // Mark all deleted methods as old, obsolete and deleted + old_method->set_is_deleted(); old_method->set_is_old(); old_method->set_is_obsolete(); ++obsolete_count; @@ -3576,7 +3577,7 @@ no_old_methods = false; } - // the constant pool cache should never contain old or obsolete methods + // the constant pool cache should never contain non-deleted old or obsolete methods if (ik->constants() != NULL && ik->constants()->cache() != NULL && !ik->constants()->cache()->check_no_old_or_obsolete_entries()) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri May 23 09:22:01 2014 -0700 @@ -312,6 +312,9 @@ { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "BackEdgeThreshold", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "UseNewReflection", JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "ReflectionWrapResolutionErrors",JDK_Version::jdk(9), JDK_Version::jdk(10) }, + { "VerifyReflectionBytecodes", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { NULL, JDK_Version(0), JDK_Version(0) } }; @@ -581,11 +584,20 @@ // Parses a memory size specification string. static bool atomull(const char *s, julong* result) { julong n = 0; - int args_read = sscanf(s, JULONG_FORMAT, &n); + int args_read = 0; + bool is_hex = false; + // Skip leading 0[xX] for hexadecimal + if (*s =='0' && (*(s+1) == 'x' || *(s+1) == 'X')) { + s += 2; + is_hex = true; + args_read = sscanf(s, JULONG_FORMAT_X, &n); + } else { + args_read = sscanf(s, JULONG_FORMAT, &n); + } if (args_read != 1) { return false; } - while (*s != '\0' && isdigit(*s)) { + while (*s != '\0' && (isdigit(*s) || (is_hex && isxdigit(*s)))) { s++; } // 4705540: illegal if more characters are found after the first non-digit @@ -779,7 +791,7 @@ } } -#define VALUE_RANGE "[-kmgtKMGT0123456789]" +#define VALUE_RANGE "[-kmgtxKMGTX0123456789abcdefABCDEF]" if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) VALUE_RANGE "%c", name, value, &dummy) == 2) { return set_numeric_flag(name, value, origin); } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri May 23 09:22:01 2014 -0700 @@ -3656,22 +3656,6 @@ \ /* New JDK 1.4 reflection implementation */ \ \ - develop(bool, UseNewReflection, true, \ - "Temporary flag for transition to reflection based on dynamic " \ - "bytecode generation in 1.4; can no longer be turned off in 1.4 " \ - "JDK, and is unneeded in 1.3 JDK, but marks most places VM " \ - "changes were needed") \ - \ - develop(bool, VerifyReflectionBytecodes, false, \ - "Force verification of 1.4 reflection bytecodes. Does not work " \ - "in situations like that described in 4486457 or for " \ - "constructors generated for serialization, so can not be enabled "\ - "in product.") \ - \ - product(bool, ReflectionWrapResolutionErrors, true, \ - "Temporary flag for transition to AbstractMethodError wrapped " \ - "in InvocationTargetException. See 6531596") \ - \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ \ diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/os.cpp Fri May 23 09:22:01 2014 -0700 @@ -1097,11 +1097,15 @@ } - // Check if in metaspace. - if (ClassLoaderDataGraph::contains((address)addr)) { - // Use addr->print() from the debugger instead (not here) - st->print_cr(INTPTR_FORMAT - " is pointing into metadata", addr); + // Check if in metaspace and print types that have vptrs (only method now) + if (Metaspace::contains(addr)) { + if (Method::has_method_vptr((const void*)addr)) { + ((Method*)addr)->print_value_on(st); + st->cr(); + } else { + // Use addr->print() from the debugger instead (not here) + st->print_cr(INTPTR_FORMAT " is pointing into metadata", addr); + } return; } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/reflection.cpp --- a/hotspot/src/share/vm/runtime/reflection.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/reflection.cpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -466,7 +466,6 @@ // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -571,7 +570,6 @@ // New (1.4) reflection implementation. Allow all accesses from // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. if ( JDK_Version::is_gte_jdk14x_version() - && UseNewReflection && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { return true; } @@ -708,7 +706,7 @@ } -oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { +oop Reflection::new_method(methodHandle method, bool for_constant_pool_access, TRAPS) { // In jdk1.2.x, getMethods on an interface erroneously includes , thus the complicated assert. // Also allow sun.reflect.ConstantPool to refer to methods as java.lang.reflect.Methods. assert(!method()->is_initializer() || @@ -731,14 +729,8 @@ if (exception_types.is_null()) return NULL; Symbol* method_name = method->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(method_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(method_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); if (name == NULL) return NULL; int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; @@ -825,16 +817,10 @@ } -oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { +oop Reflection::new_field(fieldDescriptor* fd, TRAPS) { Symbol* field_name = fd->name(); - Handle name; - if (intern_name) { - // intern_name is only true with UseNewReflection - oop name_oop = StringTable::intern(field_name, CHECK_NULL); - name = Handle(THREAD, name_oop); - } else { - name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); - } + oop name_oop = StringTable::intern(field_name, CHECK_NULL); + Handle name = Handle(THREAD, name_oop); Symbol* signature = fd->signature(); instanceKlassHandle holder (THREAD, fd->field_holder()); Handle type = new_type(signature, holder, CHECK_NULL); @@ -933,27 +919,23 @@ // resolve based on the receiver if (reflected_method->method_holder()->is_interface()) { // resolve interface call - if (ReflectionWrapResolutionErrors) { - // new default: 6531596 - // Match resolution errors with those thrown due to reflection inlining - // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); - if (HAS_PENDING_EXCEPTION) { - // Method resolution threw an exception; wrap it in an InvocationTargetException - oop resolution_exception = PENDING_EXCEPTION; - CLEAR_PENDING_EXCEPTION; - // JVMTI has already reported the pending exception - // JVMTI internal flag reset is needed in order to report InvocationTargetException - if (THREAD->is_Java_thread()) { - JvmtiExport::clear_detected_exception((JavaThread*) THREAD); - } - JavaCallArguments args(Handle(THREAD, resolution_exception)); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); + // + // Match resolution errors with those thrown due to reflection inlining + // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() + method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); + if (HAS_PENDING_EXCEPTION) { + // Method resolution threw an exception; wrap it in an InvocationTargetException + oop resolution_exception = PENDING_EXCEPTION; + CLEAR_PENDING_EXCEPTION; + // JVMTI has already reported the pending exception + // JVMTI internal flag reset is needed in order to report InvocationTargetException + if (THREAD->is_Java_thread()) { + JvmtiExport::clear_detected_exception((JavaThread*) THREAD); } - } else { - method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); + JavaCallArguments args(Handle(THREAD, resolution_exception)); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } else { // if the method can be overridden, we resolve using the vtable index. @@ -970,24 +952,16 @@ // Check for abstract methods as well if (method->is_abstract()) { // new default: 6531596 - if (ReflectionWrapResolutionErrors) { - ResourceMark rm(THREAD); - Handle h_origexception = Exceptions::new_exception(THREAD, - vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - JavaCallArguments args(h_origexception); - THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), - vmSymbols::throwable_void_signature(), - &args); - } else { - ResourceMark rm(THREAD); - THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), - Method::name_and_sig_as_C_string(target_klass(), - method->name(), - method->signature())); - } + ResourceMark rm(THREAD); + Handle h_origexception = Exceptions::new_exception(THREAD, + vmSymbols::java_lang_AbstractMethodError(), + Method::name_and_sig_as_C_string(target_klass(), + method->name(), + method->signature())); + JavaCallArguments args(h_origexception); + THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), + vmSymbols::throwable_void_signature(), + &args); } } } @@ -1006,7 +980,7 @@ // In the JDK 1.4 reflection implementation, the security check is // done at the Java level - if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { + if (!JDK_Version::is_gte_jdk14x_version()) { // Access checking (unless overridden by Method) if (!override) { @@ -1018,7 +992,7 @@ } } - } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) + } // !Universe::is_gte_jdk14x_version() assert(ptypes->is_objArray(), "just checking"); int args_len = args.is_null() ? 0 : args->length(); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/reflection.hpp --- a/hotspot/src/share/vm/runtime/reflection.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/reflection.hpp Fri May 23 09:22:01 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -113,11 +113,11 @@ // // Create a java.lang.reflect.Method object based on a method - static oop new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS); + static oop new_method(methodHandle method, bool for_constant_pool_access, TRAPS); // Create a java.lang.reflect.Constructor object based on a method static oop new_constructor(methodHandle method, TRAPS); // Create a java.lang.reflect.Field object based on a field descriptor - static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS); + static oop new_field(fieldDescriptor* fd, TRAPS); // Create a java.lang.reflect.Parameter object based on a // MethodParameterElement static oop new_parameter(Handle method, int index, Symbol* sym, diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/safepoint.cpp --- a/hotspot/src/share/vm/runtime/safepoint.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/safepoint.cpp Fri May 23 09:22:01 2014 -0700 @@ -541,6 +541,13 @@ gclog_or_tty->rotate_log(false); } + { + // CMS delays purging the CLDG until the beginning of the next safepoint and to + // make sure concurrent sweep is done + TraceTime t7("purging class loader data graph", TraceSafepointCleanupTime); + ClassLoaderDataGraph::purge_if_needed(); + } + if (MemTracker::is_on()) { MemTracker::sync(); } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/sharedRuntime.cpp diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/sharedRuntime.hpp diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/runtime/vframe.cpp --- a/hotspot/src/share/vm/runtime/vframe.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/runtime/vframe.cpp Fri May 23 09:22:01 2014 -0700 @@ -473,7 +473,7 @@ void vframeStreamCommon::skip_reflection_related_frames() { while (!at_end() && - (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && + (JDK_Version::is_gte_jdk14x_version() && (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { next(); diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/trace/traceStream.hpp --- a/hotspot/src/share/vm/trace/traceStream.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/trace/traceStream.hpp Fri May 23 09:22:01 2014 -0700 @@ -66,7 +66,7 @@ } void print_val(const char* label, s8 val) { - _st.print("%s = "INT64_FORMAT, label, val); + _st.print("%s = "INT64_FORMAT, label, (int64_t) val); } void print_val(const char* label, bool val) { diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/utilities/accessFlags.hpp --- a/hotspot/src/share/vm/utilities/accessFlags.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/utilities/accessFlags.hpp Fri May 23 09:22:01 2014 -0700 @@ -54,7 +54,8 @@ JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete JVM_ACC_IS_PREFIXED_NATIVE = 0x00040000, // JVMTI has prefixed this native method - JVM_ACC_ON_STACK = 0x00080000, // RedefinedClasses() is used on the stack + JVM_ACC_ON_STACK = 0x00080000, // RedefineClasses() was used on the stack + JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method // Klass* flags JVM_ACC_HAS_MIRANDA_METHODS = 0x10000000, // True if this class has miranda methods in it's vtable @@ -131,6 +132,7 @@ bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; } bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; } bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; } + bool is_deleted () const { return (_flags & JVM_ACC_IS_DELETED ) != 0; } bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; } // Klass* flags @@ -195,6 +197,7 @@ void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); } void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); } void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); } + void set_is_deleted() { atomic_set_bits(JVM_ACC_IS_DELETED); } void set_is_prefixed_native() { atomic_set_bits(JVM_ACC_IS_PREFIXED_NATIVE); } void clear_not_c1_compilable() { atomic_clear_bits(JVM_ACC_NOT_C1_COMPILABLE); } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/utilities/globalDefinitions.hpp --- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Fri May 23 09:22:01 2014 -0700 @@ -1346,6 +1346,9 @@ #ifndef JULONG_FORMAT #define JULONG_FORMAT UINT64_FORMAT #endif +#ifndef JULONG_FORMAT_X +#define JULONG_FORMAT_X UINT64_FORMAT_X +#endif // Format pointers which change size between 32- and 64-bit. #ifdef _LP64 @@ -1385,7 +1388,7 @@ // All C++ compilers that we know of have the vtbl pointer in the first // word. If there are exceptions, this function needs to be made compiler // specific. -static inline void* dereference_vptr(void* addr) { +static inline void* dereference_vptr(const void* addr) { return *(void**)addr; } diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/utilities/workgroup.cpp --- a/hotspot/src/share/vm/utilities/workgroup.cpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/utilities/workgroup.cpp Fri May 23 09:22:01 2014 -0700 @@ -378,21 +378,22 @@ WorkGangBarrierSync::WorkGangBarrierSync() : _monitor(Mutex::safepoint, "work gang barrier sync", true), - _n_workers(0), _n_completed(0), _should_reset(false) { + _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) { } WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name) : _monitor(Mutex::safepoint, name, true), - _n_workers(n_workers), _n_completed(0), _should_reset(false) { + _n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) { } void WorkGangBarrierSync::set_n_workers(uint n_workers) { - _n_workers = n_workers; - _n_completed = 0; + _n_workers = n_workers; + _n_completed = 0; _should_reset = false; + _aborted = false; } -void WorkGangBarrierSync::enter() { +bool WorkGangBarrierSync::enter() { MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); if (should_reset()) { // The should_reset() was set and we are the first worker to enter @@ -415,10 +416,17 @@ set_should_reset(true); monitor()->notify_all(); } else { - while (n_completed() != n_workers()) { + while (n_completed() != n_workers() && !aborted()) { monitor()->wait(/* no_safepoint_check */ true); } } + return !aborted(); +} + +void WorkGangBarrierSync::abort() { + MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag); + set_aborted(); + monitor()->notify_all(); } // SubTasksDone functions. diff -r 14439491d407 -r 3cea99d662dc hotspot/src/share/vm/utilities/workgroup.hpp --- a/hotspot/src/share/vm/utilities/workgroup.hpp Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/src/share/vm/utilities/workgroup.hpp Fri May 23 09:22:01 2014 -0700 @@ -359,18 +359,20 @@ class WorkGangBarrierSync : public StackObj { protected: Monitor _monitor; - uint _n_workers; - uint _n_completed; + uint _n_workers; + uint _n_completed; bool _should_reset; + bool _aborted; Monitor* monitor() { return &_monitor; } uint n_workers() { return _n_workers; } uint n_completed() { return _n_completed; } bool should_reset() { return _should_reset; } + bool aborted() { return _aborted; } void zero_completed() { _n_completed = 0; } void inc_completed() { _n_completed++; } - + void set_aborted() { _aborted = true; } void set_should_reset(bool v) { _should_reset = v; } public: @@ -383,8 +385,14 @@ // Enter the barrier. A worker that enters the barrier will // not be allowed to leave until all other threads have - // also entered the barrier. - void enter(); + // also entered the barrier or the barrier is aborted. + // Returns false if the barrier was aborted. + bool enter(); + + // Aborts the barrier and wakes up any threads waiting for + // the barrier to complete. The barrier will remain in the + // aborted state until the next call to set_n_workers(). + void abort(); }; // A class to manage claiming of subtasks within a group of tasks. The diff -r 14439491d407 -r 3cea99d662dc hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/EscapeAnalysis/TestAllocatedEscapesPtrComparison.java Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,107 @@ +/* + * Copyright 2014 Google, Inc. 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 8043354 + * @summary bcEscapeAnalyzer allocated_escapes not conservative enough + * @run main/othervm -XX:CompileOnly=.visitAndPop TestAllocatedEscapesPtrComparison + * @author Chuck Rasbold rasbold@google.com + */ + +/* + * Test always passes with -XX:-OptmimizePtrCompare + */ + +import java.util.ArrayList; +import java.util.List; + +public class TestAllocatedEscapesPtrComparison { + + static TestAllocatedEscapesPtrComparison dummy; + + class Marker { + } + + List markerList = new ArrayList<>(); + + // Suppress compilation of this method, it must be processed + // by the bytecode escape analyzer. + + // Make a new marker and put it on the List + Marker getMarker() { + // result escapes through markerList + final Marker result = new Marker(); + markerList.add(result); + return result; + } + + void visit(int depth) { + // Make a new marker + getMarker(); + + // Call visitAndPop every once in a while + // Cap the depth of our recursive visits + if (depth % 10 == 2) { + visitAndPop(depth + 1); + } else if (depth < 15) { + visit(depth + 1); + } + } + + void visitAndPop(int depth) { + // Random dummy allocation to force EscapeAnalysis to process this method + dummy = new TestAllocatedEscapesPtrComparison(); + + // Make a new marker + Marker marker = getMarker(); + + visit(depth + 1); + + // Walk and pop the marker list up to the current marker + boolean found = false; + for (int i = markerList.size() - 1; i >= 0; i--) { + Marker removed = markerList.remove(i); + + // In the failure, EA mistakenly converts this comparison to false + if (removed == marker) { + found = true; + break; + } + } + + if (!found) { + throw new RuntimeException("test fails"); + } + } + + + public static void main(String args[]) { + TestAllocatedEscapesPtrComparison tc = new TestAllocatedEscapesPtrComparison(); + + // Warmup and run enough times + for (int i = 0; i < 20000; i++) { + tc.visit(0); + } + } +} diff -r 14439491d407 -r 3cea99d662dc hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java --- a/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/gc/arguments/TestDynMaxHeapFreeRatio.java Fri May 23 09:22:01 2014 -0700 @@ -21,6 +21,11 @@ * questions. */ +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; + /** * @test TestDynMaxHeapFreeRatio * @bug 8028391 @@ -33,32 +38,45 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMaxHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMaxHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; - -public class TestDynMaxHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; - - public TestDynMaxHeapFreeRatio() { - super(MaxFreeRatioFlagName); - } - - public void test() { - - int minHeapFreeValue = DynamicVMOptionChecker.getIntValue(MinFreeRatioFlagName); - System.out.println(MinFreeRatioFlagName + " = " + minHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(minHeapFreeValue - 1)); - checkValidValue(Integer.toString(minHeapFreeValue)); - checkValidValue("100"); - } +public class TestDynMaxHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMaxHeapFreeRatio().test(); + + // low boundary value + int minValue = DynamicVMOption.getInt("MinHeapFreeRatio"); + System.out.println("MinHeapFreeRatio= " + minValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(minValue - 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(minValue), + Integer.toString(minValue + 1), + Integer.toString((minValue + 100) / 2), + "99", "100" + }; + + DynamicVMOption option = new DynamicVMOption("MaxHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } } - } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java --- a/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/gc/arguments/TestDynMinHeapFreeRatio.java Fri May 23 09:22:01 2014 -0700 @@ -33,30 +33,52 @@ * @run main/othervm -XX:MinHeapFreeRatio=51 -XX:MaxHeapFreeRatio=52 TestDynMinHeapFreeRatio * @run main/othervm -XX:MinHeapFreeRatio=75 -XX:MaxHeapFreeRatio=100 TestDynMinHeapFreeRatio */ -import com.oracle.java.testlibrary.TestDynamicVMOption; -import com.oracle.java.testlibrary.DynamicVMOptionChecker; - -public class TestDynMinHeapFreeRatio extends TestDynamicVMOption { - - public static final String MinFreeRatioFlagName = "MinHeapFreeRatio"; - public static final String MaxFreeRatioFlagName = "MaxHeapFreeRatio"; +import static com.oracle.java.testlibrary.Asserts.assertEQ; +import static com.oracle.java.testlibrary.Asserts.assertFalse; +import static com.oracle.java.testlibrary.Asserts.assertTrue; +import com.oracle.java.testlibrary.DynamicVMOption; - public TestDynMinHeapFreeRatio() { - super(MinFreeRatioFlagName); - } - - public void test() { - int maxHeapFreeValue = DynamicVMOptionChecker.getIntValue(MaxFreeRatioFlagName); - System.out.println(MaxFreeRatioFlagName + " = " + maxHeapFreeValue); - - testPercentageValues(); - - checkInvalidValue(Integer.toString(maxHeapFreeValue + 1)); - checkValidValue(Integer.toString(maxHeapFreeValue)); - checkValidValue("0"); - } +public class TestDynMinHeapFreeRatio { public static void main(String args[]) throws Exception { - new TestDynMinHeapFreeRatio().test(); + + // high boundary value + int maxValue = DynamicVMOption.getInt("MaxHeapFreeRatio"); + System.out.println("MaxHeapFreeRatio= " + maxValue); + + String badValues[] = { + null, + "", + "not a number", + "8.5", "-0.01", + Integer.toString(Integer.MIN_VALUE), + Integer.toString(Integer.MAX_VALUE), + Integer.toString(maxValue + 1), + "-1024", "-1", "101", "1997" + }; + + String goodValues[] = { + Integer.toString(maxValue), + Integer.toString(maxValue - 1), + Integer.toString(maxValue / 2), + "0", "1" + }; + + // option under test + DynamicVMOption option = new DynamicVMOption("MinHeapFreeRatio"); + + assertTrue(option.isWriteable(), "Option " + option.name + + " is expected to be writable"); + + for (String v : badValues) { + assertFalse(option.isValidValue(v), + "'" + v + "' is expected to be illegal for flag " + option.name); + } + + for (String v : goodValues) { + option.setValue(v); + String newValue = option.getValue(); + assertEQ(v, newValue); + } } } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/gc/g1/TestGCLogMessages.java --- a/hotspot/test/gc/g1/TestGCLogMessages.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/gc/g1/TestGCLogMessages.java Fri May 23 09:22:01 2014 -0700 @@ -22,7 +22,7 @@ */ /* - * @test TestPrintGCDetails + * @test TestGCLogMessages * @bug 8035406 8027295 8035398 8019342 * @summary Ensure that the PrintGCDetails output for a minor GC with G1 * includes the expected necessary messages. @@ -90,12 +90,6 @@ output.shouldContain("[String Dedup Fixup"); output.shouldContain("[Young Free CSet"); output.shouldContain("[Non-Young Free CSet"); - - // also check evacuation failure messages once - output.shouldNotContain("[Evacuation Failure"); - output.shouldNotContain("[Recalculate Used"); - output.shouldNotContain("[Remove Self Forwards"); - output.shouldNotContain("[Restore RemSet"); output.shouldHaveExitValue(0); } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java --- a/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/gc/parallelScavenge/TestDynShrinkHeap.java Fri May 23 09:22:01 2014 -0700 @@ -28,8 +28,7 @@ * @library /testlibrary * @run main/othervm -XX:+UseAdaptiveSizePolicyWithSystemGC -XX:+UseParallelGC -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 -verbose:gc TestDynShrinkHeap */ - -import com.oracle.java.testlibrary.TestDynamicVMOption; +import com.oracle.java.testlibrary.DynamicVMOption; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.util.ArrayList; @@ -44,12 +43,7 @@ private static ArrayList list = new ArrayList<>(0); private static final int M = 1024 * 1024; // to make heap more manageable by test code - private final TestDynamicVMOption maxRatioOption; - private final TestDynamicVMOption minRatioOption; - public TestDynShrinkHeap() { - minRatioOption = new TestDynamicVMOption(MIN_FREE_RATIO_FLAG_NAME); - maxRatioOption = new TestDynamicVMOption(MAX_FREE_RATIO_FLAG_NAME); } private final void test() { @@ -86,7 +80,8 @@ } private void free() { - maxRatioOption.setIntValue(minRatioOption.getIntValue() + 1); + int min = DynamicVMOption.getInt(MIN_FREE_RATIO_FLAG_NAME); + DynamicVMOption.setInt(MAX_FREE_RATIO_FLAG_NAME, min); System.gc(); MemoryUsagePrinter.printMemoryUsage("under pressure"); } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/7110720/Test7110720.sh --- a/hotspot/test/runtime/7110720/Test7110720.sh Wed May 21 11:25:25 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -# -# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# - - -# -# @test Test7110720.sh -# @bug 7110720 -# @summary improve VM configuration file loading -# @run shell Test7110720.sh -# - -if [ "${TESTSRC}" = "" ] -then - TESTSRC=${PWD} - echo "TESTSRC not set. Using "${TESTSRC}" as default" -fi -echo "TESTSRC=${TESTSRC}" -## Adding common setup Variables for running shell tests. -. ${TESTSRC}/../../test_env.sh - -# Jtreg sets TESTVMOPTS which may include -d64 which is -# required to test a 64-bit JVM on some platforms. -# If another test harness still creates HOME/JDK64BIT, -# we can recognise that. - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - FS="/" - RM=/bin/rm - CP=/bin/cp - MV=/bin/mv - ## for solaris, linux it's HOME - FILE_LOCATION=$HOME - if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ] - then - TESTVMOPTS=`cat ${FILE_LOCATION}${FS}JDK64BIT` - fi - ;; - Windows_* ) - FS="\\" - RM=rm - CP=cp - MV=mv - ;; - CYGWIN_* ) - FS="/" - RM=rm - CP=cp - MV=mv - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - - -JAVA=${TESTJAVA}${FS}bin${FS}java - -# Don't test debug builds, they do read the config files: -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "debug" >/dev/null -if [ "$?" = "0" ]; then - echo Skipping test for debug build. - exit 0 -fi - -ok=yes - -$RM -f .hotspot_compiler .hotspotrc - -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: base case failure" - exit 1 -fi - - -echo "garbage in, garbage out" > .hotspot_compiler -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspot_compiler was read" - ok=no -fi - -$MV .hotspot_compiler hs_comp.txt -${JAVA} ${TESTVMOPTS} -XX:CompileCommandFile=hs_comp.txt -version 2>&1 | grep "garbage in" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit compiler command file not read" - ok=no -fi - -$RM -f .hotspot_compiler hs_comp.txt - -echo "garbage" > .hotspotrc -${JAVA} ${TESTVMOPTS} -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "0" ]; then - echo "FAILED: .hotspotrc was read" - ok=no -fi - -$MV .hotspotrc hs_flags.txt -${JAVA} ${TESTVMOPTS} -XX:Flags=hs_flags.txt -version 2>&1 | grep "garbage" >/dev/null -if [ "$?" = "1" ]; then - echo "FAILED: explicit flags file not read" - ok=no -fi - -if [ "${ok}" = "no" ]; then - echo "Some tests failed." - exit 1 -else - echo "Passed" - exit 0 -fi - diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java --- a/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/runtime/CommandLine/CompilerConfigFileWarning.java Fri May 23 09:22:01 2014 -0700 @@ -33,17 +33,28 @@ public class CompilerConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + ProcessBuilder pb; + OutputAnalyzer output; + PrintWriter pw; - PrintWriter pw = new PrintWriter(".hotspot_compiler"); - pw.println("aa"); + pw = new PrintWriter("hs_comp.txt"); + pw.println("aaa, aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("CompilerOracle: unrecognized line"); + output.shouldContain("aaa aaa"); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspot_compiler"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspot_compiler file is present but has been ignored. Run with -XX:CompileCommandFile=.hotspot_compiler to load the file."); + } } } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/CommandLine/ConfigFileWarning.java --- a/hotspot/test/runtime/CommandLine/ConfigFileWarning.java Wed May 21 11:25:25 2014 +0200 +++ b/hotspot/test/runtime/CommandLine/ConfigFileWarning.java Fri May 23 09:22:01 2014 -0700 @@ -33,17 +33,28 @@ public class ConfigFileWarning { public static void main(String[] args) throws Exception { - if (Platform.isDebugBuild()) { - System.out.println("Skip on debug builds since we'll always read the file there"); - return; - } + PrintWriter pw; + ProcessBuilder pb; + OutputAnalyzer output; - PrintWriter pw = new PrintWriter(".hotspotrc"); - pw.println("aa"); + pw = new PrintWriter("hs_flags.txt"); + pw.println("aaa"); pw.close(); - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version"); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + pb = ProcessTools.createJavaProcessBuilder("-XX:Flags=hs_flags.txt","-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Unrecognized VM option 'aaa'"); + output.shouldHaveExitValue(1); + + // Skip on debug builds since we'll always read the file there + if (!Platform.isDebugBuild()) { + pw = new PrintWriter(".hotspotrc"); + pw.println("aa"); + pw.close(); + + pb = ProcessTools.createJavaProcessBuilder("-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: .hotspotrc file is present but has been ignored. Run with -XX:Flags=.hotspotrc to load the file."); + } } } diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/CommandLine/TestHexArguments.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/CommandLine/TestHexArguments.java Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,49 @@ +/* + * 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 + * @bug 8042885 + * @summary Make sure there is no error using hexadecimal format in vm options + * @author Yumin Qi + * @library /testlibrary + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class TestHexArguments { + public static void main(String args[]) throws Exception { + String[] javaArgs = {"-XX:SharedBaseAddress=0x1D000000", "-version"}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, javaArgs); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("Could not create the Java Virtual Machine"); + output.shouldHaveExitValue(0); + + String[] javaArgs1 = {"-XX:SharedBaseAddress=1D000000", "-version"}; + pb = ProcessTools.createJavaProcessBuilder(true, javaArgs1); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("Could not create the Java Virtual Machine"); + } +} diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java --- a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java Wed May 21 11:25:25 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +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 CdsWriteError - * @summary Test how VM handles situation when it is impossible to write the - * CDS archive. VM is expected to exit gracefully and display the - * correct reason for the error. - * @library /testlibrary - * @run main CdsWriteError - * @bug 8032222 - */ - -import com.oracle.java.testlibrary.*; -import java.io.File; - -public class CdsWriteError { - public static void main(String[] args) throws Exception { - - if (Platform.isWindows()) { - System.out.println("This test is ignored on Windows. This test " + - "manipulates folder writable attribute, which is known to be " + - "often ignored by Windows"); - - return; - } - - // This test has been unstable for Mac OSx (see JDK-8032222) - if (Platform.isOSX()) { - System.out.println("This test is skipped on Mac"); - return; - } - - String folderName = "tmp"; - String fileName = folderName + File.separator + "empty.jsa"; - - // create an empty archive file and make it read only - File folder = new File(folderName); - if (!folder.mkdir()) - throw new RuntimeException("Error when creating a tmp folder"); - - File cdsFile = new File(fileName); - if (!cdsFile.createNewFile()) - throw new RuntimeException("Error when creating an empty CDS file"); - if (!cdsFile.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on cds file"); - if (!folder.setWritable(false)) - throw new RuntimeException("Error: could not set writable attribute on the cds folder"); - - try { - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./" + fileName, "-Xshare:dump"); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("Unable to create shared archive file"); - output.shouldHaveExitValue(1); - } finally { - // doing this, just in case, to make sure that files can be deleted by the harness - // on any subsequent run - folder.setWritable(true); - cdsFile.setWritable(true); - } - } -} - diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/TestEmptyBootstrapMethodsAttr.java Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,75 @@ +/* + * 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 TestEmptyBootstrapMethodsAttr + * @bug 8041918 + * @library /testlibrary + * @summary Test empty bootstrap_methods table within BootstrapMethods attribute + * @compile TestEmptyBootstrapMethodsAttr.java + * @run main TestEmptyBootstrapMethodsAttr + */ + +import java.io.File; +import com.oracle.java.testlibrary.*; + +public class TestEmptyBootstrapMethodsAttr { + + public static void main(String args[]) throws Throwable { + System.out.println("Regression test for bug 8041918"); + String jarFile = System.getProperty("test.src") + File.separator + "emptynumbootstrapmethods.jar"; + + // ====== extract the test case + ProcessBuilder pb = new ProcessBuilder(new String[] { JDKToolFinder.getJDKTool("jar"), "xvf", jarFile } ); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + + // Test case #1: + // Try loading class with empty bootstrap_methods table where no + // other attributes are following BootstrapMethods in attribute table. + String className = "emptynumbootstrapmethods1"; + + // ======= execute test case #1 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate a ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + + // Test case #2: + // Try loading class with empty bootstrap_methods table where an + // AnnotationDefault attribute follows the BootstrapMethods in the attribute table. + className = "emptynumbootstrapmethods2"; + + // ======= execute test case #2 + // Expect a lack of main method, this implies that the class loaded correctly + // with an empty bootstrap_methods and did not generate ClassFormatError. + pb = ProcessTools.createJavaProcessBuilder("-cp", ".", className); + output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("java.lang.ClassFormatError"); + output.shouldContain("Main method not found in class " + className); + output.shouldHaveExitValue(1); + } +} diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar Binary file hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods.jar has changed diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods1.jcod Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,68 @@ +/* + * 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. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. + */ +class emptynumbootstrapmethods1 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [12] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods1"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [1] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + } // Attributes +} // end class atrbsm00101m10p diff -r 14439491d407 -r 3cea99d662dc hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/classFileParserBug/emptynumbootstrapmethods2.jcod Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,89 @@ +/* + * 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. + */ + +/* + * This test contains a BootstrapMethods attribute with an empty + * bootstrap_methods table. This yields a BootstrapMethods + * attribute length of 2 and should not cause a + * java.lang.ClassFormatError to be thrown. To ensure that an empty + * bootstrap_methods table is parsed correctly, another attribute, + * AnnotationDefault, follows the BootstrapMethods attribute in + * the attribute table. + */ + +class emptynumbootstrapmethods2 { + 0xCAFEBABE; + 0; // minor version + 51; // version + [14] { // Constant Pool + ; // first element is empty + class #2; // #1 at 0x0A + Utf8 "emptynumbootstrapmethods2"; // #2 at 0x0D + class #4; // #3 at 0x1F + Utf8 "java/lang/Object"; // #4 at 0x22 + MethodHandle 5b #9; // #5 at 0x35 + NameAndType #7 #8; // #6 at 0x39 + Utf8 "equals"; // #7 at 0x3E + Utf8 "(Ljava/lang/Object;)Z"; // #8 at 0x47 + Method #3 #6; // #9 at 0x5F + Utf8 "equalsx"; // #10 at 0x3E + Utf8 "BootstrapMethods"; // #11 at 0x69 + Utf8 "AnnotationDefault"; // #12 + Utf8 "LAnnotationDefaultI;"; // #13 + } // Constant Pool + + 0x0001; // access + #1;// this_cpx + #3;// super_cpx + + [0] { // Interfaces + } // Interfaces + + [0] { // fields + } // fields + + [0] { // methods + } // methods + + [2] { // Attributes + Attr(#11, 2) { // BootstrapMethods at 0x8A + [0] { // bootstrap_methods + } + } // end BootstrapMethods + ; + Attr(#12) { // AnnotationDefault + [] { // type annotations + { // type annotation + 0x00; // target_type + 0x00; // type_parameter_index + []b { // type_path + } + + #13; // type_index + [] { // element_value_pairs + } // element_value_pairs + } // type annotation + } // type annotations + } // end AnnotationDefault + } // Attributes +} // end class atrbsm00101m10p diff -r 14439491d407 -r 3cea99d662dc hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOption.java Fri May 23 09:22:01 2014 -0700 @@ -0,0 +1,165 @@ +/* + * 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. + */ +package com.oracle.java.testlibrary; + +import com.sun.management.HotSpotDiagnosticMXBean; +import java.lang.management.ManagementFactory; + +/** + * A utility class to work with VM options which could be altered during + * execution. + * + * This class is a wrapper around {@code com.sun.management.VMOption}. + * It provides more convenient interface to read/write the values. + * + */ +public class DynamicVMOption { + + private final HotSpotDiagnosticMXBean mxBean; + + /** + * VM option name, like "MinHeapFreeRatio". + */ + public final String name; + + /** + * Creates an instance of DynamicVMOption. + * + * @param name the VM option name + */ + public DynamicVMOption(String name) { + this.name = name; + mxBean = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); + } + + /** + * Sets a new value for the option. + * Trying to set not applicable value will cause IllegalArgumentException. + * Behavior with null is undefined, most likely NPE will be thrown. + * + * @param newValue the value to be set + * @see #getValue() + * @throws IllegalArgumentException if newValue is not applicable to the option + */ + public final void setValue(String newValue) { + mxBean.setVMOption(name, newValue); + } + + /** + * Returns the value of option. + * + * @return the current option value + * @see #setValue(java.lang.String) + */ + public final String getValue() { + return mxBean.getVMOption(name).getValue(); + } + + /** + * Returns true, if option is writable, false otherwise. + * + * @return true, if option is writable, false otherwise + */ + public final boolean isWriteable() { + return mxBean.getVMOption(name).isWriteable(); + } + + /** + * Checks if the given value is applicable for the option. + * + * This method tries to set the option to the new value. If no exception + * has been thrown the value is treated as valid. + * + * Calling this method will not change the option value. After an attempt + * to set a new value, the option will be restored to its previous value. + * + * @param value the value to verify + * @return true if option could be set to the given value + */ + public boolean isValidValue(String value) { + boolean isValid = true; + String oldValue = getValue(); + try { + setValue(value); + } catch (NullPointerException e) { + if (value == null) { + isValid = false; + } + } catch (IllegalArgumentException e) { + isValid = false; + } finally { + setValue(oldValue); + } + return isValid; + } + + /** + * Returns the value of the given VM option as String. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).getValue()} + * + * @param name the name of VM option + * @return value as a string + * @see #getValue() + */ + public static String getString(String name) { + return new DynamicVMOption(name).getValue(); + } + + /** + * Returns the value of the given option as int. + * + * @param name the name of VM option + * @return value parsed as integer + * @see #getString(java.lang.String) + * + */ + public static int getInt(String name) { + return Integer.parseInt(getString(name)); + } + + /** + * Sets the VM option to a new value. + * + * This is a simple shortcut for {@code new DynamicVMOption(name).setValue(value)} + * + * @param name the name of VM option + * @param value the value to be set + * @see #setValue(java.lang.String) + */ + public static void setString(String name, String value) { + new DynamicVMOption(name).setValue(value); + } + + /** + * Sets the VM option value to a new integer value. + * + * @param name the name of VM option + * @param value the integer value to be set + * @see #setString(java.lang.String, java.lang.String) + */ + public static void setInt(String name, int value) { + new DynamicVMOption(name).setValue(Integer.toString(value)); + } + +} diff -r 14439491d407 -r 3cea99d662dc hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/DynamicVMOptionChecker.java Wed May 21 11:25:25 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +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. - */ -package com.oracle.java.testlibrary; - -import com.sun.management.HotSpotDiagnosticMXBean; -import com.sun.management.VMOption; -import java.lang.management.ManagementFactory; - -/** - * Simple class to check writeability, invalid and valid values for VMOption - */ -public class DynamicVMOptionChecker { - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @param name of option - * @return parsed value - */ - public static int getIntValue(String name) { - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - return Integer.parseInt(option.getValue()); - } - - /** - * Sets VM option value - * - * @param name of option - * @param value to set - */ - public static void setIntValue(String name, int value) { - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class).setVMOption(name, Integer.toString(value)); - } - - /** - * Checks that VM option is dynamically writable - * - * @param name - * @throws RuntimeException if option if not writable - * @return always true - */ - public static boolean checkIsWritable(String name) { - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.isWriteable()) { - throw new RuntimeException(name + " is not writable"); - } - - return true; - } - - /** - * Checks that value cannot be set - * - * @param name of flag - * @param value string representation of value to set - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public static void checkInvalidValue(String name, String value) { - // should throw - try { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - } catch (IllegalArgumentException e) { - return; - } - - throw new RuntimeException("Expected IllegalArgumentException was not thrown, " + name + "= " + value); - } - - /** - * Checks that value can be set - * - * @param name of flag to set - * @param value string representation of value to set - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public static void checkValidValue(String name, String value) { - ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - setVMOption(name, value); - - VMOption option = ManagementFactory. - getPlatformMXBean(HotSpotDiagnosticMXBean.class). - getVMOption(name); - - if (!option.getValue().equals(value)) { - throw new RuntimeException("Actual value of " + name + " \"" + option.getValue() - + "\" not equal origin \"" + value + "\""); - } - } - -} diff -r 14439491d407 -r 3cea99d662dc hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/TestDynamicVMOption.java Wed May 21 11:25:25 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +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. - */ -package com.oracle.java.testlibrary; - -/** - * Simple class to check writeability, invalid and valid values for concrete VMOption - */ -public class TestDynamicVMOption { - - private final String name; - private final int value; - - /** - * Constructor - * - * @param name of VM option to test - */ - public TestDynamicVMOption(String name) { - this.name = name; - this.value = DynamicVMOptionChecker.getIntValue(name); - System.out.println(this.name + " = " + this.value); - } - - /** - * Checks that this value can accept valid percentage values and cannot accept invalid percentage values - * - * @throws RuntimeException - */ - public void testPercentageValues() { - checkInvalidValue(Integer.toString(Integer.MIN_VALUE)); - checkInvalidValue(Integer.toString(Integer.MAX_VALUE)); - checkInvalidValue("-10"); - checkInvalidValue("190"); - } - - /** - * Reads VM option from PlatformMXBean and parse it to integer value - * - * @return value - */ - public int getIntValue() { - return DynamicVMOptionChecker.getIntValue(this.name); - } - - /** - * Sets VM option value - * - * @param value to set - */ - public void setIntValue(int value) { - DynamicVMOptionChecker.setIntValue(this.name, value); - } - - /** - * Checks that this VM option is dynamically writable - * - * @throws RuntimeException if option if not writable - * @return true - */ - public boolean checkIsWritable() throws RuntimeException { - return DynamicVMOptionChecker.checkIsWritable(this.name); - } - - /** - * Checks that value for this VM option cannot be set - * - * @param value to check - * @throws RuntimeException on error - when expected exception hasn't been thrown - */ - public void checkInvalidValue(String value) { - DynamicVMOptionChecker.checkInvalidValue(this.name, value); - } - - /** - * Checks that value for this VM option can be set - * - * @param value to check - * @throws RuntimeException on error - when value in VM is not equal to origin - */ - public void checkValidValue(String value) { - DynamicVMOptionChecker.checkValidValue(this.name, value); - } - -}