Mercurial > hg > openjdk > bsd-port > hotspot
changeset 4659:2efcfec8a6dc hs24-b43
Merge
author | amurillo |
---|---|
date | Thu, 02 May 2013 09:56:32 -0700 |
parents | 0599c2274c79 (current diff) 12494ffb721b (diff) |
children | 944e87027dc7 |
files | |
diffstat | 12 files changed, 125 insertions(+), 79 deletions(-) [+] |
line wrap: on
line diff
--- a/make/hotspot_version Wed May 01 14:50:51 2013 -0700 +++ b/make/hotspot_version Thu May 02 09:56:32 2013 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=42 +HS_BUILD_NUMBER=43 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Thu May 02 09:56:32 2013 -0700 @@ -146,43 +146,6 @@ verify(); } -uint CollectionSetChooser::calc_min_old_cset_length() { - // The min old CSet region bound is based on the maximum desired - // number of mixed GCs after a cycle. I.e., even if some old regions - // look expensive, we should add them to the CSet anyway to make - // sure we go through the available old regions in no more than the - // maximum desired number of mixed GCs. - // - // The calculation is based on the number of marked regions we added - // to the CSet chooser in the first place, not how many remain, so - // that the result is the same during all mixed GCs that follow a cycle. - - const size_t region_num = (size_t) _length; - const size_t gc_num = (size_t) G1MixedGCCountTarget; - size_t result = region_num / gc_num; - // emulate ceiling - if (result * gc_num < region_num) { - result += 1; - } - return (uint) result; -} - -uint CollectionSetChooser::calc_max_old_cset_length() { - // The max old CSet region bound is based on the threshold expressed - // as a percentage of the heap size. I.e., it should bound the - // number of old regions added to the CSet irrespective of how many - // of them are available. - - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - const size_t region_num = g1h->n_regions(); - const size_t perc = (size_t) G1OldCSetRegionThresholdPercent; - size_t result = region_num * perc / 100; - // emulate ceiling - if (100 * result < region_num * perc) { - result += 1; - } - return (uint) result; -} void CollectionSetChooser::add_region(HeapRegion* hr) { assert(!hr->isHumongous(),
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Thu May 02 09:56:32 2013 -0700 @@ -51,6 +51,8 @@ uint _curr_index; // The number of candidate old regions added to the CSet chooser. + // Note: this is not updated when removing a region using + // remove_and_move_to_next() below. uint _length; // Keeps track of the start of the next array chunk to be claimed by @@ -111,13 +113,8 @@ hr->live_bytes() < _region_live_threshold_bytes; } - // Calculate the minimum number of old regions we'll add to the CSet - // during a mixed GC. - uint calc_min_old_cset_length(); - - // Calculate the maximum number of old regions we'll add to the CSet - // during a mixed GC. - uint calc_max_old_cset_length(); + // Returns the number candidate old regions added + uint length() { return _length; } // Serial version. void add_region(HeapRegion *hr);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu May 02 09:56:32 2013 -0700 @@ -1809,6 +1809,14 @@ } #endif // !PRODUCT +double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) { + // Returns the given amount of reclaimable bytes (that represents + // the amount of reclaimable space still to be collected) as a + // percentage of the current heap capacity. + size_t capacity_bytes = _g1->capacity(); + return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes; +} + bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str, const char* false_action_str) { CollectionSetChooser* cset_chooser = _collectionSetChooser; @@ -1818,19 +1826,21 @@ ergo_format_reason("candidate old regions not available")); return false; } + + // Is the amount of uncollected reclaimable space above G1HeapWastePercent? size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes(); - size_t capacity_bytes = _g1->capacity(); - double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes; + double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes); double threshold = (double) G1HeapWastePercent; - if (perc < threshold) { + if (reclaimable_perc <= threshold) { ergo_verbose4(ErgoMixedGCs, false_action_str, - ergo_format_reason("reclaimable percentage lower than threshold") + ergo_format_reason("reclaimable percentage not over threshold") ergo_format_region("candidate old regions") ergo_format_byte_perc("reclaimable") ergo_format_perc("threshold"), cset_chooser->remaining_regions(), - reclaimable_bytes, perc, threshold); + reclaimable_bytes, + reclaimable_perc, threshold); return false; } @@ -1841,10 +1851,49 @@ ergo_format_byte_perc("reclaimable") ergo_format_perc("threshold"), cset_chooser->remaining_regions(), - reclaimable_bytes, perc, threshold); + reclaimable_bytes, + reclaimable_perc, threshold); return true; } +uint G1CollectorPolicy::calc_min_old_cset_length() { + // The min old CSet region bound is based on the maximum desired + // number of mixed GCs after a cycle. I.e., even if some old regions + // look expensive, we should add them to the CSet anyway to make + // sure we go through the available old regions in no more than the + // maximum desired number of mixed GCs. + // + // The calculation is based on the number of marked regions we added + // to the CSet chooser in the first place, not how many remain, so + // that the result is the same during all mixed GCs that follow a cycle. + + const size_t region_num = (size_t) _collectionSetChooser->length(); + const size_t gc_num = (size_t) MAX2(G1MixedGCCountTarget, (uintx) 1); + size_t result = region_num / gc_num; + // emulate ceiling + if (result * gc_num < region_num) { + result += 1; + } + return (uint) result; +} + +uint G1CollectorPolicy::calc_max_old_cset_length() { + // The max old CSet region bound is based on the threshold expressed + // as a percentage of the heap size. I.e., it should bound the + // number of old regions added to the CSet irrespective of how many + // of them are available. + + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + const size_t region_num = g1h->n_regions(); + const size_t perc = (size_t) G1OldCSetRegionThresholdPercent; + size_t result = region_num * perc / 100; + // emulate ceiling + if (100 * result < region_num * perc) { + result += 1; + } + return (uint) result; +} + void G1CollectorPolicy::finalize_cset(double target_pause_time_ms, EvacuationInfo& evacuation_info) { double young_start_time_sec = os::elapsedTime(); @@ -1858,7 +1907,7 @@ double base_time_ms = predict_base_elapsed_time_ms(_pending_cards); double predicted_pause_time_ms = base_time_ms; - double time_remaining_ms = target_pause_time_ms - base_time_ms; + double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0); ergo_verbose4(ErgoCSetConstruction | ErgoHigh, "start choosing CSet", @@ -1896,7 +1945,7 @@ _collection_set = _inc_cset_head; _collection_set_bytes_used_before = _inc_cset_bytes_used_before; - time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms; + time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0); predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms; ergo_verbose3(ErgoCSetConstruction | ErgoHigh, @@ -1920,8 +1969,8 @@ if (!gcs_are_young()) { CollectionSetChooser* cset_chooser = _collectionSetChooser; cset_chooser->verify(); - const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length(); - const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length(); + const uint min_old_cset_length = calc_min_old_cset_length(); + const uint max_old_cset_length = calc_max_old_cset_length(); uint expensive_region_num = 0; bool check_time_remaining = adaptive_young_list_length(); @@ -1939,6 +1988,30 @@ break; } + + // Stop adding regions if the remaining reclaimable space is + // not above G1HeapWastePercent. + size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes(); + double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes); + double threshold = (double) G1HeapWastePercent; + if (reclaimable_perc <= threshold) { + // We've added enough old regions that the amount of uncollected + // reclaimable space is at or below the waste threshold. Stop + // adding old regions to the CSet. + ergo_verbose5(ErgoCSetConstruction, + "finish adding old regions to CSet", + ergo_format_reason("reclaimable percentage not over threshold") + ergo_format_region("old") + ergo_format_region("max") + ergo_format_byte_perc("reclaimable") + ergo_format_perc("threshold"), + old_cset_region_length(), + max_old_cset_length, + reclaimable_bytes, + reclaimable_perc, threshold); + break; + } + double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young()); if (check_time_remaining) { if (predicted_time_ms > time_remaining_ms) { @@ -1978,7 +2051,7 @@ } // We will add this region to the CSet. - time_remaining_ms -= predicted_time_ms; + time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0); predicted_pause_time_ms += predicted_time_ms; cset_chooser->remove_and_move_to_next(hr); _g1->old_set_remove(hr);
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu May 02 09:56:32 2013 -0700 @@ -620,6 +620,18 @@ bool predict_will_fit(uint young_length, double base_time_ms, uint base_free_regions, double target_pause_time_ms); + // Calculate the minimum number of old regions we'll add to the CSet + // during a mixed GC. + uint calc_min_old_cset_length(); + + // Calculate the maximum number of old regions we'll add to the CSet + // during a mixed GC. + uint calc_max_old_cset_length(); + + // Returns the given amount of uncollected reclaimable space + // as a percentage of the current heap capacity. + double reclaimable_bytes_perc(size_t reclaimable_bytes); + public: G1CollectorPolicy();
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Thu May 02 09:56:32 2013 -0700 @@ -2173,12 +2173,13 @@ // This kind of CP cache entry does not need to match the flags byte, because // there is a 1-1 relation between bytecode type and CP entry type. ConstantPoolCacheEntry* cache = cp->entry_at(index); - oop result = cache->f1_as_instance(); - if (result == NULL) { + if (cache->f1_as_instance() == NULL) { CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception); - result = cache->f1_as_instance(); + // GC might move cache while returning from VM call. + cache = cp->entry_at(index); // reload } + oop result = cache->f1_as_instance(); VERIFY_OOP(result); SET_STACK_OBJECT(result, 0); @@ -2197,23 +2198,19 @@ u4 index = Bytes::get_native_u4(pc+1); ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index); - oop result = cache->f1_as_instance(); // We are resolved if the f1 field contains a non-null object (CallSite, etc.) // This kind of CP cache entry does not need to match the flags byte, because // there is a 1-1 relation between bytecode type and CP entry type. assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format"); - if (! cache->is_resolved((Bytecodes::Code) opcode)) { + if (cache->is_f1_null()) { CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), handle_exception); - result = cache->f1_as_instance(); + // GC might move cache while returning from VM call. + cache = cp->secondary_entry_at(index); // reload } - VERIFY_OOP(result); - oop method_handle = java_lang_invoke_CallSite::target(result); - CHECK_NULL(method_handle); - - methodOop method = cache->f1_as_method(); + methodOop method = cache->f2_as_vfinal_method(); VERIFY_OOP(method); if (cache->has_appendix()) { @@ -2241,10 +2238,11 @@ if (! cache->is_resolved((Bytecodes::Code) opcode)) { CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD), handle_exception); - cache = cp->entry_at(index); + // GC might move cache while returning from VM call. + cache = cp->entry_at(index); // reload } - methodOop method = cache->f1_as_method(); + methodOop method = cache->f2_as_vfinal_method(); VERIFY_OOP(method);
--- a/src/share/vm/runtime/arguments.cpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/runtime/arguments.cpp Thu May 02 09:56:32 2013 -0700 @@ -1157,7 +1157,6 @@ set_parnew_gc_flags(); } - // MaxHeapSize is aligned down in collectorPolicy size_t max_heap = align_size_down(MaxHeapSize, CardTableRS::ct_max_alignment_constraint()); @@ -1195,10 +1194,6 @@ } // Code along this path potentially sets NewSize and OldSize - - assert(max_heap >= InitialHeapSize, "Error"); - assert(max_heap >= NewSize, "Error"); - if (PrintGCDetails && Verbose) { // Too early to use gclog_or_tty tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT
--- a/src/share/vm/runtime/thread.cpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/runtime/thread.cpp Thu May 02 09:56:32 2013 -0700 @@ -238,7 +238,6 @@ CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;) _jvmti_env_iteration_count = 0; set_allocated_bytes(0); - set_trace_buffer(NULL); _vm_operation_started_count = 0; _vm_operation_completed_count = 0; _current_pending_monitor = NULL;
--- a/src/share/vm/runtime/thread.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/runtime/thread.hpp Thu May 02 09:56:32 2013 -0700 @@ -254,7 +254,7 @@ jlong _allocated_bytes; // Cumulative number of bytes allocated on // the Java heap - TRACE_BUFFER _trace_buffer; // Thread-local buffer for tracing + TRACE_DATA _trace_data; // Thread-local data for tracing int _vm_operation_started_count; // VM_Operation support int _vm_operation_completed_count; // VM_Operation support @@ -442,8 +442,7 @@ return allocated_bytes; } - TRACE_BUFFER trace_buffer() { return _trace_buffer; } - void set_trace_buffer(TRACE_BUFFER buf) { _trace_buffer = buf; } + TRACE_DATA* trace_data() { return &_trace_data; } // VM operation support int vm_operation_ticket() { return ++_vm_operation_started_count; }
--- a/src/share/vm/trace/noTraceBackend.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/trace/noTraceBackend.hpp Thu May 02 09:56:32 2013 -0700 @@ -36,6 +36,11 @@ } }; +class TraceThreadData { +public: + TraceThreadData() {} +}; + typedef NoTraceBackend Tracing; #endif
--- a/src/share/vm/trace/traceBackend.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/trace/traceBackend.hpp Thu May 02 09:56:32 2013 -0700 @@ -52,6 +52,11 @@ } }; +class TraceThreadData { +public: + TraceThreadData() {} +}; + typedef TraceBackend Tracing; #else /* INCLUDE_TRACE */
--- a/src/share/vm/trace/traceMacros.hpp Wed May 01 14:50:51 2013 -0700 +++ b/src/share/vm/trace/traceMacros.hpp Thu May 02 09:56:32 2013 -0700 @@ -28,7 +28,7 @@ #define EVENT_THREAD_EXIT(thread) #define TRACE_INIT_ID(k) -#define TRACE_BUFFER void* +#define TRACE_DATA TraceThreadData #define TRACE_START() JNI_OK #define TRACE_INITIALIZE() JNI_OK