# HG changeset patch # User vladidan # Date 1348527655 14400 # Node ID ef7fe63a2d3958d208a3c87b55a9a68acd13818e # Parent 04ed664b7e30a8cc0d007acda3a0856653effc1e# Parent fac3dd92ebaf94a5b6d3ddfac52cafb9edad4974 Merge diff -r fac3dd92ebaf -r ef7fe63a2d39 .hgtags --- a/.hgtags Wed Sep 19 17:22:49 2012 -0400 +++ b/.hgtags Mon Sep 24 19:00:55 2012 -0400 @@ -277,3 +277,5 @@ af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55 6124ff4218296c91e4a72f1a76c064892d39d61b jdk8-b56 9b076bc3ab67d42d1d02144ef8dcd6006a7fc0d6 hs25-b01 +d70102c4cb73158902acaa6016f47c7bc14e0d67 jdk8-b57 +5f54277c67f755a377999bff904ab48aa63ddaf9 hs25-b02 diff -r fac3dd92ebaf -r ef7fe63a2d39 make/hotspot_version --- a/make/hotspot_version Wed Sep 19 17:22:49 2012 -0400 +++ b/make/hotspot_version Mon Sep 24 19:00:55 2012 -0400 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=02 +HS_BUILD_NUMBER=03 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/classfile/classLoaderData.hpp --- a/src/share/vm/classfile/classLoaderData.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/classfile/classLoaderData.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -204,15 +204,6 @@ void classes_do(KlassClosure* klass_closure); - bool has_defined(Klass* klass) { - for (Klass* k = _klasses; k != NULL; k = k->next_link()) { - if (klass == k) { - return true; - } - } - return false; - } - JNIMethodBlock* jmethod_ids() const { return _jmethod_ids; } void set_jmethod_ids(JNIMethodBlock* new_block) { _jmethod_ids = new_block; } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -1496,6 +1496,19 @@ int d_index = dictionary()->hash_to_index(d_hash); check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK); + // Register class just loaded with class loader (placed in Vector) + // Note we do this before updating the dictionary, as this can + // fail with an OutOfMemoryError (if it does, we will *not* put this + // class in the dictionary and will not update the class hierarchy). + // JVMTI FollowReferences needs to find the classes this way. + if (k->class_loader() != NULL) { + methodHandle m(THREAD, Universe::loader_addClass_method()); + JavaValue result(T_VOID); + JavaCallArguments args(class_loader_h); + args.push_oop(Handle(THREAD, k->java_mirror())); + JavaCalls::call(&result, m, &args, CHECK); + } + // Add the new class. We need recompile lock during update of CHA. { unsigned int p_hash = placeholders()->compute_hash(name_h, loader_data); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -314,6 +314,7 @@ template(type_name, "type") \ template(findNative_name, "findNative") \ template(deadChild_name, "deadChild") \ + template(addClass_name, "addClass") \ template(getFromClass_name, "getFromClass") \ template(dispatch_name, "dispatch") \ template(getSystemClassLoader_name, "getSystemClassLoader") \ diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -789,14 +789,6 @@ _gc_counters = new CollectorCounters("CMS", 1); _completed_initialization = true; _inter_sweep_timer.start(); // start of time -#ifdef SPARC - // Issue a stern warning, but allow use for experimentation and debugging. - if (VM_Version::is_sun4v() && UseMemSetInBOT) { - assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); - warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" - " on sun4v; please understand that you are using at your own risk!"); - } -#endif } const char* ConcurrentMarkSweepGeneration::name() const { @@ -3425,10 +3417,7 @@ _wallclock.stop(); if (PrintGCDetails) { gclog_or_tty->date_stamp(PrintGCDateStamps); - if (PrintGCTimeStamps) { - gclog_or_tty->stamp(); - gclog_or_tty->print(": "); - } + gclog_or_tty->stamp(PrintGCTimeStamps); gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]", _collector->cmsGen()->short_name(), _phase, _collector->timerValue(), _wallclock.seconds()); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -110,7 +110,7 @@ #ifndef PRODUCT bool CMBitMapRO::covers(ReservedSpace rs) const { // assert(_bm.map() == _virtual_space.low(), "map inconsistency"); - assert(((size_t)_bm.size() * (size_t)(1 << _shifter)) == _bmWordSize, + assert(((size_t)_bm.size() * ((size_t)1 << _shifter)) == _bmWordSize, "size inconsistency"); return _bmStartWord == (HeapWord*)(rs.base()) && _bmWordSize == rs.size()>>LogHeapWordSize; diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -1954,14 +1954,6 @@ NOT_PRODUCT(reset_evacuation_should_fail();) guarantee(_task_queues != NULL, "task_queues allocation failure."); -#ifdef SPARC - // Issue a stern warning, but allow use for experimentation and debugging. - if (VM_Version::is_sun4v() && UseMemSetInBOT) { - assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); - warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" - " on sun4v; please understand that you are using at your own risk!"); - } -#endif } jint G1CollectedHeap::initialize() { @@ -3663,6 +3655,43 @@ } #endif // TASKQUEUE_STATS +void G1CollectedHeap::log_gc_header() { + if (!G1Log::fine()) { + return; + } + + gclog_or_tty->date_stamp(PrintGCDateStamps); + gclog_or_tty->stamp(PrintGCTimeStamps); + + GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause()) + .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)") + .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : ""); + + gclog_or_tty->print("[%s", (const char*)gc_cause_str); +} + +void G1CollectedHeap::log_gc_footer(double pause_time_sec) { + if (!G1Log::fine()) { + return; + } + + if (G1Log::finer()) { + if (evacuation_failed()) { + gclog_or_tty->print(" (to-space exhausted)"); + } + gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec); + g1_policy()->phase_times()->note_gc_end(); + g1_policy()->phase_times()->print(pause_time_sec); + g1_policy()->print_detailed_heap_transition(); + } else { + if (evacuation_failed()) { + gclog_or_tty->print("--"); + } + g1_policy()->print_heap_transition(); + gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec); + } +} + bool G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { assert_at_safepoint(true /* should_be_vm_thread */); @@ -3705,17 +3734,13 @@ // full collection counter. increment_old_marking_cycles_started(); } - // if the log level is "finer" is on, we'll print long statistics information - // in the collector policy code, so let's not print this as the output - // is messy if we do. - gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ? workers()->active_workers() : 1); double pause_start_sec = os::elapsedTime(); g1_policy()->phase_times()->note_gc_start(active_workers); - bool initial_mark_gc = g1_policy()->during_initial_mark_pause(); + log_gc_header(); TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); @@ -4012,35 +4037,7 @@ gc_epilogue(false); - if (G1Log::fine()) { - if (PrintGCTimeStamps) { - gclog_or_tty->stamp(); - gclog_or_tty->print(": "); - } - - GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause()) - .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)") - .append(initial_mark_gc ? " (initial-mark)" : ""); - - double pause_time_sec = os::elapsedTime() - pause_start_sec; - - if (G1Log::finer()) { - if (evacuation_failed()) { - gc_cause_str.append(" (to-space exhausted)"); - } - gclog_or_tty->print_cr("[%s, %3.7f secs]", (const char*)gc_cause_str, pause_time_sec); - g1_policy()->phase_times()->note_gc_end(); - g1_policy()->phase_times()->print(pause_time_sec); - g1_policy()->print_detailed_heap_transition(); - } else { - if (evacuation_failed()) { - gc_cause_str.append("--"); - } - gclog_or_tty->print("[%s", (const char*)gc_cause_str); - g1_policy()->print_heap_transition(); - gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec); - } - } + log_gc_footer(os::elapsedTime() - pause_start_sec); } // It is not yet to safe to tell the concurrent mark to @@ -6418,7 +6415,7 @@ MemRegion mr(bottom, end); assert(_g1_reserved.contains(mr), "invariant"); // This might return NULL if the allocation fails - return new HeapRegion(hrs_index, _bot_shared, mr, true /* is_zeroed */); + return new HeapRegion(hrs_index, _bot_shared, mr); } void G1CollectedHeap::verify_region_sets() { diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -408,6 +408,9 @@ void verify_before_gc(); void verify_after_gc(); + void log_gc_header(); + void log_gc_footer(double pause_time_sec); + // These are macros so that, if the assert fires, we get the correct // line number, file, etc. @@ -1848,9 +1851,7 @@ if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose); add_to_alloc_buffer_waste(alloc_buf->words_remaining()); - alloc_buf->flush_stats_and_retire(_g1h->stats_for_purpose(purpose), - false /* end_of_gc */, - false /* retain */); + alloc_buf->retire(false /* end_of_gc */, false /* retain */); HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size); if (buf == NULL) return NULL; // Let caller handle allocation failure. diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -476,10 +476,6 @@ return low; } -void HeapRegion::initialize(MemRegion mr, bool clear_space, bool mangle_space) { - G1OffsetTableContigSpace::initialize(mr, false, mangle_space); - hr_clear(false/*par*/, clear_space); -} #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away #pragma warning( disable:4355 ) // 'this' : used in base member initializer list #endif // _MSC_VER @@ -487,8 +483,8 @@ HeapRegion::HeapRegion(uint hrs_index, G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, bool is_zeroed) : - G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed), + MemRegion mr) : + G1OffsetTableContigSpace(sharedOffsetArray, mr), _hrs_index(hrs_index), _humongous_type(NotHumongous), _humongous_start_region(NULL), _in_collection_set(false), @@ -507,7 +503,7 @@ _orig_end = mr.end(); // Note that initialize() will set the start of the unmarked area of the // region. - this->initialize(mr, !is_zeroed, SpaceDecorator::Mangle); + hr_clear(false /*par*/, false /*clear_space*/); set_top(bottom()); set_saved_mark(); @@ -908,14 +904,6 @@ // G1OffsetTableContigSpace code; copied from space.cpp. Hope this can go // away eventually. -void G1OffsetTableContigSpace::initialize(MemRegion mr, bool clear_space, bool mangle_space) { - // false ==> we'll do the clearing if there's clearing to be done. - ContiguousSpace::initialize(mr, false, mangle_space); - _offsets.zero_bottom_entry(); - _offsets.initialize_threshold(); - if (clear_space) clear(mangle_space); -} - void G1OffsetTableContigSpace::clear(bool mangle_space) { ContiguousSpace::clear(mangle_space); _offsets.zero_bottom_entry(); @@ -983,11 +971,14 @@ G1OffsetTableContigSpace:: G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, bool is_zeroed) : + MemRegion mr) : _offsets(sharedOffsetArray, mr), _par_alloc_lock(Mutex::leaf, "OffsetTableContigSpace par alloc lock", true), _gc_time_stamp(0) { _offsets.set_space(this); - initialize(mr, !is_zeroed, SpaceDecorator::Mangle); + // false ==> we'll do the clearing if there's clearing to be done. + ContiguousSpace::initialize(mr, false, SpaceDecorator::Mangle); + _offsets.zero_bottom_entry(); + _offsets.initialize_threshold(); } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -165,10 +165,8 @@ HeapWord* _pre_dummy_top; public: - // Constructor. If "is_zeroed" is true, the MemRegion "mr" may be - // assumed to contain zeros. G1OffsetTableContigSpace(G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, bool is_zeroed = false); + MemRegion mr); void set_bottom(HeapWord* value); void set_end(HeapWord* value); @@ -189,7 +187,6 @@ } void reset_pre_dummy_top() { _pre_dummy_top = NULL; } - virtual void initialize(MemRegion mr, bool clear_space, bool mangle_space); virtual void clear(bool mangle_space); HeapWord* block_start(const void* p); @@ -340,10 +337,9 @@ size_t _predicted_bytes_to_copy; public: - // If "is_zeroed" is "true", the region "mr" can be assumed to contain zeros. HeapRegion(uint hrs_index, G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, bool is_zeroed); + MemRegion mr); static int LogOfHRGrainBytes; static int LogOfHRGrainWords; @@ -598,8 +594,6 @@ void hr_clear(bool par, bool clear_space); void par_clear(); - void initialize(MemRegion mr, bool clear_space, bool mangle_space); - // Get the start of the unmarked area in this region. HeapWord* prev_top_at_mark_start() const { return _prev_top_at_mark_start; } HeapWord* next_top_at_mark_start() const { return _next_top_at_mark_start; } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -273,7 +273,7 @@ if (_max_fine_entries == 0) { assert(_mod_max_fine_entries_mask == 0, "Both or none."); size_t max_entries_log = (size_t)log2_long((jlong)G1RSetRegionEntries); - _max_fine_entries = (size_t)(1 << max_entries_log); + _max_fine_entries = (size_t)1 << max_entries_log; _mod_max_fine_entries_mask = _max_fine_entries - 1; assert(_fine_eviction_sample_size == 0 diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -2392,8 +2392,6 @@ void PSParallelCompact::follow_klass(ParCompactionManager* cm, Klass* klass) { ClassLoaderData* cld = klass->class_loader_data(); - assert(cld->has_defined(klass), "inconsistency!"); - // The actual processing of the klass is done when we // traverse the list of Klasses in the class loader data. PSParallelCompact::follow_class_loader(cm, cld); @@ -2401,8 +2399,6 @@ void PSParallelCompact::adjust_klass(ParCompactionManager* cm, Klass* klass) { ClassLoaderData* cld = klass->class_loader_data(); - assert(cld->has_defined(klass), "inconsistency!"); - // The actual processing of the klass is done when we // traverse the list of Klasses in the class loader data. PSParallelCompact::adjust_class_loader(cm, cld); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/shared/markSweep.cpp --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -84,8 +84,6 @@ void MarkSweep::follow_klass(Klass* klass) { ClassLoaderData* cld = klass->class_loader_data(); - assert(cld->has_defined(klass), "inconsistency!"); - // The actual processing of the klass is done when we // traverse the list of Klasses in the class loader data. MarkSweep::follow_class_loader(cld); @@ -93,8 +91,6 @@ void MarkSweep::adjust_klass(Klass* klass) { ClassLoaderData* cld = klass->class_loader_data(); - assert(cld->has_defined(klass), "inconsistency!"); - // The actual processing of the klass is done when we // traverse the list of Klasses in the class loader data. MarkSweep::adjust_class_loader(cld); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -90,7 +90,14 @@ void PLABStats::adjust_desired_plab_sz() { assert(ResizePLAB, "Not set"); if (_allocated == 0) { - assert(_unused == 0, "Inconsistency in PLAB stats"); + assert(_unused == 0, + err_msg("Inconsistency in PLAB stats: " + "_allocated: "SIZE_FORMAT", " + "_wasted: "SIZE_FORMAT", " + "_unused: "SIZE_FORMAT", " + "_used : "SIZE_FORMAT, + _allocated, _wasted, _unused, _used)); + _allocated = 1; } double wasted_frac = (double)_unused/(double)_allocated; diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp --- a/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -52,6 +52,10 @@ static size_t FillerHeaderSize; static size_t AlignmentReserve; + // Flush the stats supporting ergonomic sizing of PLAB's + // Should not be called directly + void flush_stats(PLABStats* stats); + public: // Initializes the buffer to be empty, but with the given "word_sz". // Must get initialized with "set_buf" for an allocation to succeed. @@ -120,12 +124,22 @@ } // Flush the stats supporting ergonomic sizing of PLAB's - void flush_stats(PLABStats* stats); + // and retire the current buffer. void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) { // We flush the stats first in order to get a reading of // unused space in the last buffer. if (ResizePLAB) { flush_stats(stats); + + // Since we have flushed the stats we need to clear + // the _allocated and _wasted fields. Not doing so + // will artifically inflate the values in the stats + // to which we add them. + // The next time we flush these values, we will add + // what we have just flushed in addition to the size + // of the buffers allocated between now and then. + _allocated = 0; + _wasted = 0; } // Retire the last allocation buffer. retire(end_of_gc, retain); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/gc_implementation/shared/vmGCOperations.cpp --- a/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -230,15 +230,9 @@ // amount of the expansion. // This should work unless there really is no more space // or a MaxMetaspaceSize has been specified on the command line. - MetaspaceGC::set_expand_after_GC(true); - size_t before_inc = MetaspaceGC::capacity_until_GC(); - size_t delta_words = MetaspaceGC::delta_capacity_until_GC(_size); - MetaspaceGC::inc_capacity_until_GC(delta_words); - if (PrintGCDetails && Verbose) { - gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT - " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC()); - } - _result = _loader_data->metaspace_non_null()->allocate(_size, _mdtype); + _result = + _loader_data->metaspace_non_null()->expand_and_allocate(_size, _mdtype); + if (do_cms_concurrent && _result == NULL) { // Rather than fail with a metaspace out-of-memory, do a full // GC for CMS. diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/blockOffsetTable.hpp --- a/src/share/vm/memory/blockOffsetTable.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/blockOffsetTable.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -285,7 +285,7 @@ }; static size_t power_to_cards_back(uint i) { - return (size_t)(1 << (LogBase * i)); + return (size_t)1 << (LogBase * i); } static size_t power_to_words_back(uint i) { return power_to_cards_back(i) * N_words; diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/collectorPolicy.cpp --- a/src/share/vm/memory/collectorPolicy.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/collectorPolicy.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -743,6 +743,36 @@ uint full_gc_count = 0; do { + MetaWord* result = NULL; + if (GC_locker::is_active_and_needs_gc()) { + // If the GC_locker is active, just expand and allocate. + // If that does not succeed, wait if this thread is not + // in a critical section itself. + result = + loader_data->metaspace_non_null()->expand_and_allocate(word_size, + mdtype); + if (result != NULL) { + return result; + } + JavaThread* jthr = JavaThread::current(); + if (!jthr->in_critical()) { + MutexUnlocker mul(Heap_lock); + // Wait for JNI critical section to be exited + GC_locker::stall_until_clear(); + // The GC invoked by the last thread leaving the critical + // section will be a young collection and a full collection + // is (currently) needed for unloading classes so continue + // to the next iteration to get a full GC. + continue; + } else { + if (CheckJNICalls) { + fatal("Possible deadlock due to allocating while" + " in jni critical section"); + } + return NULL; + } + } + { // Need lock to get self consistent gc_count's MutexLocker ml(Heap_lock); gc_count = Universe::heap()->total_collections(); diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/metaspace.cpp --- a/src/share/vm/memory/metaspace.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/metaspace.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -2843,6 +2843,21 @@ } } +MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) { + MetaWord* result; + MetaspaceGC::set_expand_after_GC(true); + size_t before_inc = MetaspaceGC::capacity_until_GC(); + size_t delta_words = MetaspaceGC::delta_capacity_until_GC(word_size); + MetaspaceGC::inc_capacity_until_GC(delta_words); + if (PrintGCDetails && Verbose) { + gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT + " to " SIZE_FORMAT, before_inc, MetaspaceGC::capacity_until_GC()); + } + result = allocate(word_size, mdtype); + + return result; +} + // Space allocated in the Metaspace. This may // be across several metadata virtual spaces. char* Metaspace::bottom() const { diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/metaspace.hpp --- a/src/share/vm/memory/metaspace.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/metaspace.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -130,8 +130,10 @@ static MetaWord* allocate(ClassLoaderData* loader_data, size_t size, bool read_only, MetadataType mdtype, TRAPS); + void deallocate(MetaWord* ptr, size_t byte_size, bool is_class); - void deallocate(MetaWord* ptr, size_t byte_size, bool is_class); + MetaWord* expand_and_allocate(size_t size, + MetadataType mdtype); #ifndef PRODUCT bool contains(const void *ptr) const; diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/universe.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -117,6 +117,7 @@ oop Universe::_the_null_string = NULL; oop Universe::_the_min_jint_string = NULL; LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; +LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_perm_gen = NULL; @@ -228,6 +229,7 @@ f->do_ptr((void**)&_the_empty_method_array); f->do_ptr((void**)&_the_empty_klass_array); _finalizer_register_cache->serialize(f); + _loader_addClass_cache->serialize(f); _reflect_invoke_cache->serialize(f); } @@ -652,6 +654,7 @@ // We have a heap so create the Method* caches before // Metaspace::initialize_shared_spaces() tries to populate them. Universe::_finalizer_register_cache = new LatestMethodOopCache(); + Universe::_loader_addClass_cache = new LatestMethodOopCache(); Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); if (UseSharedSpaces) { @@ -1041,6 +1044,16 @@ } Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); + // Setup method for registering loaded classes in class loader vector + InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); + m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); + if (m == NULL || m->is_static()) { + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), + "java.lang.ClassLoader.addClass", false); + } + Universe::_loader_addClass_cache->init( + SystemDictionary::ClassLoader_klass(), m, CHECK_false); + // The folowing is initializing converter functions for serialization in // JVM.cpp. If we clean up the StrictMath code above we may want to find // a better solution for this as well. diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/memory/universe.hpp Mon Sep 24 19:00:55 2012 -0400 @@ -175,6 +175,7 @@ static oop _the_null_string; // A cache of "null" as a Java string static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects + static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks static oop _out_of_memory_error_java_heap; // preallocated error object (no backtrace) static oop _out_of_memory_error_perm_gen; // preallocated error object (no backtrace) @@ -318,6 +319,7 @@ static oop the_null_string() { return _the_null_string; } static oop the_min_jint_string() { return _the_min_jint_string; } static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } + static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/runtime/arguments.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -1978,6 +1978,19 @@ status = status && verify_min_value(ClassMetaspaceSize, 1*M, "ClassMetaspaceSize"); +#ifdef SPARC + if (UseConcMarkSweepGC || UseG1GC) { + // Issue a stern warning if the user has explicitly set + // UseMemSetInBOT (it is known to cause issues), but allow + // use for experimentation and debugging. + if (VM_Version::is_sun4v() && UseMemSetInBOT) { + assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); + warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" + " on sun4v; please understand that you are using at your own risk!"); + } + } +#endif // SPARC + return status; } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/runtime/timer.cpp --- a/src/share/vm/runtime/timer.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/runtime/timer.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -120,10 +120,7 @@ if (_active) { _accum = NULL; - if (PrintGCTimeStamps) { - _logfile->stamp(); - _logfile->print(": "); - } + _logfile->stamp(PrintGCTimeStamps); _logfile->print("[%s", title); _logfile->flush(); _t.start(); @@ -141,10 +138,7 @@ _logfile = (logfile != NULL) ? logfile : tty; if (_active) { if (_verbose) { - if (PrintGCTimeStamps) { - _logfile->stamp(); - _logfile->print(": "); - } + _logfile->stamp(PrintGCTimeStamps); _logfile->print("[%s", title); _logfile->flush(); } diff -r fac3dd92ebaf -r ef7fe63a2d39 src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp Wed Sep 19 17:22:49 2012 -0400 +++ b/src/share/vm/utilities/debug.cpp Mon Sep 24 19:00:55 2012 -0400 @@ -101,14 +101,13 @@ void warning(const char* format, ...) { if (PrintWarnings) { - // In case error happens before init or during shutdown - if (tty == NULL) ostream_init(); - - tty->print("%s warning: ", VM_Version::vm_name()); + FILE* const err = defaultStream::error_stream(); + jio_fprintf(err, "%s warning: ", VM_Version::vm_name()); va_list ap; va_start(ap, format); - tty->vprint_cr(format, ap); + vfprintf(err, format, ap); va_end(ap); + fputc('\n', err); } if (BreakAtWarning) BREAKPOINT; }