src/share/vm/memory/metaspace.cpp

Print this page
rev 7105 : 8049599: MetaspaceGC::_capacity_until_GC can overflow
rev 7106 : 8049599: MetaspaceGC::_capacity_until_GC can overflow (01)

*** 1413,1426 **** size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC); assert(value >= MetaspaceSize, "Not initialied properly?"); return value; } ! size_t MetaspaceGC::inc_capacity_until_GC(size_t v) { assert_is_size_aligned(v, Metaspace::commit_alignment()); ! return (size_t)Atomic::add_ptr(v, &_capacity_until_GC); } size_t MetaspaceGC::dec_capacity_until_GC(size_t v) { assert_is_size_aligned(v, Metaspace::commit_alignment()); --- 1413,1447 ---- size_t value = (size_t)OrderAccess::load_ptr_acquire(&_capacity_until_GC); assert(value >= MetaspaceSize, "Not initialied properly?"); return value; } ! bool MetaspaceGC::inc_capacity_until_GC(size_t v, size_t* new_cap_until_GC, size_t* old_cap_until_GC) { assert_is_size_aligned(v, Metaspace::commit_alignment()); ! size_t capacity_until_GC = (size_t) _capacity_until_GC; ! size_t new_value = capacity_until_GC + v; ! ! if (new_value < capacity_until_GC) { ! // the addition wrapped around, set new_value to aligned max value ! new_value = align_size_down(max_uintx, Metaspace::commit_alignment()); ! } ! ! intptr_t expected = (intptr_t) capacity_until_GC; ! intptr_t actual = Atomic::cmpxchg((intptr_t) new_value, &_capacity_until_GC, expected); ! ! if (expected != actual) { ! return false; ! } ! ! if (new_cap_until_GC != NULL) { ! *new_cap_until_GC = new_value; ! } ! if (old_cap_until_GC != NULL) { ! *old_cap_until_GC = capacity_until_GC; ! } ! return true; } size_t MetaspaceGC::dec_capacity_until_GC(size_t v) { assert_is_size_aligned(v, Metaspace::commit_alignment());
*** 1516,1526 **** // increment the HWM. size_t expand_bytes = minimum_desired_capacity - capacity_until_GC; expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment()); // Don't expand unless it's significant if (expand_bytes >= MinMetaspaceExpansion) { ! size_t new_capacity_until_GC = MetaspaceGC::inc_capacity_until_GC(expand_bytes); Metaspace::tracer()->report_gc_threshold(capacity_until_GC, new_capacity_until_GC, MetaspaceGCThresholdUpdater::ComputeNewSize); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr(" expanding:" --- 1537,1550 ---- // increment the HWM. size_t expand_bytes = minimum_desired_capacity - capacity_until_GC; expand_bytes = align_size_up(expand_bytes, Metaspace::commit_alignment()); // Don't expand unless it's significant if (expand_bytes >= MinMetaspaceExpansion) { ! size_t new_capacity_until_GC = 0; ! bool succeeded = MetaspaceGC::inc_capacity_until_GC(expand_bytes, &new_capacity_until_GC); ! assert(succeeded, "Should always succesfully increment HWM when at safepoint"); ! Metaspace::tracer()->report_gc_threshold(capacity_until_GC, new_capacity_until_GC, MetaspaceGCThresholdUpdater::ComputeNewSize); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr(" expanding:"
*** 3319,3341 **** MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) { size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); assert(delta_bytes > 0, "Must be"); ! size_t after_inc = MetaspaceGC::inc_capacity_until_GC(delta_bytes); ! ! // capacity_until_GC might be updated concurrently, must calculate previous value. ! size_t before_inc = after_inc - delta_bytes; tracer()->report_gc_threshold(before_inc, after_inc, MetaspaceGCThresholdUpdater::ExpandAndAllocate); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before_inc, after_inc); } ! return allocate(word_size, mdtype); } // Space allocated in the Metaspace. This may // be across several metadata virtual spaces. char* Metaspace::bottom() const { --- 3343,3374 ---- MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) { size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord); assert(delta_bytes > 0, "Must be"); ! size_t before_inc = 0; ! size_t after_inc = 0; ! MetaWord* res = NULL; ! bool inc_succeeded = false; ! ! while (!inc_succeeded && res == NULL) { ! inc_succeeded = MetaspaceGC::inc_capacity_until_GC(delta_bytes, ! &after_inc, ! &before_inc); ! res = allocate(word_size, mdtype); ! } + if (inc_succeeded) { tracer()->report_gc_threshold(before_inc, after_inc, MetaspaceGCThresholdUpdater::ExpandAndAllocate); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT " to " SIZE_FORMAT, before_inc, after_inc); } + } ! return res; } // Space allocated in the Metaspace. This may // be across several metadata virtual spaces. char* Metaspace::bottom() const {