This commit is contained in:
J. Duke 2017-07-05 19:59:57 +02:00
commit e86014216f
301 changed files with 11688 additions and 5074 deletions

View File

@ -271,3 +271,4 @@ aefd8899a8d6615fb34ba99b2e38996a7145baa8 jdk9-b25
d3ec8d048e6c3c46b6e0ee011cc551ad386dfba5 jdk9-b26 d3ec8d048e6c3c46b6e0ee011cc551ad386dfba5 jdk9-b26
ba5645f2735b41ed085d07ba20fa7b322afff318 jdk9-b27 ba5645f2735b41ed085d07ba20fa7b322afff318 jdk9-b27
ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28 ea2f7981236f3812436958748ab3d26e80a35130 jdk9-b28
9e6581aeda388a23fbee021fc33e6aa152a60657 jdk9-b29

View File

@ -271,3 +271,4 @@ da08cca6b97f41b7081a3e176dcb400af6e4bb26 jdk9-b25
6c777df597bbf5abba3488d44c401edfe73c74af jdk9-b26 6c777df597bbf5abba3488d44c401edfe73c74af jdk9-b26
7e06bf1dcb0907b80ddf59315426ce9ce775e56d jdk9-b27 7e06bf1dcb0907b80ddf59315426ce9ce775e56d jdk9-b27
a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28 a00b04ef067e39f50b9a0fea6f1904e35d632a73 jdk9-b28
163a9cd806fd09970baf1f5f42b92a3cfe7ee945 jdk9-b29

View File

@ -431,3 +431,4 @@ dde2d03b0ea46a27650839e3a1d212c7c1f7b4c8 jdk9-b24
48b95a073d752d6891cc0d1d2836b321ecf3ce0c jdk9-b26 48b95a073d752d6891cc0d1d2836b321ecf3ce0c jdk9-b26
f95347244306affc32ce3056f27ceff7b2100810 jdk9-b27 f95347244306affc32ce3056f27ceff7b2100810 jdk9-b27
657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28 657294869d7ff063e055f5492cab7ce5612ca851 jdk9-b28
deb29e92f68ace2808a36ecfa18c7d61dcb645bb jdk9-b29

View File

@ -43,8 +43,8 @@ import sun.jvm.hotspot.types.TypeDataBase;
// Mirror class for G1CollectedHeap. // Mirror class for G1CollectedHeap.
public class G1CollectedHeap extends SharedHeap { public class G1CollectedHeap extends SharedHeap {
// HeapRegionSeq _seq; // HeapRegionManager _hrm;
static private long hrsFieldOffset; static private long hrmFieldOffset;
// MemRegion _g1_reserved; // MemRegion _g1_reserved;
static private long g1ReservedFieldOffset; static private long g1ReservedFieldOffset;
// size_t _summary_bytes_used; // size_t _summary_bytes_used;
@ -67,7 +67,7 @@ public class G1CollectedHeap extends SharedHeap {
static private synchronized void initialize(TypeDataBase db) { static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("G1CollectedHeap"); Type type = db.lookupType("G1CollectedHeap");
hrsFieldOffset = type.getField("_hrs").getOffset(); hrmFieldOffset = type.getField("_hrm").getOffset();
summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used"); summaryBytesUsedField = type.getCIntegerField("_summary_bytes_used");
g1mmField = type.getAddressField("_g1mm"); g1mmField = type.getAddressField("_g1mm");
oldSetFieldOffset = type.getField("_old_set").getOffset(); oldSetFieldOffset = type.getField("_old_set").getOffset();
@ -75,7 +75,7 @@ public class G1CollectedHeap extends SharedHeap {
} }
public long capacity() { public long capacity() {
return hrs().capacity(); return hrm().capacity();
} }
public long used() { public long used() {
@ -83,13 +83,13 @@ public class G1CollectedHeap extends SharedHeap {
} }
public long n_regions() { public long n_regions() {
return hrs().length(); return hrm().length();
} }
private HeapRegionSeq hrs() { private HeapRegionManager hrm() {
Address hrsAddr = addr.addOffsetTo(hrsFieldOffset); Address hrmAddr = addr.addOffsetTo(hrmFieldOffset);
return (HeapRegionSeq) VMObjectFactory.newObject(HeapRegionSeq.class, return (HeapRegionManager) VMObjectFactory.newObject(HeapRegionManager.class,
hrsAddr); hrmAddr);
} }
public G1MonitoringSupport g1mm() { public G1MonitoringSupport g1mm() {
@ -110,7 +110,7 @@ public class G1CollectedHeap extends SharedHeap {
} }
private Iterator<HeapRegion> heapRegionIterator() { private Iterator<HeapRegion> heapRegionIterator() {
return hrs().heapRegionIterator(); return hrm().heapRegionIterator();
} }
public void heapRegionIterate(SpaceClosure scl) { public void heapRegionIterate(SpaceClosure scl) {

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,9 +37,9 @@ import sun.jvm.hotspot.types.CIntegerField;
import sun.jvm.hotspot.types.Type; import sun.jvm.hotspot.types.Type;
import sun.jvm.hotspot.types.TypeDataBase; import sun.jvm.hotspot.types.TypeDataBase;
// Mirror class for HeapRegionSeq. It essentially encapsulates the G1HeapRegionTable. // Mirror class for HeapRegionManager.
public class HeapRegionSeq extends VMObject { public class HeapRegionManager extends VMObject {
// G1HeapRegionTable _regions // G1HeapRegionTable _regions
static private long regionsFieldOffset; static private long regionsFieldOffset;
// uint _committed_length // uint _committed_length
@ -54,7 +54,7 @@ public class HeapRegionSeq extends VMObject {
} }
static private synchronized void initialize(TypeDataBase db) { static private synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("HeapRegionSeq"); Type type = db.lookupType("HeapRegionManager");
regionsFieldOffset = type.getField("_regions").getOffset(); regionsFieldOffset = type.getField("_regions").getOffset();
numCommittedField = type.getCIntegerField("_num_committed"); numCommittedField = type.getCIntegerField("_num_committed");
@ -82,7 +82,7 @@ public class HeapRegionSeq extends VMObject {
return regions().heapRegionIterator(length()); return regions().heapRegionIterator(length());
} }
public HeapRegionSeq(Address addr) { public HeapRegionManager(Address addr) {
super(addr); super(addr);
} }
} }

View File

@ -721,6 +721,19 @@ copy_debug_jdk::
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \ ($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
fi fi
copy_optimized_jdk::
$(RM) -r $(JDK_IMAGE_DIR)/optimized
$(MKDIR) -p $(JDK_IMAGE_DIR)/optimized
if [ -d $(JDK_IMPORT_PATH)/optimized ] ; then \
($(CD) $(JDK_IMPORT_PATH)/optimized && \
$(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
else \
($(CD) $(JDK_IMPORT_PATH) && \
$(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/optimized && $(TAR) -xf -) ; \
fi
# #
# Check target # Check target
# #

View File

@ -42,6 +42,9 @@ jprt_build_debugEmb:
jprt_build_fastdebugEmb: jprt_build_fastdebugEmb:
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug $(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_fastdebug
jprt_build_optimizedEmb:
$(MAKE) JAVASE_EMBEDDED=true MINIMIZE_RAM_USAGE=true jprt_build_optimized
jprt_build_productOpen: jprt_build_productOpen:
$(MAKE) OPENJDK=true jprt_build_product $(MAKE) OPENJDK=true jprt_build_product
@ -51,6 +54,9 @@ jprt_build_debugOpen:
jprt_build_fastdebugOpen: jprt_build_fastdebugOpen:
$(MAKE) OPENJDK=true jprt_build_fastdebug $(MAKE) OPENJDK=true jprt_build_fastdebug
jprt_build_optimizedOpen:
$(MAKE) OPENJDK=true jprt_build_optimized
jprt_build_product: all_product copy_product_jdk export_product_jdk jprt_build_product: all_product copy_product_jdk export_product_jdk
( $(CD) $(JDK_IMAGE_DIR) && \ ( $(CD) $(JDK_IMAGE_DIR) && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . ) $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
@ -63,5 +69,9 @@ jprt_build_debug: all_debug copy_debug_jdk export_debug_jdk
( $(CD) $(JDK_IMAGE_DIR)/debug && \ ( $(CD) $(JDK_IMAGE_DIR)/debug && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . ) $(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug jprt_build_optimized: all_optimized copy_optimized_jdk export_optimized_jdk
( $(CD) $(JDK_IMAGE_DIR)/optimized && \
$(ZIPEXE) $(ZIPFLAGS) -r $(JPRT_ARCHIVE_BUNDLE) . )
.PHONY: jprt_build_product jprt_build_fastdebug jprt_build_debug jprt_build_optimized

View File

@ -93,13 +93,13 @@ jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
# Standard list of jprt build targets for this source tree # Standard list of jprt build targets for this source tree
jprt.build.targets.standard= \ jprt.build.targets.standard= \
${jprt.my.solaris.sparcv9}-{product|fastdebug|optimized}, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}, \
${jprt.my.solaris.x64}-{product|fastdebug}, \ ${jprt.my.solaris.x64}-{product|fastdebug}, \
${jprt.my.linux.i586}-{product|fastdebug}, \ ${jprt.my.linux.i586}-{product|fastdebug}, \
${jprt.my.linux.x64}-{product|fastdebug|optimized}, \ ${jprt.my.linux.x64}-{product|fastdebug}, \
${jprt.my.macosx.x64}-{product|fastdebug}, \ ${jprt.my.macosx.x64}-{product|fastdebug}, \
${jprt.my.windows.i586}-{product|fastdebug}, \ ${jprt.my.windows.i586}-{product|fastdebug}, \
${jprt.my.windows.x64}-{product|fastdebug|optimized}, \ ${jprt.my.windows.x64}-{product|fastdebug}, \
${jprt.my.linux.armvh}-{product|fastdebug} ${jprt.my.linux.armvh}-{product|fastdebug}
jprt.build.targets.open= \ jprt.build.targets.open= \

View File

@ -34,6 +34,9 @@ ALTSRC=$(WorkSpace)\src\closed
CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT" CXX_FLAGS=$(CXX_FLAGS) /D "PRODUCT"
!else !else
CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT" CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
!if "$(BUILDARCH)" == "amd64"
CXX_FLAGS=$(CXX_FLAGS) /homeparams
!endif
!endif !endif
!if "$(Variant)" == "compiler1" !if "$(Variant)" == "compiler1"

View File

@ -604,6 +604,17 @@ void VM_Version::get_processor_features() {
#if INCLUDE_RTM_OPT #if INCLUDE_RTM_OPT
if (UseRTMLocking) { if (UseRTMLocking) {
if (is_intel_family_core()) {
if ((_model == CPU_MODEL_HASWELL_E3) ||
(_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
(_model == CPU_MODEL_BROADWELL && _stepping < 4)) {
if (!UnlockExperimentalVMOptions) {
vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
} else {
warning("UseRTMLocking is only available as experimental option on this platform.");
}
}
}
if (!FLAG_IS_CMDLINE(UseRTMLocking)) { if (!FLAG_IS_CMDLINE(UseRTMLocking)) {
// RTM locking should be used only for applications with // RTM locking should be used only for applications with
// high lock contention. For now we do not use it by default. // high lock contention. For now we do not use it by default.

View File

@ -276,7 +276,10 @@ protected:
CPU_MODEL_WESTMERE_EX = 0x2f, CPU_MODEL_WESTMERE_EX = 0x2f,
CPU_MODEL_SANDYBRIDGE = 0x2a, CPU_MODEL_SANDYBRIDGE = 0x2a,
CPU_MODEL_SANDYBRIDGE_EP = 0x2d, CPU_MODEL_SANDYBRIDGE_EP = 0x2d,
CPU_MODEL_IVYBRIDGE_EP = 0x3a CPU_MODEL_IVYBRIDGE_EP = 0x3a,
CPU_MODEL_HASWELL_E3 = 0x3c,
CPU_MODEL_HASWELL_E7 = 0x3f,
CPU_MODEL_BROADWELL = 0x3d
} cpuExtendedFamily; } cpuExtendedFamily;
// cpuid information block. All info derived from executing cpuid with // cpuid information block. All info derived from executing cpuid with

View File

@ -135,11 +135,6 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) {
if (ForceTimeHighResolution) if (ForceTimeHighResolution)
timeEndPeriod(1L); timeEndPeriod(1L);
// Workaround for issue when a custom launcher doesn't call
// DestroyJavaVM and NMT is trying to track memory when free is
// called from a static destructor
MemTracker::shutdown();
break; break;
default: default:
break; break;
@ -414,6 +409,8 @@ struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo); LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo);
extern jint volatile vm_getting_terminated;
// Thread start routine for all new Java threads // Thread start routine for all new Java threads
static unsigned __stdcall java_start(Thread* thread) { static unsigned __stdcall java_start(Thread* thread) {
// Try to randomize the cache line index of hot stack frames. // Try to randomize the cache line index of hot stack frames.
@ -435,9 +432,17 @@ static unsigned __stdcall java_start(Thread* thread) {
} }
} }
// Diagnostic code to investigate JDK-6573254 (Part I)
unsigned res = 90115; // non-java thread
if (thread->is_Java_thread()) {
JavaThread* java_thread = (JavaThread*)thread;
res = java_lang_Thread::is_daemon(java_thread->threadObj())
? 70115 // java daemon thread
: 80115; // java non-daemon thread
}
// Install a win32 structured exception handler around every thread created // Install a win32 structured exception handler around every thread created
// by VM, so VM can genrate error dump when an exception occurred in non- // by VM, so VM can generate error dump when an exception occurred in non-
// Java thread (e.g. VM thread). // Java thread (e.g. VM thread).
__try { __try {
thread->run(); thread->run();
@ -453,6 +458,11 @@ static unsigned __stdcall java_start(Thread* thread) {
Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count); Atomic::dec_ptr((intptr_t*)&os::win32::_os_thread_count);
} }
// Diagnostic code to investigate JDK-6573254 (Part II)
if (OrderAccess::load_acquire(&vm_getting_terminated)) {
return res;
}
return 0; return 0;
} }

View File

@ -504,7 +504,7 @@ abstract class GenericDebugConfig extends BuildConfig {
super.init(includes, defines); super.init(includes, defines);
getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag())); getV("CompilerFlags").addAll(getCI().getDebugCompilerFlags(getOptFlag(), get("PlatformName")));
getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags()); getV("LinkerFlags").addAll(getCI().getDebugLinkerFlags());
} }
} }
@ -619,7 +619,7 @@ class TieredProductConfig extends ProductConfig {
abstract class CompilerInterface { abstract class CompilerInterface {
abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName); abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);
abstract Vector getDebugCompilerFlags(String opt); abstract Vector getDebugCompilerFlags(String opt, String platformName);
abstract Vector getDebugLinkerFlags(); abstract Vector getDebugLinkerFlags();
abstract void getAdditionalNonKernelLinkerFlags(Vector rv); abstract void getAdditionalNonKernelLinkerFlags(Vector rv);
abstract Vector getProductCompilerFlags(); abstract Vector getProductCompilerFlags();

View File

@ -357,7 +357,7 @@ class CompilerInterfaceVC10 extends CompilerInterface {
} }
@Override @Override
Vector getDebugCompilerFlags(String opt) { Vector getDebugCompilerFlags(String opt, String platformName) {
Vector rv = new Vector(); Vector rv = new Vector();
// Set /On option // Set /On option
@ -369,6 +369,10 @@ class CompilerInterfaceVC10 extends CompilerInterface {
addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL"); addAttr(rv, "RuntimeLibrary", "MultiThreadedDLL");
// Set /Oy- option // Set /Oy- option
addAttr(rv, "OmitFramePointers", "false"); addAttr(rv, "OmitFramePointers", "false");
// Set /homeparams for x64 debug builds
if(platformName.equals("x64")) {
addAttr(rv, "AdditionalOptions", "/homeparams");
}
return rv; return rv;
} }

View File

@ -284,7 +284,7 @@ class CompilerInterfaceVC7 extends CompilerInterface {
} }
Vector getDebugCompilerFlags(String opt) { Vector getDebugCompilerFlags(String opt, String platformName) {
Vector rv = new Vector(); Vector rv = new Vector();
getDebugCompilerFlags_common(opt, rv); getDebugCompilerFlags_common(opt, rv);

View File

@ -48,7 +48,7 @@ class CompilerInterfaceVC8 extends CompilerInterfaceVC7 {
} }
Vector getDebugCompilerFlags(String opt) { Vector getDebugCompilerFlags(String opt, String platformName) {
Vector rv = new Vector(); Vector rv = new Vector();
getDebugCompilerFlags_common(opt,rv); getDebugCompilerFlags_common(opt,rv);

View File

@ -328,9 +328,11 @@ AdaptiveSizePolicy* CMSCollector::size_policy() {
void ConcurrentMarkSweepGeneration::initialize_performance_counters() { void ConcurrentMarkSweepGeneration::initialize_performance_counters() {
const char* gen_name = "old"; const char* gen_name = "old";
GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
// Generation Counters - generation 1, 1 subspace // Generation Counters - generation 1, 1 subspace
_gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space); _gen_counters = new GenerationCounters(gen_name, 1, 1,
gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
_space_counters = new GSpaceCounters(gen_name, 0, _space_counters = new GSpaceCounters(gen_name, 0,
_virtual_space.reserved_size(), _virtual_space.reserved_size(),

View File

@ -34,8 +34,8 @@
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.hpp" #include "gc_implementation/g1/g1RemSet.hpp"
#include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp"
#include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "gc_implementation/g1/heapRegionSet.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp" #include "gc_implementation/shared/vmGCOperations.hpp"
#include "gc_implementation/shared/gcTimer.hpp" #include "gc_implementation/shared/gcTimer.hpp"
@ -434,10 +434,6 @@ void CMMarkStack::oops_do(OopClosure* f) {
} }
} }
bool ConcurrentMark::not_yet_marked(oop obj) const {
return _g1h->is_obj_ill(obj);
}
CMRootRegions::CMRootRegions() : CMRootRegions::CMRootRegions() :
_young_list(NULL), _cm(NULL), _scan_in_progress(false), _young_list(NULL), _cm(NULL), _scan_in_progress(false),
_should_abort(false), _next_survivor(NULL) { } _should_abort(false), _next_survivor(NULL) { }
@ -892,7 +888,16 @@ class CheckBitmapClearHRClosure : public HeapRegionClosure {
} }
virtual bool doHeapRegion(HeapRegion* r) { virtual bool doHeapRegion(HeapRegion* r) {
return _bitmap->getNextMarkedWordAddress(r->bottom(), r->end()) != r->end(); // This closure can be called concurrently to the mutator, so we must make sure
// that the result of the getNextMarkedWordAddress() call is compared to the
// value passed to it as limit to detect any found bits.
// We can use the region's orig_end() for the limit and the comparison value
// as it always contains the "real" end of the region that never changes and
// has no side effects.
// Due to the latter, there can also be no problem with the compiler generating
// reloads of the orig_end() call.
HeapWord* end = r->orig_end();
return _bitmap->getNextMarkedWordAddress(r->bottom(), end) != end;
} }
}; };
@ -1117,20 +1122,17 @@ public:
if (!_cm->has_aborted()) { if (!_cm->has_aborted()) {
do { do {
double start_vtime_sec = os::elapsedVTime(); double start_vtime_sec = os::elapsedVTime();
double start_time_sec = os::elapsedTime();
double mark_step_duration_ms = G1ConcMarkStepDurationMillis; double mark_step_duration_ms = G1ConcMarkStepDurationMillis;
the_task->do_marking_step(mark_step_duration_ms, the_task->do_marking_step(mark_step_duration_ms,
true /* do_termination */, true /* do_termination */,
false /* is_serial*/); false /* is_serial*/);
double end_time_sec = os::elapsedTime();
double end_vtime_sec = os::elapsedVTime(); double end_vtime_sec = os::elapsedVTime();
double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec; double elapsed_vtime_sec = end_vtime_sec - start_vtime_sec;
double elapsed_time_sec = end_time_sec - start_time_sec;
_cm->clear_has_overflown(); _cm->clear_has_overflown();
bool ret = _cm->do_yield_check(worker_id); _cm->do_yield_check(worker_id);
jlong sleep_time_ms; jlong sleep_time_ms;
if (!_cm->has_aborted() && the_task->has_aborted()) { if (!_cm->has_aborted() && the_task->has_aborted()) {
@ -1140,17 +1142,6 @@ public:
os::sleep(Thread::current(), sleep_time_ms, false); os::sleep(Thread::current(), sleep_time_ms, false);
SuspendibleThreadSet::join(); SuspendibleThreadSet::join();
} }
double end_time2_sec = os::elapsedTime();
double elapsed_time2_sec = end_time2_sec - start_time_sec;
#if 0
gclog_or_tty->print_cr("CM: elapsed %1.4lf ms, sleep %1.4lf ms, "
"overhead %1.4lf",
elapsed_vtime_sec * 1000.0, (double) sleep_time_ms,
the_task->conc_overhead(os::elapsedTime()) * 8.0);
gclog_or_tty->print_cr("elapsed time %1.4lf ms, time 2: %1.4lf ms",
elapsed_time_sec * 1000.0, elapsed_time2_sec * 1000.0);
#endif
} while (!_cm->has_aborted() && the_task->has_aborted()); } while (!_cm->has_aborted() && the_task->has_aborted());
} }
the_task->record_end_time(); the_task->record_end_time();
@ -1409,7 +1400,7 @@ protected:
void set_bit_for_region(HeapRegion* hr) { void set_bit_for_region(HeapRegion* hr) {
assert(!hr->continuesHumongous(), "should have filtered those out"); assert(!hr->continuesHumongous(), "should have filtered those out");
BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index(); BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
if (!hr->startsHumongous()) { if (!hr->startsHumongous()) {
// Normal (non-humongous) case: just set the bit. // Normal (non-humongous) case: just set the bit.
_region_bm->par_at_put(index, true); _region_bm->par_at_put(index, true);
@ -1597,7 +1588,7 @@ public:
if (_verbose) { if (_verbose) {
gclog_or_tty->print_cr("Region %u: marked bytes mismatch: " gclog_or_tty->print_cr("Region %u: marked bytes mismatch: "
"expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT, "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
hr->hrs_index(), exp_marked_bytes, act_marked_bytes); hr->hrm_index(), exp_marked_bytes, act_marked_bytes);
} }
failures += 1; failures += 1;
} }
@ -1606,7 +1597,7 @@ public:
// (which was just calculated) region bit maps. // (which was just calculated) region bit maps.
// We're not OK if the bit in the calculated expected region // We're not OK if the bit in the calculated expected region
// bitmap is set and the bit in the actual region bitmap is not. // bitmap is set and the bit in the actual region bitmap is not.
BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index(); BitMap::idx_t index = (BitMap::idx_t) hr->hrm_index();
bool expected = _exp_region_bm->at(index); bool expected = _exp_region_bm->at(index);
bool actual = _region_bm->at(index); bool actual = _region_bm->at(index);
@ -1614,7 +1605,7 @@ public:
if (_verbose) { if (_verbose) {
gclog_or_tty->print_cr("Region %u: region bitmap mismatch: " gclog_or_tty->print_cr("Region %u: region bitmap mismatch: "
"expected: %s, actual: %s", "expected: %s, actual: %s",
hr->hrs_index(), hr->hrm_index(),
BOOL_TO_STR(expected), BOOL_TO_STR(actual)); BOOL_TO_STR(expected), BOOL_TO_STR(actual));
} }
failures += 1; failures += 1;
@ -1635,7 +1626,7 @@ public:
if (_verbose) { if (_verbose) {
gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": " gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": "
"expected: %s, actual: %s", "expected: %s, actual: %s",
hr->hrs_index(), i, hr->hrm_index(), i,
BOOL_TO_STR(expected), BOOL_TO_STR(actual)); BOOL_TO_STR(expected), BOOL_TO_STR(actual));
} }
failures += 1; failures += 1;
@ -2949,11 +2940,6 @@ void ConcurrentMark::clearRangeNextBitmap(MemRegion mr) {
_nextMarkBitMap->clearRange(mr); _nextMarkBitMap->clearRange(mr);
} }
void ConcurrentMark::clearRangeBothBitmaps(MemRegion mr) {
clearRangePrevBitmap(mr);
clearRangeNextBitmap(mr);
}
HeapRegion* HeapRegion*
ConcurrentMark::claim_region(uint worker_id) { ConcurrentMark::claim_region(uint worker_id) {
// "checkpoint" the finger // "checkpoint" the finger
@ -3256,7 +3242,7 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
assert(limit_idx <= end_idx, "or else use atomics"); assert(limit_idx <= end_idx, "or else use atomics");
// Aggregate the "stripe" in the count data associated with hr. // Aggregate the "stripe" in the count data associated with hr.
uint hrs_index = hr->hrs_index(); uint hrm_index = hr->hrm_index();
size_t marked_bytes = 0; size_t marked_bytes = 0;
for (uint i = 0; i < _max_worker_id; i += 1) { for (uint i = 0; i < _max_worker_id; i += 1) {
@ -3265,7 +3251,7 @@ class AggregateCountDataHRClosure: public HeapRegionClosure {
// Fetch the marked_bytes in this region for task i and // Fetch the marked_bytes in this region for task i and
// add it to the running total for this region. // add it to the running total for this region.
marked_bytes += marked_bytes_array[hrs_index]; marked_bytes += marked_bytes_array[hrm_index];
// Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx) // Now union the bitmaps[0,max_worker_id)[start_idx..limit_idx)
// into the global card bitmap. // into the global card bitmap.
@ -3499,17 +3485,6 @@ bool ConcurrentMark::do_yield_check(uint worker_id) {
} }
} }
bool ConcurrentMark::containing_card_is_marked(void* p) {
size_t offset = pointer_delta(p, _g1h->reserved_region().start(), 1);
return _card_bm.at(offset >> CardTableModRefBS::card_shift);
}
bool ConcurrentMark::containing_cards_are_marked(void* start,
void* last) {
return containing_card_is_marked(start) &&
containing_card_is_marked(last);
}
#ifndef PRODUCT #ifndef PRODUCT
// for debugging purposes // for debugging purposes
void ConcurrentMark::print_finger() { void ConcurrentMark::print_finger() {
@ -3762,7 +3737,7 @@ void CMTask::regular_clock_call() {
if (_cm->verbose_medium()) { if (_cm->verbose_medium()) {
gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, " gclog_or_tty->print_cr("[%u] regular clock, interval = %1.2lfms, "
"scanned = %d%s, refs reached = %d%s", "scanned = "SIZE_FORMAT"%s, refs reached = "SIZE_FORMAT"%s",
_worker_id, last_interval_ms, _worker_id, last_interval_ms,
_words_scanned, _words_scanned,
(_words_scanned >= _words_scanned_limit) ? " (*)" : "", (_words_scanned >= _words_scanned_limit) ? " (*)" : "",

View File

@ -683,7 +683,9 @@ public:
return _task_queues->steal(worker_id, hash_seed, obj); return _task_queues->steal(worker_id, hash_seed, obj);
} }
ConcurrentMark(G1CollectedHeap* g1h, G1RegionToSpaceMapper* prev_bitmap_storage, G1RegionToSpaceMapper* next_bitmap_storage); ConcurrentMark(G1CollectedHeap* g1h,
G1RegionToSpaceMapper* prev_bitmap_storage,
G1RegionToSpaceMapper* next_bitmap_storage);
~ConcurrentMark(); ~ConcurrentMark();
ConcurrentMarkThread* cmThread() { return _cmThread; } ConcurrentMarkThread* cmThread() { return _cmThread; }
@ -712,8 +714,10 @@ public:
// inconsistent) and always passing the size. hr is the region that // inconsistent) and always passing the size. hr is the region that
// contains the object and it's passed optionally from callers who // contains the object and it's passed optionally from callers who
// might already have it (no point in recalculating it). // might already have it (no point in recalculating it).
inline void grayRoot(oop obj, size_t word_size, inline void grayRoot(oop obj,
uint worker_id, HeapRegion* hr = NULL); size_t word_size,
uint worker_id,
HeapRegion* hr = NULL);
// It iterates over the heap and for each object it comes across it // It iterates over the heap and for each object it comes across it
// will dump the contents of its reference fields, as well as // will dump the contents of its reference fields, as well as
@ -734,7 +738,8 @@ public:
// AND MARKED : indicates that an object is both explicitly and // AND MARKED : indicates that an object is both explicitly and
// implicitly live (it should be one or the other, not both) // implicitly live (it should be one or the other, not both)
void print_reachable(const char* str, void print_reachable(const char* str,
VerifyOption vo, bool all) PRODUCT_RETURN; VerifyOption vo,
bool all) PRODUCT_RETURN;
// Clear the next marking bitmap (will be called concurrently). // Clear the next marking bitmap (will be called concurrently).
void clearNextBitmap(); void clearNextBitmap();
@ -771,12 +776,11 @@ public:
// this carefully! // this carefully!
inline void markPrev(oop p); inline void markPrev(oop p);
// Clears marks for all objects in the given range, for the prev, // Clears marks for all objects in the given range, for the prev or
// next, or both bitmaps. NB: the previous bitmap is usually // next bitmaps. NB: the previous bitmap is usually
// read-only, so use this carefully! // read-only, so use this carefully!
void clearRangePrevBitmap(MemRegion mr); void clearRangePrevBitmap(MemRegion mr);
void clearRangeNextBitmap(MemRegion mr); void clearRangeNextBitmap(MemRegion mr);
void clearRangeBothBitmaps(MemRegion mr);
// Notify data structures that a GC has started. // Notify data structures that a GC has started.
void note_start_of_gc() { void note_start_of_gc() {
@ -798,21 +802,6 @@ public:
bool verify_thread_buffers, bool verify_thread_buffers,
bool verify_fingers) PRODUCT_RETURN; bool verify_fingers) PRODUCT_RETURN;
bool isMarked(oop p) const {
assert(p != NULL && p->is_oop(), "expected an oop");
HeapWord* addr = (HeapWord*)p;
assert(addr >= _nextMarkBitMap->startWord() ||
addr < _nextMarkBitMap->endWord(), "in a region");
return _nextMarkBitMap->isMarked(addr);
}
inline bool not_yet_marked(oop p) const;
// XXX Debug code
bool containing_card_is_marked(void* p);
bool containing_cards_are_marked(void* start, void* last);
bool isPrevMarked(oop p) const { bool isPrevMarked(oop p) const {
assert(p != NULL && p->is_oop(), "expected an oop"); assert(p != NULL && p->is_oop(), "expected an oop");
HeapWord* addr = (HeapWord*)p; HeapWord* addr = (HeapWord*)p;
@ -898,7 +887,8 @@ public:
// marked_bytes array slot for the given HeapRegion. // marked_bytes array slot for the given HeapRegion.
// Sets the bits in the given card bitmap that are associated with the // Sets the bits in the given card bitmap that are associated with the
// cards that are spanned by the memory region. // cards that are spanned by the memory region.
inline void count_region(MemRegion mr, HeapRegion* hr, inline void count_region(MemRegion mr,
HeapRegion* hr,
size_t* marked_bytes_array, size_t* marked_bytes_array,
BitMap* task_card_bm); BitMap* task_card_bm);
@ -906,56 +896,27 @@ public:
// data structures for the given worker id. // data structures for the given worker id.
inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id); inline void count_region(MemRegion mr, HeapRegion* hr, uint worker_id);
// Counts the given memory region in the task/worker counting
// data structures for the given worker id.
inline void count_region(MemRegion mr, uint worker_id);
// Counts the given object in the given task/worker counting // Counts the given object in the given task/worker counting
// data structures. // data structures.
inline void count_object(oop obj, HeapRegion* hr, inline void count_object(oop obj,
HeapRegion* hr,
size_t* marked_bytes_array, size_t* marked_bytes_array,
BitMap* task_card_bm); BitMap* task_card_bm);
// Counts the given object in the task/worker counting data
// structures for the given worker id.
inline void count_object(oop obj, HeapRegion* hr, uint worker_id);
// Attempts to mark the given object and, if successful, counts // Attempts to mark the given object and, if successful, counts
// the object in the given task/worker counting structures. // the object in the given task/worker counting structures.
inline bool par_mark_and_count(oop obj, HeapRegion* hr, inline bool par_mark_and_count(oop obj,
HeapRegion* hr,
size_t* marked_bytes_array, size_t* marked_bytes_array,
BitMap* task_card_bm); BitMap* task_card_bm);
// Attempts to mark the given object and, if successful, counts // Attempts to mark the given object and, if successful, counts
// the object in the task/worker counting structures for the // the object in the task/worker counting structures for the
// given worker id. // given worker id.
inline bool par_mark_and_count(oop obj, size_t word_size, inline bool par_mark_and_count(oop obj,
HeapRegion* hr, uint worker_id); size_t word_size,
HeapRegion* hr,
// Attempts to mark the given object and, if successful, counts uint worker_id);
// the object in the task/worker counting structures for the
// given worker id.
inline bool par_mark_and_count(oop obj, HeapRegion* hr, uint worker_id);
// Similar to the above routine but we don't know the heap region that
// contains the object to be marked/counted, which this routine looks up.
inline bool par_mark_and_count(oop obj, uint worker_id);
// Similar to the above routine but there are times when we cannot
// safely calculate the size of obj due to races and we, therefore,
// pass the size in as a parameter. It is the caller's responsibility
// to ensure that the size passed in for obj is valid.
inline bool par_mark_and_count(oop obj, size_t word_size, uint worker_id);
// Unconditionally mark the given object, and unconditionally count
// the object in the counting structures for worker id 0.
// Should *not* be called from parallel code.
inline bool mark_and_count(oop obj, HeapRegion* hr);
// Similar to the above routine but we don't know the heap region that
// contains the object to be marked/counted, which this routine looks up.
// Should *not* be called from parallel code.
inline bool mark_and_count(oop obj);
// Returns true if initialization was successfully completed. // Returns true if initialization was successfully completed.
bool completed_initialization() const { bool completed_initialization() const {
@ -1227,9 +1188,12 @@ public:
_finger = new_finger; _finger = new_finger;
} }
CMTask(uint worker_id, ConcurrentMark *cm, CMTask(uint worker_id,
size_t* marked_bytes, BitMap* card_bm, ConcurrentMark *cm,
CMTaskQueue* task_queue, CMTaskQueueSet* task_queues); size_t* marked_bytes,
BitMap* card_bm,
CMTaskQueue* task_queue,
CMTaskQueueSet* task_queues);
// it prints statistics associated with this task // it prints statistics associated with this task
void print_stats(); void print_stats();

View File

@ -86,7 +86,7 @@ inline void ConcurrentMark::count_region(MemRegion mr, HeapRegion* hr,
HeapWord* start = mr.start(); HeapWord* start = mr.start();
HeapWord* end = mr.end(); HeapWord* end = mr.end();
size_t region_size_bytes = mr.byte_size(); size_t region_size_bytes = mr.byte_size();
uint index = hr->hrs_index(); uint index = hr->hrm_index();
assert(!hr->continuesHumongous(), "should not be HC region"); assert(!hr->continuesHumongous(), "should not be HC region");
assert(hr == g1h->heap_region_containing(start), "sanity"); assert(hr == g1h->heap_region_containing(start), "sanity");
@ -125,14 +125,6 @@ inline void ConcurrentMark::count_region(MemRegion mr,
count_region(mr, hr, marked_bytes_array, task_card_bm); count_region(mr, hr, marked_bytes_array, task_card_bm);
} }
// Counts the given memory region, which may be a single object, in the
// task/worker counting data structures for the given worker id.
inline void ConcurrentMark::count_region(MemRegion mr, uint worker_id) {
HeapWord* addr = mr.start();
HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
count_region(mr, hr, worker_id);
}
// Counts the given object in the given task/worker counting data structures. // Counts the given object in the given task/worker counting data structures.
inline void ConcurrentMark::count_object(oop obj, inline void ConcurrentMark::count_object(oop obj,
HeapRegion* hr, HeapRegion* hr,
@ -142,17 +134,6 @@ inline void ConcurrentMark::count_object(oop obj,
count_region(mr, hr, marked_bytes_array, task_card_bm); count_region(mr, hr, marked_bytes_array, task_card_bm);
} }
// Counts the given object in the task/worker counting data
// structures for the given worker id.
inline void ConcurrentMark::count_object(oop obj,
HeapRegion* hr,
uint worker_id) {
size_t* marked_bytes_array = count_marked_bytes_array_for(worker_id);
BitMap* task_card_bm = count_card_bitmap_for(worker_id);
HeapWord* addr = (HeapWord*) obj;
count_object(obj, hr, marked_bytes_array, task_card_bm);
}
// Attempts to mark the given object and, if successful, counts // Attempts to mark the given object and, if successful, counts
// the object in the given task/worker counting structures. // the object in the given task/worker counting structures.
inline bool ConcurrentMark::par_mark_and_count(oop obj, inline bool ConcurrentMark::par_mark_and_count(oop obj,
@ -184,63 +165,6 @@ inline bool ConcurrentMark::par_mark_and_count(oop obj,
return false; return false;
} }
// Attempts to mark the given object and, if successful, counts
// the object in the task/worker counting structures for the
// given worker id.
inline bool ConcurrentMark::par_mark_and_count(oop obj,
HeapRegion* hr,
uint worker_id) {
HeapWord* addr = (HeapWord*)obj;
if (_nextMarkBitMap->parMark(addr)) {
// Update the task specific count data for the object.
count_object(obj, hr, worker_id);
return true;
}
return false;
}
// As above - but we don't know the heap region containing the
// object and so have to supply it.
inline bool ConcurrentMark::par_mark_and_count(oop obj, uint worker_id) {
HeapWord* addr = (HeapWord*)obj;
HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
return par_mark_and_count(obj, hr, worker_id);
}
// Similar to the above routine but we already know the size, in words, of
// the object that we wish to mark/count
inline bool ConcurrentMark::par_mark_and_count(oop obj,
size_t word_size,
uint worker_id) {
HeapWord* addr = (HeapWord*)obj;
if (_nextMarkBitMap->parMark(addr)) {
// Update the task specific count data for the object.
MemRegion mr(addr, word_size);
count_region(mr, worker_id);
return true;
}
return false;
}
// Unconditionally mark the given object, and unconditionally count
// the object in the counting structures for worker id 0.
// Should *not* be called from parallel code.
inline bool ConcurrentMark::mark_and_count(oop obj, HeapRegion* hr) {
HeapWord* addr = (HeapWord*)obj;
_nextMarkBitMap->mark(addr);
// Update the task specific count data for the object.
count_object(obj, hr, 0 /* worker_id */);
return true;
}
// As above - but we don't have the heap region containing the
// object, so we have to supply it.
inline bool ConcurrentMark::mark_and_count(oop obj) {
HeapWord* addr = (HeapWord*)obj;
HeapRegion* hr = _g1h->heap_region_containing_raw(addr);
return mark_and_count(obj, hr);
}
inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) { inline bool CMBitMapRO::iterate(BitMapClosure* cl, MemRegion mr) {
HeapWord* start_addr = MAX2(startWord(), mr.start()); HeapWord* start_addr = MAX2(startWord(), mr.start());
HeapWord* end_addr = MIN2(endWord(), mr.end()); HeapWord* end_addr = MIN2(endWord(), mr.end());

View File

@ -30,14 +30,7 @@
#include "runtime/java.hpp" #include "runtime/java.hpp"
#include "services/memTracker.hpp" #include "services/memTracker.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
void G1BlockOffsetSharedArrayMappingChangedListener::on_commit(uint start_idx, size_t num_regions) {
// Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
// retrieve it here since this would cause firing of several asserts. The code
// executed after commit of a region already needs to do some re-initialization of
// the HeapRegion, so we combine that.
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// G1BlockOffsetSharedArray // G1BlockOffsetSharedArray
@ -59,10 +52,10 @@ G1BlockOffsetSharedArray::G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpa
if (TraceBlockOffsetTable) { if (TraceBlockOffsetTable) {
gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: "); gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
gclog_or_tty->print_cr(" " gclog_or_tty->print_cr(" "
" rs.base(): " INTPTR_FORMAT " rs.base(): " PTR_FORMAT
" rs.size(): " INTPTR_FORMAT " rs.size(): " SIZE_FORMAT
" rs end(): " INTPTR_FORMAT, " rs end(): " PTR_FORMAT,
bot_reserved.start(), bot_reserved.byte_size(), bot_reserved.end()); p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
} }
} }
@ -72,26 +65,16 @@ bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
return (delta & right_n_bits(LogN_words)) == (size_t)NoBits; return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
} }
void G1BlockOffsetSharedArray::set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
set_offset_array(index_for(left), index_for(right -1), offset);
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// G1BlockOffsetArray // G1BlockOffsetArray
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array, G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
MemRegion mr, bool init_to_zero) : MemRegion mr) :
G1BlockOffsetTable(mr.start(), mr.end()), G1BlockOffsetTable(mr.start(), mr.end()),
_unallocated_block(_bottom), _unallocated_block(_bottom),
_array(array), _gsp(NULL), _array(array), _gsp(NULL) {
_init_to_zero(init_to_zero) {
assert(_bottom <= _end, "arguments out of order"); assert(_bottom <= _end, "arguments out of order");
if (!_init_to_zero) {
// initialize cards to point back to mr.start()
set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
_array->set_offset_array(0, 0); // set first card to 0
}
} }
void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) { void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
@ -181,93 +164,6 @@ G1BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size
DEBUG_ONLY(check_all_cards(start_card, end_card);) DEBUG_ONLY(check_all_cards(start_card, end_card);)
} }
// The block [blk_start, blk_end) has been allocated;
// adjust the block offset table to represent this information;
// right-open interval: [blk_start, blk_end)
void
G1BlockOffsetArray::alloc_block(HeapWord* blk_start, HeapWord* blk_end) {
mark_block(blk_start, blk_end);
allocated(blk_start, blk_end);
}
// Adjust BOT to show that a previously whole block has been split
// into two.
void G1BlockOffsetArray::split_block(HeapWord* blk, size_t blk_size,
size_t left_blk_size) {
// Verify that the BOT shows [blk, blk + blk_size) to be one block.
verify_single_block(blk, blk_size);
// Update the BOT to indicate that [blk + left_blk_size, blk + blk_size)
// is one single block.
mark_block(blk + left_blk_size, blk + blk_size);
}
// Action_mark - update the BOT for the block [blk_start, blk_end).
// Current typical use is for splitting a block.
// Action_single - update the BOT for an allocation.
// Action_verify - BOT verification.
void G1BlockOffsetArray::do_block_internal(HeapWord* blk_start,
HeapWord* blk_end,
Action action) {
assert(Universe::heap()->is_in_reserved(blk_start),
"reference must be into the heap");
assert(Universe::heap()->is_in_reserved(blk_end-1),
"limit must be within the heap");
// This is optimized to make the test fast, assuming we only rarely
// cross boundaries.
uintptr_t end_ui = (uintptr_t)(blk_end - 1);
uintptr_t start_ui = (uintptr_t)blk_start;
// Calculate the last card boundary preceding end of blk
intptr_t boundary_before_end = (intptr_t)end_ui;
clear_bits(boundary_before_end, right_n_bits(LogN));
if (start_ui <= (uintptr_t)boundary_before_end) {
// blk starts at or crosses a boundary
// Calculate index of card on which blk begins
size_t start_index = _array->index_for(blk_start);
// Index of card on which blk ends
size_t end_index = _array->index_for(blk_end - 1);
// Start address of card on which blk begins
HeapWord* boundary = _array->address_for_index(start_index);
assert(boundary <= blk_start, "blk should start at or after boundary");
if (blk_start != boundary) {
// blk starts strictly after boundary
// adjust card boundary and start_index forward to next card
boundary += N_words;
start_index++;
}
assert(start_index <= end_index, "monotonicity of index_for()");
assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
switch (action) {
case Action_mark: {
if (init_to_zero()) {
_array->set_offset_array(start_index, boundary, blk_start);
break;
} // Else fall through to the next case
}
case Action_single: {
_array->set_offset_array(start_index, boundary, blk_start);
// We have finished marking the "offset card". We need to now
// mark the subsequent cards that this blk spans.
if (start_index < end_index) {
HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
set_remainder_to_point_to_start(rem_st, rem_end);
}
break;
}
case Action_check: {
_array->check_offset_array(start_index, boundary, blk_start);
// We have finished checking the "offset card". We need to now
// check the subsequent cards that this blk spans.
check_all_cards(start_index + 1, end_index);
break;
}
default:
ShouldNotReachHere();
}
}
}
// The card-interval [start_card, end_card] is a closed interval; this // The card-interval [start_card, end_card] is a closed interval; this
// is an expensive check -- use with care and only under protection of // is an expensive check -- use with care and only under protection of
// suitable flag. // suitable flag.
@ -306,25 +202,6 @@ void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) con
} }
} }
// The range [blk_start, blk_end) represents a single contiguous block
// of storage; modify the block offset table to represent this
// information; Right-open interval: [blk_start, blk_end)
// NOTE: this method does _not_ adjust _unallocated_block.
void
G1BlockOffsetArray::single_block(HeapWord* blk_start, HeapWord* blk_end) {
do_block_internal(blk_start, blk_end, Action_single);
}
// Mark the BOT such that if [blk_start, blk_end) straddles a card
// boundary, the card following the first such boundary is marked
// with the appropriate offset.
// NOTE: this method does _not_ adjust _unallocated_block or
// any cards subsequent to the first one.
void
G1BlockOffsetArray::mark_block(HeapWord* blk_start, HeapWord* blk_end) {
do_block_internal(blk_start, blk_end, Action_mark);
}
HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) { HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
assert(_bottom <= addr && addr < _end, assert(_bottom <= addr && addr < _end,
"addr must be covered by this Array"); "addr must be covered by this Array");
@ -381,7 +258,7 @@ G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
assert(next_boundary <= _array->_end, assert(next_boundary <= _array->_end,
err_msg("next_boundary is beyond the end of the covered region " err_msg("next_boundary is beyond the end of the covered region "
" next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT, " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
next_boundary, _array->_end)); p2i(next_boundary), p2i(_array->_end)));
if (addr >= gsp()->top()) return gsp()->top(); if (addr >= gsp()->top()) return gsp()->top();
while (next_boundary < addr) { while (next_boundary < addr) {
while (n <= next_boundary) { while (n <= next_boundary) {
@ -397,57 +274,13 @@ G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
return forward_to_block_containing_addr_const(q, n, addr); return forward_to_block_containing_addr_const(q, n, addr);
} }
HeapWord* G1BlockOffsetArray::block_start_careful(const void* addr) const {
assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
assert(_bottom <= addr && addr < _end,
"addr must be covered by this Array");
// Must read this exactly once because it can be modified by parallel
// allocation.
HeapWord* ub = _unallocated_block;
if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
assert(ub < _end, "tautology (see above)");
return ub;
}
// Otherwise, find the block start using the table, but taking
// care (cf block_start_unsafe() above) not to parse any objects/blocks
// on the cards themselves.
size_t index = _array->index_for(addr);
assert(_array->address_for_index(index) == addr,
"arg should be start of card");
HeapWord* q = (HeapWord*)addr;
uint offset;
do {
offset = _array->offset_array(index--);
q -= offset;
} while (offset == N_words);
assert(q <= addr, "block start should be to left of arg");
return q;
}
// Note that the committed size of the covered space may have changed, // Note that the committed size of the covered space may have changed,
// so the table size might also wish to change. // so the table size might also wish to change.
void G1BlockOffsetArray::resize(size_t new_word_size) { void G1BlockOffsetArray::resize(size_t new_word_size) {
HeapWord* new_end = _bottom + new_word_size; HeapWord* new_end = _bottom + new_word_size;
if (_end < new_end && !init_to_zero()) {
// verify that the old and new boundaries are also card boundaries
assert(_array->is_card_boundary(_end),
"_end not a card boundary");
assert(_array->is_card_boundary(new_end),
"new _end would not be a card boundary");
// set all the newly added cards
_array->set_offset_array(_end, new_end, N_words);
}
_end = new_end; // update _end _end = new_end; // update _end
} }
void G1BlockOffsetArray::set_region(MemRegion mr) {
_bottom = mr.start();
_end = mr.end();
}
// //
// threshold_ // threshold_
// | _index_ // | _index_
@ -522,7 +355,7 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_
"blk_start: " PTR_FORMAT ", " "blk_start: " PTR_FORMAT ", "
"boundary: " PTR_FORMAT, "boundary: " PTR_FORMAT,
(uint)_array->offset_array(orig_index), (uint)_array->offset_array(orig_index),
blk_start, boundary)); p2i(blk_start), p2i(boundary)));
for (size_t j = orig_index + 1; j <= end_index; j++) { for (size_t j = orig_index + 1; j <= end_index; j++) {
assert(_array->offset_array(j) > 0 && assert(_array->offset_array(j) > 0 &&
_array->offset_array(j) <= _array->offset_array(j) <=
@ -556,9 +389,9 @@ G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
"card addr: "PTR_FORMAT" BOT entry: %u " "card addr: "PTR_FORMAT" BOT entry: %u "
"obj: "PTR_FORMAT" word size: "SIZE_FORMAT" " "obj: "PTR_FORMAT" word size: "SIZE_FORMAT" "
"cards: ["SIZE_FORMAT","SIZE_FORMAT"]", "cards: ["SIZE_FORMAT","SIZE_FORMAT"]",
block_start, card, card_addr, p2i(block_start), card, p2i(card_addr),
_array->offset_array(card), _array->offset_array(card),
obj_start, word_size, first_card, last_card); p2i(obj_start), word_size, first_card, last_card);
return false; return false;
} }
} }
@ -572,10 +405,10 @@ G1BlockOffsetArray::print_on(outputStream* out) {
size_t to_index = _array->index_for(_end); size_t to_index = _array->index_for(_end);
out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") " out->print_cr(">> BOT for area ["PTR_FORMAT","PTR_FORMAT") "
"cards ["SIZE_FORMAT","SIZE_FORMAT")", "cards ["SIZE_FORMAT","SIZE_FORMAT")",
_bottom, _end, from_index, to_index); p2i(_bottom), p2i(_end), from_index, to_index);
for (size_t i = from_index; i < to_index; ++i) { for (size_t i = from_index; i < to_index; ++i) {
out->print_cr(" entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u", out->print_cr(" entry "SIZE_FORMAT_W(8)" | "PTR_FORMAT" : %3u",
i, _array->address_for_index(i), i, p2i(_array->address_for_index(i)),
(uint) _array->offset_array(i)); (uint) _array->offset_array(i));
} }
} }
@ -606,7 +439,7 @@ block_start_unsafe_const(const void* addr) const {
G1BlockOffsetArrayContigSpace:: G1BlockOffsetArrayContigSpace::
G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array,
MemRegion mr) : MemRegion mr) :
G1BlockOffsetArray(array, mr, true) G1BlockOffsetArray(array, mr)
{ {
_next_offset_threshold = NULL; _next_offset_threshold = NULL;
_next_offset_index = 0; _next_offset_index = 0;
@ -641,15 +474,6 @@ HeapWord* G1BlockOffsetArrayContigSpace::initialize_threshold() {
return _next_offset_threshold; return _next_offset_threshold;
} }
void G1BlockOffsetArrayContigSpace::zero_bottom_entry() {
assert(!Universe::heap()->is_in_reserved(_array->_offset_array),
"just checking");
size_t bottom_index = _array->index_for(_bottom);
assert(_array->address_for_index(bottom_index) == _bottom,
"Precondition of call");
_array->set_offset_array(bottom_index, 0);
}
void void
G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) { G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
assert(new_top <= _end, "_end should have already been updated"); assert(new_top <= _end, "_end should have already been updated");
@ -663,7 +487,7 @@ G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* new_top) {
void void
G1BlockOffsetArrayContigSpace::print_on(outputStream* out) { G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
G1BlockOffsetArray::print_on(out); G1BlockOffsetArray::print_on(out);
out->print_cr(" next offset threshold: "PTR_FORMAT, _next_offset_threshold); out->print_cr(" next offset threshold: "PTR_FORMAT, p2i(_next_offset_threshold));
out->print_cr(" next offset index: "SIZE_FORMAT, _next_offset_index); out->print_cr(" next offset index: "SIZE_FORMAT, _next_offset_index);
} }
#endif // !PRODUCT #endif // !PRODUCT

View File

@ -109,7 +109,12 @@ public:
class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener { class G1BlockOffsetSharedArrayMappingChangedListener : public G1MappingChangedListener {
public: public:
virtual void on_commit(uint start_idx, size_t num_regions); virtual void on_commit(uint start_idx, size_t num_regions) {
// Nothing to do. The BOT is hard-wired to be part of the HeapRegion, and we cannot
// retrieve it here since this would cause firing of several asserts. The code
// executed after commit of a region already needs to do some re-initialization of
// the HeapRegion, so we combine that.
}
}; };
// This implementation of "G1BlockOffsetTable" divides the covered region // This implementation of "G1BlockOffsetTable" divides the covered region
@ -153,8 +158,6 @@ private:
// For performance these have to devolve to array accesses in product builds. // For performance these have to devolve to array accesses in product builds.
inline u_char offset_array(size_t index) const; inline u_char offset_array(size_t index) const;
void set_offset_array(HeapWord* left, HeapWord* right, u_char offset);
void set_offset_array_raw(size_t index, u_char offset) { void set_offset_array_raw(size_t index, u_char offset) {
_offset_array[index] = offset; _offset_array[index] = offset;
} }
@ -165,8 +168,6 @@ private:
inline void set_offset_array(size_t left, size_t right, u_char offset); inline void set_offset_array(size_t left, size_t right, u_char offset);
inline void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const;
bool is_card_boundary(HeapWord* p) const; bool is_card_boundary(HeapWord* p) const;
public: public:
@ -193,8 +194,6 @@ public:
// G1BlockOffsetTable(s) to initialize cards. // G1BlockOffsetTable(s) to initialize cards.
G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage); G1BlockOffsetSharedArray(MemRegion heap, G1RegionToSpaceMapper* storage);
void set_bottom(HeapWord* new_bottom);
// Return the appropriate index into "_offset_array" for "p". // Return the appropriate index into "_offset_array" for "p".
inline size_t index_for(const void* p) const; inline size_t index_for(const void* p) const;
inline size_t index_for_raw(const void* p) const; inline size_t index_for_raw(const void* p) const;
@ -220,14 +219,6 @@ private:
LogN = G1BlockOffsetSharedArray::LogN LogN = G1BlockOffsetSharedArray::LogN
}; };
// The following enums are used by do_block_helper
enum Action {
Action_single, // BOT records a single block (see single_block())
Action_mark, // BOT marks the start of a block (see mark_block())
Action_check // Check that BOT records block correctly
// (see verify_single_block()).
};
// This is the array, which can be shared by several BlockOffsetArray's // This is the array, which can be shared by several BlockOffsetArray's
// servicing different // servicing different
G1BlockOffsetSharedArray* _array; G1BlockOffsetSharedArray* _array;
@ -235,10 +226,6 @@ private:
// The space that owns this subregion. // The space that owns this subregion.
G1OffsetTableContigSpace* _gsp; G1OffsetTableContigSpace* _gsp;
// If true, array entries are initialized to 0; otherwise, they are
// initialized to point backwards to the beginning of the covered region.
bool _init_to_zero;
// The portion [_unallocated_block, _sp.end()) of the space that // The portion [_unallocated_block, _sp.end()) of the space that
// is a single block known not to contain any objects. // is a single block known not to contain any objects.
// NOTE: See BlockOffsetArrayUseUnallocatedBlock flag. // NOTE: See BlockOffsetArrayUseUnallocatedBlock flag.
@ -253,9 +240,6 @@ private:
// that is closed: [start_index, end_index] // that is closed: [start_index, end_index]
void set_remainder_to_point_to_start_incl(size_t start, size_t end); void set_remainder_to_point_to_start_incl(size_t start, size_t end);
// A helper function for BOT adjustment/verification work
void do_block_internal(HeapWord* blk_start, HeapWord* blk_end, Action action);
protected: protected:
G1OffsetTableContigSpace* gsp() const { return _gsp; } G1OffsetTableContigSpace* gsp() const { return _gsp; }
@ -303,11 +287,9 @@ protected:
public: public:
// The space may not have it's bottom and top set yet, which is why the // The space may not have it's bottom and top set yet, which is why the
// region is passed as a parameter. If "init_to_zero" is true, the // region is passed as a parameter. The elements of the array are
// elements of the array are initialized to zero. Otherwise, they are // initialized to zero.
// initialized to point backwards to the beginning. G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr);
G1BlockOffsetArray(G1BlockOffsetSharedArray* array, MemRegion mr,
bool init_to_zero);
// Note: this ought to be part of the constructor, but that would require // Note: this ought to be part of the constructor, but that would require
// "this" to be passed as a parameter to a member constructor for // "this" to be passed as a parameter to a member constructor for
@ -315,114 +297,19 @@ public:
// This would be legal C++, but MS VC++ doesn't allow it. // This would be legal C++, but MS VC++ doesn't allow it.
void set_space(G1OffsetTableContigSpace* sp); void set_space(G1OffsetTableContigSpace* sp);
// Resets the covered region to the given "mr".
void set_region(MemRegion mr);
// Resets the covered region to one with the same _bottom as before but // Resets the covered region to one with the same _bottom as before but
// the "new_word_size". // the "new_word_size".
void resize(size_t new_word_size); void resize(size_t new_word_size);
// These must be guaranteed to work properly (i.e., do nothing)
// when "blk_start" ("blk" for second version) is "NULL".
virtual void alloc_block(HeapWord* blk_start, HeapWord* blk_end);
virtual void alloc_block(HeapWord* blk, size_t size) {
alloc_block(blk, blk + size);
}
// The following methods are useful and optimized for a
// general, non-contiguous space.
// Given a block [blk_start, blk_start + full_blk_size), and
// a left_blk_size < full_blk_size, adjust the BOT to show two
// blocks [blk_start, blk_start + left_blk_size) and
// [blk_start + left_blk_size, blk_start + full_blk_size).
// It is assumed (and verified in the non-product VM) that the
// BOT was correct for the original block.
void split_block(HeapWord* blk_start, size_t full_blk_size,
size_t left_blk_size);
// Adjust the BOT to show that it has a single block in the
// range [blk_start, blk_start + size). All necessary BOT
// cards are adjusted, but _unallocated_block isn't.
void single_block(HeapWord* blk_start, HeapWord* blk_end);
void single_block(HeapWord* blk, size_t size) {
single_block(blk, blk + size);
}
// Adjust BOT to show that it has a block in the range
// [blk_start, blk_start + size). Only the first card
// of BOT is touched. It is assumed (and verified in the
// non-product VM) that the remaining cards of the block
// are correct.
void mark_block(HeapWord* blk_start, HeapWord* blk_end);
void mark_block(HeapWord* blk, size_t size) {
mark_block(blk, blk + size);
}
// Adjust _unallocated_block to indicate that a particular
// block has been newly allocated or freed. It is assumed (and
// verified in the non-product VM) that the BOT is correct for
// the given block.
inline void allocated(HeapWord* blk_start, HeapWord* blk_end) {
// Verify that the BOT shows [blk, blk + blk_size) to be one block.
verify_single_block(blk_start, blk_end);
if (BlockOffsetArrayUseUnallocatedBlock) {
_unallocated_block = MAX2(_unallocated_block, blk_end);
}
}
inline void allocated(HeapWord* blk, size_t size) {
allocated(blk, blk + size);
}
inline void freed(HeapWord* blk_start, HeapWord* blk_end);
inline void freed(HeapWord* blk, size_t size);
virtual HeapWord* block_start_unsafe(const void* addr); virtual HeapWord* block_start_unsafe(const void* addr);
virtual HeapWord* block_start_unsafe_const(const void* addr) const; virtual HeapWord* block_start_unsafe_const(const void* addr) const;
// Requires "addr" to be the start of a card and returns the
// start of the block that contains the given address.
HeapWord* block_start_careful(const void* addr) const;
// If true, initialize array slots with no allocated blocks to zero.
// Otherwise, make them point back to the front.
bool init_to_zero() { return _init_to_zero; }
// Verification & debugging - ensure that the offset table reflects the fact
// that the block [blk_start, blk_end) or [blk, blk + size) is a
// single block of storage. NOTE: can;t const this because of
// call to non-const do_block_internal() below.
inline void verify_single_block(HeapWord* blk_start, HeapWord* blk_end) {
if (VerifyBlockOffsetArray) {
do_block_internal(blk_start, blk_end, Action_check);
}
}
inline void verify_single_block(HeapWord* blk, size_t size) {
verify_single_block(blk, blk + size);
}
// Used by region verification. Checks that the contents of the // Used by region verification. Checks that the contents of the
// BOT reflect that there's a single object that spans the address // BOT reflect that there's a single object that spans the address
// range [obj_start, obj_start + word_size); returns true if this is // range [obj_start, obj_start + word_size); returns true if this is
// the case, returns false if it's not. // the case, returns false if it's not.
bool verify_for_object(HeapWord* obj_start, size_t word_size) const; bool verify_for_object(HeapWord* obj_start, size_t word_size) const;
// Verify that the given block is before _unallocated_block
inline void verify_not_unallocated(HeapWord* blk_start,
HeapWord* blk_end) const {
if (BlockOffsetArrayUseUnallocatedBlock) {
assert(blk_start < blk_end, "Block inconsistency?");
assert(blk_end <= _unallocated_block, "_unallocated_block problem");
}
}
inline void verify_not_unallocated(HeapWord* blk, size_t size) const {
verify_not_unallocated(blk, blk + size);
}
void check_all_cards(size_t left_card, size_t right_card) const; void check_all_cards(size_t left_card, size_t right_card) const;
virtual void print_on(outputStream* out) PRODUCT_RETURN; virtual void print_on(outputStream* out) PRODUCT_RETURN;
@ -445,14 +332,12 @@ class G1BlockOffsetArrayContigSpace: public G1BlockOffsetArray {
blk_start, blk_end); blk_start, blk_end);
} }
// Variant of zero_bottom_entry that does not check for availability of the // Zero out the entry for _bottom (offset will be zero). Does not check for availability of the
// memory first. // memory first.
void zero_bottom_entry_raw(); void zero_bottom_entry_raw();
// Variant of initialize_threshold that does not check for availability of the // Variant of initialize_threshold that does not check for availability of the
// memory first. // memory first.
HeapWord* initialize_threshold_raw(); HeapWord* initialize_threshold_raw();
// Zero out the entry for _bottom (offset will be zero).
void zero_bottom_entry();
public: public:
G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr); G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);

View File

@ -91,13 +91,6 @@ void G1BlockOffsetSharedArray::set_offset_array(size_t left, size_t right, u_cha
} }
} }
void G1BlockOffsetSharedArray::check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
check_index(index, "index out of range");
assert(high >= low, "addresses out of order");
check_offset(pointer_delta(high, low), "offset too large");
assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
}
// Variant of index_for that does not check the index for validity. // Variant of index_for that does not check the index for validity.
inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const { inline size_t G1BlockOffsetSharedArray::index_for_raw(const void* p) const {
return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN; return pointer_delta((char*)p, _reserved.start(), sizeof(char)) >> LogN;
@ -193,28 +186,4 @@ G1BlockOffsetArray::forward_to_block_containing_addr(HeapWord* q,
return q; return q;
} }
//////////////////////////////////////////////////////////////////////////
// BlockOffsetArrayNonContigSpace inlines
//////////////////////////////////////////////////////////////////////////
inline void G1BlockOffsetArray::freed(HeapWord* blk_start, HeapWord* blk_end) {
// Verify that the BOT shows [blk_start, blk_end) to be one block.
verify_single_block(blk_start, blk_end);
// adjust _unallocated_block upward or downward
// as appropriate
if (BlockOffsetArrayUseUnallocatedBlock) {
assert(_unallocated_block <= _end,
"Inconsistent value for _unallocated_block");
if (blk_end >= _unallocated_block && blk_start <= _unallocated_block) {
// CMS-specific note: a block abutting _unallocated_block to
// its left is being freed, a new block is being added or
// we are resetting following a compaction
_unallocated_block = blk_start;
}
}
}
inline void G1BlockOffsetArray::freed(HeapWord* blk, size_t size) {
freed(blk, blk + size);
}
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1BLOCKOFFSETTABLE_INLINE_HPP

View File

@ -532,9 +532,9 @@ G1CollectedHeap::new_region_try_secondary_free_list(bool is_old) {
// again to allocate from it. // again to allocate from it.
append_secondary_free_list(); append_secondary_free_list();
assert(_hrs.num_free_regions() > 0, "if the secondary_free_list was not " assert(_hrm.num_free_regions() > 0, "if the secondary_free_list was not "
"empty we should have moved at least one entry to the free_list"); "empty we should have moved at least one entry to the free_list");
HeapRegion* res = _hrs.allocate_free_region(is_old); HeapRegion* res = _hrm.allocate_free_region(is_old);
if (G1ConcRegionFreeingVerbose) { if (G1ConcRegionFreeingVerbose) {
gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
"allocated "HR_FORMAT" from secondary_free_list", "allocated "HR_FORMAT" from secondary_free_list",
@ -575,7 +575,7 @@ HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool is_old, bool do_e
} }
} }
res = _hrs.allocate_free_region(is_old); res = _hrm.allocate_free_region(is_old);
if (res == NULL) { if (res == NULL) {
if (G1ConcRegionFreeingVerbose) { if (G1ConcRegionFreeingVerbose) {
@ -601,7 +601,7 @@ HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool is_old, bool do_e
// always expand the heap by an amount aligned to the heap // always expand the heap by an amount aligned to the heap
// region size, the free list should in theory not be empty. // region size, the free list should in theory not be empty.
// In either case allocate_free_region() will check for NULL. // In either case allocate_free_region() will check for NULL.
res = _hrs.allocate_free_region(is_old); res = _hrm.allocate_free_region(is_old);
} else { } else {
_expand_heap_after_alloc_failure = false; _expand_heap_after_alloc_failure = false;
} }
@ -613,7 +613,7 @@ HeapWord*
G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first, G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
uint num_regions, uint num_regions,
size_t word_size) { size_t word_size) {
assert(first != G1_NO_HRS_INDEX, "pre-condition"); assert(first != G1_NO_HRM_INDEX, "pre-condition");
assert(isHumongous(word_size), "word_size should be humongous"); assert(isHumongous(word_size), "word_size should be humongous");
assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
@ -751,7 +751,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
verify_region_sets_optional(); verify_region_sets_optional();
uint first = G1_NO_HRS_INDEX; uint first = G1_NO_HRM_INDEX;
uint obj_regions = (uint)(align_size_up_(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords); uint obj_regions = (uint)(align_size_up_(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords);
if (obj_regions == 1) { if (obj_regions == 1) {
@ -760,7 +760,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
// later. // later.
HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */); HeapRegion* hr = new_region(word_size, true /* is_old */, false /* do_expand */);
if (hr != NULL) { if (hr != NULL) {
first = hr->hrs_index(); first = hr->hrm_index();
} }
} else { } else {
// We can't allocate humongous regions spanning more than one region while // We can't allocate humongous regions spanning more than one region while
@ -776,18 +776,18 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
// Policy: Try only empty regions (i.e. already committed first). Maybe we // Policy: Try only empty regions (i.e. already committed first). Maybe we
// are lucky enough to find some. // are lucky enough to find some.
first = _hrs.find_contiguous_only_empty(obj_regions); first = _hrm.find_contiguous_only_empty(obj_regions);
if (first != G1_NO_HRS_INDEX) { if (first != G1_NO_HRM_INDEX) {
_hrs.allocate_free_regions_starting_at(first, obj_regions); _hrm.allocate_free_regions_starting_at(first, obj_regions);
} }
} }
if (first == G1_NO_HRS_INDEX) { if (first == G1_NO_HRM_INDEX) {
// Policy: We could not find enough regions for the humongous object in the // Policy: We could not find enough regions for the humongous object in the
// free list. Look through the heap to find a mix of free and uncommitted regions. // free list. Look through the heap to find a mix of free and uncommitted regions.
// If so, try expansion. // If so, try expansion.
first = _hrs.find_contiguous_empty_or_unavailable(obj_regions); first = _hrm.find_contiguous_empty_or_unavailable(obj_regions);
if (first != G1_NO_HRS_INDEX) { if (first != G1_NO_HRM_INDEX) {
// We found something. Make sure these regions are committed, i.e. expand // We found something. Make sure these regions are committed, i.e. expand
// the heap. Alternatively we could do a defragmentation GC. // the heap. Alternatively we could do a defragmentation GC.
ergo_verbose1(ErgoHeapSizing, ergo_verbose1(ErgoHeapSizing,
@ -796,7 +796,7 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
ergo_format_byte("allocation request"), ergo_format_byte("allocation request"),
word_size * HeapWordSize); word_size * HeapWordSize);
_hrs.expand_at(first, obj_regions); _hrm.expand_at(first, obj_regions);
g1_policy()->record_new_heap_size(num_regions()); g1_policy()->record_new_heap_size(num_regions());
#ifdef ASSERT #ifdef ASSERT
@ -806,14 +806,14 @@ HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) {
assert(is_on_master_free_list(hr), "sanity"); assert(is_on_master_free_list(hr), "sanity");
} }
#endif #endif
_hrs.allocate_free_regions_starting_at(first, obj_regions); _hrm.allocate_free_regions_starting_at(first, obj_regions);
} else { } else {
// Policy: Potentially trigger a defragmentation GC. // Policy: Potentially trigger a defragmentation GC.
} }
} }
HeapWord* result = NULL; HeapWord* result = NULL;
if (first != G1_NO_HRS_INDEX) { if (first != G1_NO_HRM_INDEX) {
result = humongous_obj_allocate_initialize_regions(first, obj_regions, word_size); result = humongous_obj_allocate_initialize_regions(first, obj_regions, word_size);
assert(result != NULL, "it should always return a valid result"); assert(result != NULL, "it should always return a valid result");
@ -1248,7 +1248,7 @@ public:
: _hr_printer(hr_printer) { } : _hr_printer(hr_printer) { }
}; };
void G1CollectedHeap::print_hrs_post_compaction() { void G1CollectedHeap::print_hrm_post_compaction() {
PostCompactionPrinterClosure cl(hr_printer()); PostCompactionPrinterClosure cl(hr_printer());
heap_region_iterate(&cl); heap_region_iterate(&cl);
} }
@ -1417,7 +1417,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
// that all the COMMIT / UNCOMMIT events are generated before // that all the COMMIT / UNCOMMIT events are generated before
// the end GC event. // the end GC event.
print_hrs_post_compaction(); print_hrm_post_compaction();
_hr_printer.end_gc(true /* full */, (size_t) total_collections()); _hr_printer.end_gc(true /* full */, (size_t) total_collections());
} }
@ -1490,7 +1490,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
// Update the number of full collections that have been completed. // Update the number of full collections that have been completed.
increment_old_marking_cycles_completed(false /* concurrent */); increment_old_marking_cycles_completed(false /* concurrent */);
_hrs.verify_optional(); _hrm.verify_optional();
verify_region_sets_optional(); verify_region_sets_optional();
verify_after_gc(); verify_after_gc();
@ -1734,7 +1734,7 @@ HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) {
ergo_format_byte("allocation request"), ergo_format_byte("allocation request"),
word_size * HeapWordSize); word_size * HeapWordSize);
if (expand(expand_bytes)) { if (expand(expand_bytes)) {
_hrs.verify_optional(); _hrm.verify_optional();
verify_region_sets_optional(); verify_region_sets_optional();
return attempt_allocation_at_safepoint(word_size, return attempt_allocation_at_safepoint(word_size,
false /* expect_null_mutator_alloc_region */); false /* expect_null_mutator_alloc_region */);
@ -1762,7 +1762,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes); uint regions_to_expand = (uint)(aligned_expand_bytes / HeapRegion::GrainBytes);
assert(regions_to_expand > 0, "Must expand by at least one region"); assert(regions_to_expand > 0, "Must expand by at least one region");
uint expanded_by = _hrs.expand_by(regions_to_expand); uint expanded_by = _hrm.expand_by(regions_to_expand);
if (expanded_by > 0) { if (expanded_by > 0) {
size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes; size_t actual_expand_bytes = expanded_by * HeapRegion::GrainBytes;
@ -1775,7 +1775,7 @@ bool G1CollectedHeap::expand(size_t expand_bytes) {
// The expansion of the virtual storage space was unsuccessful. // The expansion of the virtual storage space was unsuccessful.
// Let's see if it was because we ran out of swap. // Let's see if it was because we ran out of swap.
if (G1ExitOnExpansionFailure && if (G1ExitOnExpansionFailure &&
_hrs.available() >= regions_to_expand) { _hrm.available() >= regions_to_expand) {
// We had head room... // We had head room...
vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion"); vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion");
} }
@ -1790,7 +1790,7 @@ void G1CollectedHeap::shrink_helper(size_t shrink_bytes) {
HeapRegion::GrainBytes); HeapRegion::GrainBytes);
uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes); uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes);
uint num_regions_removed = _hrs.shrink_by(num_regions_to_remove); uint num_regions_removed = _hrm.shrink_by(num_regions_to_remove);
size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes; size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes;
ergo_verbose3(ErgoHeapSizing, ergo_verbose3(ErgoHeapSizing,
@ -1823,7 +1823,7 @@ void G1CollectedHeap::shrink(size_t shrink_bytes) {
shrink_helper(shrink_bytes); shrink_helper(shrink_bytes);
rebuild_region_sets(true /* free_list_only */); rebuild_region_sets(true /* free_list_only */);
_hrs.verify_optional(); _hrm.verify_optional();
verify_region_sets_optional(); verify_region_sets_optional();
} }
@ -1867,6 +1867,7 @@ G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) :
_old_marking_cycles_started(0), _old_marking_cycles_started(0),
_old_marking_cycles_completed(0), _old_marking_cycles_completed(0),
_concurrent_cycle_started(false), _concurrent_cycle_started(false),
_heap_summary_sent(false),
_in_cset_fast_test(), _in_cset_fast_test(),
_dirty_cards_region_list(NULL), _dirty_cards_region_list(NULL),
_worker_cset_start_region(NULL), _worker_cset_start_region(NULL),
@ -2032,7 +2033,7 @@ jint G1CollectedHeap::initialize() {
CMBitMap::mark_distance(), CMBitMap::mark_distance(),
mtGC); mtGC);
_hrs.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage); _hrm.initialize(heap_storage, prev_bitmap_storage, next_bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
g1_barrier_set()->initialize(cardtable_storage); g1_barrier_set()->initialize(cardtable_storage);
// Do later initialization work for concurrent refinement. // Do later initialization work for concurrent refinement.
_cg1r->init(card_counts_storage); _cg1r->init(card_counts_storage);
@ -2053,8 +2054,8 @@ jint G1CollectedHeap::initialize() {
_g1h = this; _g1h = this;
_in_cset_fast_test.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes); _in_cset_fast_test.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
_humongous_is_live.initialize(_hrs.reserved().start(), _hrs.reserved().end(), HeapRegion::GrainBytes); _humongous_is_live.initialize(_hrm.reserved().start(), _hrm.reserved().end(), HeapRegion::GrainBytes);
// Create the ConcurrentMark data structure and thread. // Create the ConcurrentMark data structure and thread.
// (Must do this late, so that "max_regions" is defined.) // (Must do this late, so that "max_regions" is defined.)
@ -2115,7 +2116,7 @@ jint G1CollectedHeap::initialize() {
// Here we allocate the dummy HeapRegion that is required by the // Here we allocate the dummy HeapRegion that is required by the
// G1AllocRegion class. // G1AllocRegion class.
HeapRegion* dummy_region = _hrs.get_dummy_region(); HeapRegion* dummy_region = _hrm.get_dummy_region();
// We'll re-use the same region whether the alloc region will // We'll re-use the same region whether the alloc region will
// require BOT updates or not and, if it doesn't, then a non-young // require BOT updates or not and, if it doesn't, then a non-young
@ -2232,14 +2233,14 @@ void G1CollectedHeap::ref_processing_init() {
} }
size_t G1CollectedHeap::capacity() const { size_t G1CollectedHeap::capacity() const {
return _hrs.length() * HeapRegion::GrainBytes; return _hrm.length() * HeapRegion::GrainBytes;
} }
void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) { void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
assert(!hr->continuesHumongous(), "pre-condition"); assert(!hr->continuesHumongous(), "pre-condition");
hr->reset_gc_time_stamp(); hr->reset_gc_time_stamp();
if (hr->startsHumongous()) { if (hr->startsHumongous()) {
uint first_index = hr->hrs_index() + 1; uint first_index = hr->hrm_index() + 1;
uint last_index = hr->last_hc_index(); uint last_index = hr->last_hc_index();
for (uint i = first_index; i < last_index; i += 1) { for (uint i = first_index; i < last_index; i += 1) {
HeapRegion* chr = region_at(i); HeapRegion* chr = region_at(i);
@ -2445,13 +2446,24 @@ void G1CollectedHeap::register_concurrent_cycle_end() {
_gc_timer_cm->register_gc_end(); _gc_timer_cm->register_gc_end();
_gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions());
// Clear state variables to prepare for the next concurrent cycle.
_concurrent_cycle_started = false; _concurrent_cycle_started = false;
_heap_summary_sent = false;
} }
} }
void G1CollectedHeap::trace_heap_after_concurrent_cycle() { void G1CollectedHeap::trace_heap_after_concurrent_cycle() {
if (_concurrent_cycle_started) { if (_concurrent_cycle_started) {
trace_heap_after_gc(_gc_tracer_cm); // This function can be called when:
// the cleanup pause is run
// the concurrent cycle is aborted before the cleanup pause.
// the concurrent cycle is aborted after the cleanup pause,
// but before the concurrent cycle end has been registered.
// Make sure that we only send the heap information once.
if (!_heap_summary_sent) {
trace_heap_after_gc(_gc_tracer_cm);
_heap_summary_sent = true;
}
} }
} }
@ -2537,7 +2549,7 @@ void G1CollectedHeap::collect(GCCause::Cause cause) {
} }
bool G1CollectedHeap::is_in(const void* p) const { bool G1CollectedHeap::is_in(const void* p) const {
if (_hrs.reserved().contains(p)) { if (_hrm.reserved().contains(p)) {
// Given that we know that p is in the reserved space, // Given that we know that p is in the reserved space,
// heap_region_containing_raw() should successfully // heap_region_containing_raw() should successfully
// return the containing region. // return the containing region.
@ -2551,7 +2563,7 @@ bool G1CollectedHeap::is_in(const void* p) const {
#ifdef ASSERT #ifdef ASSERT
bool G1CollectedHeap::is_in_exact(const void* p) const { bool G1CollectedHeap::is_in_exact(const void* p) const {
bool contains = reserved_region().contains(p); bool contains = reserved_region().contains(p);
bool available = _hrs.is_available(addr_to_region((HeapWord*)p)); bool available = _hrm.is_available(addr_to_region((HeapWord*)p));
if (contains && available) { if (contains && available) {
return true; return true;
} else { } else {
@ -2618,7 +2630,7 @@ void G1CollectedHeap::space_iterate(SpaceClosure* cl) {
} }
void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const {
_hrs.iterate(cl); _hrm.iterate(cl);
} }
void void
@ -2626,7 +2638,7 @@ G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
uint worker_id, uint worker_id,
uint num_workers, uint num_workers,
jint claim_value) const { jint claim_value) const {
_hrs.par_iterate(cl, worker_id, num_workers, claim_value); _hrm.par_iterate(cl, worker_id, num_workers, claim_value);
} }
class ResetClaimValuesClosure: public HeapRegionClosure { class ResetClaimValuesClosure: public HeapRegionClosure {
@ -2846,9 +2858,9 @@ void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r,
} }
HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const { HeapRegion* G1CollectedHeap::next_compaction_region(const HeapRegion* from) const {
HeapRegion* result = _hrs.next_region_in_heap(from); HeapRegion* result = _hrm.next_region_in_heap(from);
while (result != NULL && result->isHumongous()) { while (result != NULL && result->isHumongous()) {
result = _hrs.next_region_in_heap(result); result = _hrm.next_region_in_heap(result);
} }
return result; return result;
} }
@ -2908,7 +2920,7 @@ size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
} }
size_t G1CollectedHeap::max_capacity() const { size_t G1CollectedHeap::max_capacity() const {
return _hrs.reserved().byte_size(); return _hrm.reserved().byte_size();
} }
jlong G1CollectedHeap::millis_since_last_gc() { jlong G1CollectedHeap::millis_since_last_gc() {
@ -3437,9 +3449,9 @@ void G1CollectedHeap::print_on(outputStream* st) const {
st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
capacity()/K, used_unlocked()/K); capacity()/K, used_unlocked()/K);
st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
_hrs.reserved().start(), _hrm.reserved().start(),
_hrs.reserved().start() + _hrs.length() + HeapRegion::GrainWords, _hrm.reserved().start() + _hrm.length() + HeapRegion::GrainWords,
_hrs.reserved().end()); _hrm.reserved().end());
st->cr(); st->cr();
st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K); st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
uint young_regions = _young_list->length(); uint young_regions = _young_list->length();
@ -3682,7 +3694,7 @@ class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
} }
G1CollectedHeap* g1h = G1CollectedHeap::heap(); G1CollectedHeap* g1h = G1CollectedHeap::heap();
uint region_idx = r->hrs_index(); uint region_idx = r->hrm_index();
bool is_candidate = !g1h->humongous_region_is_always_live(region_idx); bool is_candidate = !g1h->humongous_region_is_always_live(region_idx);
// Is_candidate already filters out humongous regions with some remembered set. // Is_candidate already filters out humongous regions with some remembered set.
// This will not lead to humongous object that we mistakenly keep alive because // This will not lead to humongous object that we mistakenly keep alive because
@ -4205,7 +4217,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
// output from the concurrent mark thread interfering with this // output from the concurrent mark thread interfering with this
// logging output either. // logging output either.
_hrs.verify_optional(); _hrm.verify_optional();
verify_region_sets_optional(); verify_region_sets_optional();
TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
@ -6024,7 +6036,7 @@ void G1CollectedHeap::free_region(HeapRegion* hr,
bool locked) { bool locked) {
assert(!hr->isHumongous(), "this is only for non-humongous regions"); assert(!hr->isHumongous(), "this is only for non-humongous regions");
assert(!hr->is_empty(), "the region should not be empty"); assert(!hr->is_empty(), "the region should not be empty");
assert(_hrs.is_available(hr->hrs_index()), "region should be committed"); assert(_hrm.is_available(hr->hrm_index()), "region should be committed");
assert(free_list != NULL, "pre-condition"); assert(free_list != NULL, "pre-condition");
if (G1VerifyBitmaps) { if (G1VerifyBitmaps) {
@ -6055,7 +6067,7 @@ void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
hr->set_notHumongous(); hr->set_notHumongous();
free_region(hr, free_list, par); free_region(hr, free_list, par);
uint i = hr->hrs_index() + 1; uint i = hr->hrm_index() + 1;
while (i < last_index) { while (i < last_index) {
HeapRegion* curr_hr = region_at(i); HeapRegion* curr_hr = region_at(i);
assert(curr_hr->continuesHumongous(), "invariant"); assert(curr_hr->continuesHumongous(), "invariant");
@ -6079,7 +6091,7 @@ void G1CollectedHeap::prepend_to_freelist(FreeRegionList* list) {
assert(list != NULL, "list can't be null"); assert(list != NULL, "list can't be null");
if (!list->is_empty()) { if (!list->is_empty()) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
_hrs.insert_list_into_free_list(list); _hrm.insert_list_into_free_list(list);
} }
} }
@ -6448,7 +6460,7 @@ class G1FreeHumongousRegionClosure : public HeapRegionClosure {
// While this cleanup is not strictly necessary to be done (or done instantly), // While this cleanup is not strictly necessary to be done (or done instantly),
// given that their occurrence is very low, this saves us this additional // given that their occurrence is very low, this saves us this additional
// complexity. // complexity.
uint region_idx = r->hrs_index(); uint region_idx = r->hrm_index();
if (g1h->humongous_is_live(region_idx) || if (g1h->humongous_is_live(region_idx) ||
g1h->humongous_region_is_always_live(region_idx)) { g1h->humongous_region_is_always_live(region_idx)) {
@ -6687,22 +6699,22 @@ void G1CollectedHeap::tear_down_region_sets(bool free_list_only) {
// this is that during a full GC string deduplication needs to know if // this is that during a full GC string deduplication needs to know if
// a collected region was young or old when the full GC was initiated. // a collected region was young or old when the full GC was initiated.
} }
_hrs.remove_all_free_regions(); _hrm.remove_all_free_regions();
} }
class RebuildRegionSetsClosure : public HeapRegionClosure { class RebuildRegionSetsClosure : public HeapRegionClosure {
private: private:
bool _free_list_only; bool _free_list_only;
HeapRegionSet* _old_set; HeapRegionSet* _old_set;
HeapRegionSeq* _hrs; HeapRegionManager* _hrm;
size_t _total_used; size_t _total_used;
public: public:
RebuildRegionSetsClosure(bool free_list_only, RebuildRegionSetsClosure(bool free_list_only,
HeapRegionSet* old_set, HeapRegionSeq* hrs) : HeapRegionSet* old_set, HeapRegionManager* hrm) :
_free_list_only(free_list_only), _free_list_only(free_list_only),
_old_set(old_set), _hrs(hrs), _total_used(0) { _old_set(old_set), _hrm(hrm), _total_used(0) {
assert(_hrs->num_free_regions() == 0, "pre-condition"); assert(_hrm->num_free_regions() == 0, "pre-condition");
if (!free_list_only) { if (!free_list_only) {
assert(_old_set->is_empty(), "pre-condition"); assert(_old_set->is_empty(), "pre-condition");
} }
@ -6715,7 +6727,7 @@ public:
if (r->is_empty()) { if (r->is_empty()) {
// Add free regions to the free list // Add free regions to the free list
_hrs->insert_into_free_list(r); _hrm->insert_into_free_list(r);
} else if (!_free_list_only) { } else if (!_free_list_only) {
assert(!r->is_young(), "we should not come across young regions"); assert(!r->is_young(), "we should not come across young regions");
@ -6743,7 +6755,7 @@ void G1CollectedHeap::rebuild_region_sets(bool free_list_only) {
_young_list->empty_list(); _young_list->empty_list();
} }
RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrs); RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_hrm);
heap_region_iterate(&cl); heap_region_iterate(&cl);
if (!free_list_only) { if (!free_list_only) {
@ -6933,7 +6945,7 @@ class VerifyRegionListsClosure : public HeapRegionClosure {
private: private:
HeapRegionSet* _old_set; HeapRegionSet* _old_set;
HeapRegionSet* _humongous_set; HeapRegionSet* _humongous_set;
HeapRegionSeq* _hrs; HeapRegionManager* _hrm;
public: public:
HeapRegionSetCount _old_count; HeapRegionSetCount _old_count;
@ -6942,8 +6954,8 @@ public:
VerifyRegionListsClosure(HeapRegionSet* old_set, VerifyRegionListsClosure(HeapRegionSet* old_set,
HeapRegionSet* humongous_set, HeapRegionSet* humongous_set,
HeapRegionSeq* hrs) : HeapRegionManager* hrm) :
_old_set(old_set), _humongous_set(humongous_set), _hrs(hrs), _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
_old_count(), _humongous_count(), _free_count(){ } _old_count(), _humongous_count(), _free_count(){ }
bool doHeapRegion(HeapRegion* hr) { bool doHeapRegion(HeapRegion* hr) {
@ -6954,19 +6966,19 @@ public:
if (hr->is_young()) { if (hr->is_young()) {
// TODO // TODO
} else if (hr->startsHumongous()) { } else if (hr->startsHumongous()) {
assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrs_index())); assert(hr->containing_set() == _humongous_set, err_msg("Heap region %u is starts humongous but not in humongous set.", hr->hrm_index()));
_humongous_count.increment(1u, hr->capacity()); _humongous_count.increment(1u, hr->capacity());
} else if (hr->is_empty()) { } else if (hr->is_empty()) {
assert(_hrs->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrs_index())); assert(_hrm->is_free(hr), err_msg("Heap region %u is empty but not on the free list.", hr->hrm_index()));
_free_count.increment(1u, hr->capacity()); _free_count.increment(1u, hr->capacity());
} else { } else {
assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrs_index())); assert(hr->containing_set() == _old_set, err_msg("Heap region %u is old but not in the old set.", hr->hrm_index()));
_old_count.increment(1u, hr->capacity()); _old_count.increment(1u, hr->capacity());
} }
return false; return false;
} }
void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionSeq* free_list) { void verify_counts(HeapRegionSet* old_set, HeapRegionSet* humongous_set, HeapRegionManager* free_list) {
guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length())); guarantee(old_set->length() == _old_count.length(), err_msg("Old set count mismatch. Expected %u, actual %u.", old_set->length(), _old_count.length()));
guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, guarantee(old_set->total_capacity_bytes() == _old_count.capacity(), err_msg("Old set capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,
old_set->total_capacity_bytes(), _old_count.capacity())); old_set->total_capacity_bytes(), _old_count.capacity()));
@ -6985,7 +6997,7 @@ void G1CollectedHeap::verify_region_sets() {
assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */);
// First, check the explicit lists. // First, check the explicit lists.
_hrs.verify(); _hrm.verify();
{ {
// Given that a concurrent operation might be adding regions to // Given that a concurrent operation might be adding regions to
// the secondary free list we have to take the lock before // the secondary free list we have to take the lock before
@ -7016,9 +7028,9 @@ void G1CollectedHeap::verify_region_sets() {
// Finally, make sure that the region accounting in the lists is // Finally, make sure that the region accounting in the lists is
// consistent with what we see in the heap. // consistent with what we see in the heap.
VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrs); VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_hrm);
heap_region_iterate(&cl); heap_region_iterate(&cl);
cl.verify_counts(&_old_set, &_humongous_set, &_hrs); cl.verify_counts(&_old_set, &_humongous_set, &_hrm);
} }
// Optimized nmethod scanning // Optimized nmethod scanning

View File

@ -33,7 +33,7 @@
#include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/g1YCTypes.hpp" #include "gc_implementation/g1/g1YCTypes.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionManager.hpp"
#include "gc_implementation/g1/heapRegionSet.hpp" #include "gc_implementation/g1/heapRegionSet.hpp"
#include "gc_implementation/shared/hSpaceCounters.hpp" #include "gc_implementation/shared/hSpaceCounters.hpp"
#include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp"
@ -291,7 +291,7 @@ private:
G1RegionMappingChangedListener _listener; G1RegionMappingChangedListener _listener;
// The sequence of all heap regions in the heap. // The sequence of all heap regions in the heap.
HeapRegionSeq _hrs; HeapRegionManager _hrm;
// Alloc region used to satisfy mutator allocation requests. // Alloc region used to satisfy mutator allocation requests.
MutatorAllocRegion _mutator_alloc_region; MutatorAllocRegion _mutator_alloc_region;
@ -415,6 +415,7 @@ private:
volatile unsigned int _old_marking_cycles_completed; volatile unsigned int _old_marking_cycles_completed;
bool _concurrent_cycle_started; bool _concurrent_cycle_started;
bool _heap_summary_sent;
// This is a non-product method that is helpful for testing. It is // This is a non-product method that is helpful for testing. It is
// called at the end of a GC and artificially expands the heap by // called at the end of a GC and artificially expands the heap by
@ -429,7 +430,7 @@ private:
// If the HR printer is active, dump the state of the regions in the // If the HR printer is active, dump the state of the regions in the
// heap after a compaction. // heap after a compaction.
void print_hrs_post_compaction(); void print_hrm_post_compaction();
double verify(bool guard, const char* msg); double verify(bool guard, const char* msg);
void verify_before_gc(); void verify_before_gc();
@ -715,7 +716,7 @@ public:
// We register a region with the fast "in collection set" test. We // We register a region with the fast "in collection set" test. We
// simply set to true the array slot corresponding to this region. // simply set to true the array slot corresponding to this region.
void register_region_with_in_cset_fast_test(HeapRegion* r) { void register_region_with_in_cset_fast_test(HeapRegion* r) {
_in_cset_fast_test.set_in_cset(r->hrs_index()); _in_cset_fast_test.set_in_cset(r->hrm_index());
} }
// This is a fast test on whether a reference points into the // This is a fast test on whether a reference points into the
@ -1171,17 +1172,17 @@ public:
// But G1CollectedHeap doesn't yet support this. // But G1CollectedHeap doesn't yet support this.
virtual bool is_maximal_no_gc() const { virtual bool is_maximal_no_gc() const {
return _hrs.available() == 0; return _hrm.available() == 0;
} }
// The current number of regions in the heap. // The current number of regions in the heap.
uint num_regions() const { return _hrs.length(); } uint num_regions() const { return _hrm.length(); }
// The max number of regions in the heap. // The max number of regions in the heap.
uint max_regions() const { return _hrs.max_length(); } uint max_regions() const { return _hrm.max_length(); }
// The number of regions that are completely free. // The number of regions that are completely free.
uint num_free_regions() const { return _hrs.num_free_regions(); } uint num_free_regions() const { return _hrm.num_free_regions(); }
// The number of regions that are not completely free. // The number of regions that are not completely free.
uint num_used_regions() const { return num_regions() - num_free_regions(); } uint num_used_regions() const { return num_regions() - num_free_regions(); }
@ -1233,7 +1234,7 @@ public:
#ifdef ASSERT #ifdef ASSERT
bool is_on_master_free_list(HeapRegion* hr) { bool is_on_master_free_list(HeapRegion* hr) {
return _hrs.is_free(hr); return _hrm.is_free(hr);
} }
#endif // ASSERT #endif // ASSERT
@ -1245,7 +1246,7 @@ public:
} }
void append_secondary_free_list() { void append_secondary_free_list() {
_hrs.insert_list_into_free_list(&_secondary_free_list); _hrm.insert_list_into_free_list(&_secondary_free_list);
} }
void append_secondary_free_list_if_not_empty_with_lock() { void append_secondary_free_list_if_not_empty_with_lock() {
@ -1356,13 +1357,13 @@ public:
// Return "TRUE" iff the given object address is in the reserved // Return "TRUE" iff the given object address is in the reserved
// region of g1. // region of g1.
bool is_in_g1_reserved(const void* p) const { bool is_in_g1_reserved(const void* p) const {
return _hrs.reserved().contains(p); return _hrm.reserved().contains(p);
} }
// Returns a MemRegion that corresponds to the space that has been // Returns a MemRegion that corresponds to the space that has been
// reserved for the heap // reserved for the heap
MemRegion g1_reserved() const { MemRegion g1_reserved() const {
return _hrs.reserved(); return _hrm.reserved();
} }
virtual bool is_in_closed_subset(const void* p) const; virtual bool is_in_closed_subset(const void* p) const;

View File

@ -30,15 +30,15 @@
#include "gc_implementation/g1/g1AllocRegion.inline.hpp" #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp" #include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/g1/heapRegionSet.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "runtime/orderAccess.inline.hpp" #include "runtime/orderAccess.inline.hpp"
#include "utilities/taskqueue.hpp" #include "utilities/taskqueue.hpp"
// Inline functions for G1CollectedHeap // Inline functions for G1CollectedHeap
// Return the region with the given index. It assumes the index is valid. // Return the region with the given index. It assumes the index is valid.
inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrs.at(index); } inline HeapRegion* G1CollectedHeap::region_at(uint index) const { return _hrm.at(index); }
inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const { inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
assert(is_in_reserved(addr), assert(is_in_reserved(addr),
@ -48,7 +48,7 @@ inline uint G1CollectedHeap::addr_to_region(HeapWord* addr) const {
} }
inline HeapWord* G1CollectedHeap::bottom_addr_for_region(uint index) const { inline HeapWord* G1CollectedHeap::bottom_addr_for_region(uint index) const {
return _hrs.reserved().start() + index * HeapRegion::GrainWords; return _hrm.reserved().start() + index * HeapRegion::GrainWords;
} }
template <class T> template <class T>
@ -57,7 +57,7 @@ inline HeapRegion* G1CollectedHeap::heap_region_containing_raw(const T addr) con
assert(is_in_g1_reserved((const void*) addr), assert(is_in_g1_reserved((const void*) addr),
err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")", err_msg("Address "PTR_FORMAT" is outside of the heap ranging from ["PTR_FORMAT" to "PTR_FORMAT")",
p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end()))); p2i((void*)addr), p2i(g1_reserved().start()), p2i(g1_reserved().end())));
return _hrs.addr_to_region((HeapWord*) addr); return _hrm.addr_to_region((HeapWord*) addr);
} }
template <class T> template <class T>
@ -87,7 +87,7 @@ inline void G1CollectedHeap::old_set_remove(HeapRegion* hr) {
} }
inline bool G1CollectedHeap::obj_in_cs(oop obj) { inline bool G1CollectedHeap::obj_in_cs(oop obj) {
HeapRegion* r = _hrs.addr_to_region((HeapWord*) obj); HeapRegion* r = _hrm.addr_to_region((HeapWord*) obj);
return r != NULL && r->in_collection_set(); return r != NULL && r->in_collection_set();
} }

View File

@ -32,7 +32,7 @@
#include "gc_implementation/g1/g1GCPhaseTimes.hpp" #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
#include "oops/oop.inline.hpp" #include "oops/oop.inline.hpp"

View File

@ -29,7 +29,7 @@
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/heapRegion.inline.hpp" #include "gc_implementation/g1/heapRegion.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/shared/liveRange.hpp" #include "gc_implementation/shared/liveRange.hpp"
#include "memory/genOopClosures.inline.hpp" #include "memory/genOopClosures.inline.hpp"
#include "memory/iterator.hpp" #include "memory/iterator.hpp"
@ -322,34 +322,11 @@ bool HeapRegion::claimHeapRegion(jint claimValue) {
return false; return false;
} }
HeapWord* HeapRegion::next_block_start_careful(HeapWord* addr) { HeapRegion::HeapRegion(uint hrm_index,
HeapWord* low = addr;
HeapWord* high = end();
while (low < high) {
size_t diff = pointer_delta(high, low);
// Must add one below to bias toward the high amount. Otherwise, if
// "high" were at the desired value, and "low" were one less, we
// would not converge on "high". This is not symmetric, because
// we set "high" to a block start, which might be the right one,
// which we don't do for "low".
HeapWord* middle = low + (diff+1)/2;
if (middle == high) return high;
HeapWord* mid_bs = block_start_careful(middle);
if (mid_bs < addr) {
low = middle;
} else {
high = mid_bs;
}
}
assert(low == high && low >= addr, "Didn't work.");
return low;
}
HeapRegion::HeapRegion(uint hrs_index,
G1BlockOffsetSharedArray* sharedOffsetArray, G1BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr) : MemRegion mr) :
G1OffsetTableContigSpace(sharedOffsetArray, mr), G1OffsetTableContigSpace(sharedOffsetArray, mr),
_hrs_index(hrs_index), _hrm_index(hrm_index),
_humongous_type(NotHumongous), _humongous_start_region(NULL), _humongous_type(NotHumongous), _humongous_start_region(NULL),
_in_collection_set(false), _in_collection_set(false),
_next_in_special_set(NULL), _orig_end(NULL), _next_in_special_set(NULL), _orig_end(NULL),

View File

@ -54,15 +54,15 @@ class nmethod;
#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]" #define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
#define HR_FORMAT_PARAMS(_hr_) \ #define HR_FORMAT_PARAMS(_hr_) \
(_hr_)->hrs_index(), \ (_hr_)->hrm_index(), \
(_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \ (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
(_hr_)->startsHumongous() ? "HS" : \ (_hr_)->startsHumongous() ? "HS" : \
(_hr_)->continuesHumongous() ? "HC" : \ (_hr_)->continuesHumongous() ? "HC" : \
!(_hr_)->is_empty() ? "O" : "F", \ !(_hr_)->is_empty() ? "O" : "F", \
p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end()) p2i((_hr_)->bottom()), p2i((_hr_)->top()), p2i((_hr_)->end())
// sentinel value for hrs_index // sentinel value for hrm_index
#define G1_NO_HRS_INDEX ((uint) -1) #define G1_NO_HRM_INDEX ((uint) -1)
// A dirty card to oop closure for heap regions. It // A dirty card to oop closure for heap regions. It
// knows how to get the G1 heap and how to use the bitmap // knows how to get the G1 heap and how to use the bitmap
@ -206,10 +206,6 @@ class G1OffsetTableContigSpace: public CompactibleSpace {
_offsets.reset_bot(); _offsets.reset_bot();
} }
void update_bot_for_object(HeapWord* start, size_t word_size) {
_offsets.alloc_block(start, word_size);
}
void print_bot_on(outputStream* out) { void print_bot_on(outputStream* out) {
_offsets.print_on(out); _offsets.print_on(out);
} }
@ -234,7 +230,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
protected: protected:
// The index of this region in the heap region sequence. // The index of this region in the heap region sequence.
uint _hrs_index; uint _hrm_index;
HumongousType _humongous_type; HumongousType _humongous_type;
// For a humongous region, region in which it starts. // For a humongous region, region in which it starts.
@ -330,7 +326,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
size_t _predicted_bytes_to_copy; size_t _predicted_bytes_to_copy;
public: public:
HeapRegion(uint hrs_index, HeapRegion(uint hrm_index,
G1BlockOffsetSharedArray* sharedOffsetArray, G1BlockOffsetSharedArray* sharedOffsetArray,
MemRegion mr); MemRegion mr);
@ -385,9 +381,9 @@ class HeapRegion: public G1OffsetTableContigSpace {
inline HeapWord* par_allocate_no_bot_updates(size_t word_size); inline HeapWord* par_allocate_no_bot_updates(size_t word_size);
inline HeapWord* allocate_no_bot_updates(size_t word_size); inline HeapWord* allocate_no_bot_updates(size_t word_size);
// If this region is a member of a HeapRegionSeq, the index in that // If this region is a member of a HeapRegionManager, the index in that
// sequence, otherwise -1. // sequence, otherwise -1.
uint hrs_index() const { return _hrs_index; } uint hrm_index() const { return _hrm_index; }
// The number of bytes marked live in the region in the last marking phase. // The number of bytes marked live in the region in the last marking phase.
size_t marked_bytes() { return _prev_marked_bytes; } size_t marked_bytes() { return _prev_marked_bytes; }
@ -458,7 +454,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
// with this HS region. // with this HS region.
uint last_hc_index() const { uint last_hc_index() const {
assert(startsHumongous(), "don't call this otherwise"); assert(startsHumongous(), "don't call this otherwise");
return hrs_index() + region_num(); return hrm_index() + region_num();
} }
// Same as Space::is_in_reserved, but will use the original size of the region. // Same as Space::is_in_reserved, but will use the original size of the region.
@ -570,7 +566,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; } void set_next_dirty_cards_region(HeapRegion* hr) { _next_dirty_cards_region = hr; }
bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; } bool is_on_dirty_cards_region_list() const { return get_next_dirty_cards_region() != NULL; }
HeapWord* orig_end() { return _orig_end; } HeapWord* orig_end() const { return _orig_end; }
// Reset HR stuff to default values. // Reset HR stuff to default values.
void hr_clear(bool par, bool clear_space, bool locked = false); void hr_clear(bool par, bool clear_space, bool locked = false);
@ -737,18 +733,6 @@ class HeapRegion: public G1OffsetTableContigSpace {
bool filter_young, bool filter_young,
jbyte* card_ptr); jbyte* card_ptr);
// A version of block start that is guaranteed to find *some* block
// boundary at or before "p", but does not object iteration, and may
// therefore be used safely when the heap is unparseable.
HeapWord* block_start_careful(const void* p) const {
return _offsets.block_start_careful(p);
}
// Requires that "addr" is within the region. Returns the start of the
// first ("careful") block that starts at or after "addr", or else the
// "end" of the region if there is no such block.
HeapWord* next_block_start_careful(HeapWord* addr);
size_t recorded_rs_length() const { return _recorded_rs_length; } size_t recorded_rs_length() const { return _recorded_rs_length; }
double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; } double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; } size_t predicted_bytes_to_copy() const { return _predicted_bytes_to_copy; }
@ -813,7 +797,7 @@ class HeapRegion: public G1OffsetTableContigSpace {
// HeapRegionClosure is used for iterating over regions. // HeapRegionClosure is used for iterating over regions.
// Terminates the iteration when the "doHeapRegion" method returns "true". // Terminates the iteration when the "doHeapRegion" method returns "true".
class HeapRegionClosure : public StackObj { class HeapRegionClosure : public StackObj {
friend class HeapRegionSeq; friend class HeapRegionManager;
friend class G1CollectedHeap; friend class G1CollectedHeap;
bool _complete; bool _complete;

View File

@ -24,13 +24,13 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/g1/heapRegionSet.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/concurrentG1Refine.hpp" #include "gc_implementation/g1/concurrentG1Refine.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
void HeapRegionSeq::initialize(G1RegionToSpaceMapper* heap_storage, void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
G1RegionToSpaceMapper* prev_bitmap, G1RegionToSpaceMapper* prev_bitmap,
G1RegionToSpaceMapper* next_bitmap, G1RegionToSpaceMapper* next_bitmap,
G1RegionToSpaceMapper* bot, G1RegionToSpaceMapper* bot,
@ -55,24 +55,24 @@ void HeapRegionSeq::initialize(G1RegionToSpaceMapper* heap_storage,
_available_map.clear(); _available_map.clear();
} }
bool HeapRegionSeq::is_available(uint region) const { bool HeapRegionManager::is_available(uint region) const {
return _available_map.at(region); return _available_map.at(region);
} }
#ifdef ASSERT #ifdef ASSERT
bool HeapRegionSeq::is_free(HeapRegion* hr) const { bool HeapRegionManager::is_free(HeapRegion* hr) const {
return _free_list.contains(hr); return _free_list.contains(hr);
} }
#endif #endif
HeapRegion* HeapRegionSeq::new_heap_region(uint hrs_index) { HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrs_index); HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrm_index);
MemRegion mr(bottom, bottom + HeapRegion::GrainWords); MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
assert(reserved().contains(mr), "invariant"); assert(reserved().contains(mr), "invariant");
return new HeapRegion(hrs_index, G1CollectedHeap::heap()->bot_shared(), mr); return new HeapRegion(hrm_index, G1CollectedHeap::heap()->bot_shared(), mr);
} }
void HeapRegionSeq::commit_regions(uint index, size_t num_regions) { void HeapRegionManager::commit_regions(uint index, size_t num_regions) {
guarantee(num_regions > 0, "Must commit more than zero regions"); guarantee(num_regions > 0, "Must commit more than zero regions");
guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions"); guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
@ -90,7 +90,7 @@ void HeapRegionSeq::commit_regions(uint index, size_t num_regions) {
_card_counts_mapper->commit_regions(index, num_regions); _card_counts_mapper->commit_regions(index, num_regions);
} }
void HeapRegionSeq::uncommit_regions(uint start, size_t num_regions) { void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start)); guarantee(num_regions >= 1, err_msg("Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start));
guarantee(_num_committed >= num_regions, "pre-condition"); guarantee(_num_committed >= num_regions, "pre-condition");
@ -117,7 +117,7 @@ void HeapRegionSeq::uncommit_regions(uint start, size_t num_regions) {
_card_counts_mapper->uncommit_regions(start, num_regions); _card_counts_mapper->uncommit_regions(start, num_regions);
} }
void HeapRegionSeq::make_regions_available(uint start, uint num_regions) { void HeapRegionManager::make_regions_available(uint start, uint num_regions) {
guarantee(num_regions > 0, "No point in calling this for zero regions"); guarantee(num_regions > 0, "No point in calling this for zero regions");
commit_regions(start, num_regions); commit_regions(start, num_regions);
for (uint i = start; i < start + num_regions; i++) { for (uint i = start; i < start + num_regions; i++) {
@ -144,11 +144,11 @@ void HeapRegionSeq::make_regions_available(uint start, uint num_regions) {
} }
} }
uint HeapRegionSeq::expand_by(uint num_regions) { uint HeapRegionManager::expand_by(uint num_regions) {
return expand_at(0, num_regions); return expand_at(0, num_regions);
} }
uint HeapRegionSeq::expand_at(uint start, uint num_regions) { uint HeapRegionManager::expand_at(uint start, uint num_regions) {
if (num_regions == 0) { if (num_regions == 0) {
return 0; return 0;
} }
@ -171,7 +171,7 @@ uint HeapRegionSeq::expand_at(uint start, uint num_regions) {
return expanded; return expanded;
} }
uint HeapRegionSeq::find_contiguous(size_t num, bool empty_only) { uint HeapRegionManager::find_contiguous(size_t num, bool empty_only) {
uint found = 0; uint found = 0;
size_t length_found = 0; size_t length_found = 0;
uint cur = 0; uint cur = 0;
@ -199,14 +199,14 @@ uint HeapRegionSeq::find_contiguous(size_t num, bool empty_only) {
} }
return found; return found;
} else { } else {
return G1_NO_HRS_INDEX; return G1_NO_HRM_INDEX;
} }
} }
HeapRegion* HeapRegionSeq::next_region_in_heap(const HeapRegion* r) const { HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
guarantee(r != NULL, "Start region must be a valid region"); guarantee(r != NULL, "Start region must be a valid region");
guarantee(is_available(r->hrs_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrs_index())); guarantee(is_available(r->hrm_index()), err_msg("Trying to iterate starting from region %u which is not in the heap", r->hrm_index()));
for (uint i = r->hrs_index() + 1; i < _allocated_heapregions_length; i++) { for (uint i = r->hrm_index() + 1; i < _allocated_heapregions_length; i++) {
HeapRegion* hr = _regions.get_by_index(i); HeapRegion* hr = _regions.get_by_index(i);
if (is_available(i)) { if (is_available(i)) {
return hr; return hr;
@ -215,7 +215,7 @@ HeapRegion* HeapRegionSeq::next_region_in_heap(const HeapRegion* r) const {
return NULL; return NULL;
} }
void HeapRegionSeq::iterate(HeapRegionClosure* blk) const { void HeapRegionManager::iterate(HeapRegionClosure* blk) const {
uint len = max_length(); uint len = max_length();
for (uint i = 0; i < len; i++) { for (uint i = 0; i < len; i++) {
@ -231,7 +231,7 @@ void HeapRegionSeq::iterate(HeapRegionClosure* blk) const {
} }
} }
uint HeapRegionSeq::find_unavailable_from_idx(uint start_idx, uint* res_idx) const { uint HeapRegionManager::find_unavailable_from_idx(uint start_idx, uint* res_idx) const {
guarantee(res_idx != NULL, "checking"); guarantee(res_idx != NULL, "checking");
guarantee(start_idx <= (max_length() + 1), "checking"); guarantee(start_idx <= (max_length() + 1), "checking");
@ -259,11 +259,11 @@ uint HeapRegionSeq::find_unavailable_from_idx(uint start_idx, uint* res_idx) con
return num_regions; return num_regions;
} }
uint HeapRegionSeq::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const { uint HeapRegionManager::start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const {
return num_regions * worker_i / num_workers; return num_regions * worker_i / num_workers;
} }
void HeapRegionSeq::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const { void HeapRegionManager::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num_workers, jint claim_value) const {
const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length); const uint start_index = start_region_for_worker(worker_id, num_workers, _allocated_heapregions_length);
// Every worker will actually look at all regions, skipping over regions that // Every worker will actually look at all regions, skipping over regions that
@ -334,7 +334,7 @@ void HeapRegionSeq::par_iterate(HeapRegionClosure* blk, uint worker_id, uint num
} }
} }
uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) { uint HeapRegionManager::shrink_by(uint num_regions_to_remove) {
assert(length() > 0, "the region sequence should not be empty"); assert(length() > 0, "the region sequence should not be empty");
assert(length() <= _allocated_heapregions_length, "invariant"); assert(length() <= _allocated_heapregions_length, "invariant");
assert(_allocated_heapregions_length > 0, "we should have at least one region committed"); assert(_allocated_heapregions_length > 0, "we should have at least one region committed");
@ -351,10 +351,6 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
while ((removed < num_regions_to_remove) && while ((removed < num_regions_to_remove) &&
(num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) { (num_last_found = find_empty_from_idx_reverse(cur, &idx_last_found)) > 0) {
// Only allow uncommit from the end of the heap.
if ((idx_last_found + num_last_found) != _allocated_heapregions_length) {
return 0;
}
uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found); uint to_remove = MIN2(num_regions_to_remove - removed, num_last_found);
uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove); uncommit_regions(idx_last_found + num_last_found - to_remove, to_remove);
@ -368,7 +364,7 @@ uint HeapRegionSeq::shrink_by(uint num_regions_to_remove) {
return removed; return removed;
} }
uint HeapRegionSeq::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const { uint HeapRegionManager::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const {
guarantee(start_idx < _allocated_heapregions_length, "checking"); guarantee(start_idx < _allocated_heapregions_length, "checking");
guarantee(res_idx != NULL, "checking"); guarantee(res_idx != NULL, "checking");
@ -397,7 +393,7 @@ uint HeapRegionSeq::find_empty_from_idx_reverse(uint start_idx, uint* res_idx) c
return num_regions_found; return num_regions_found;
} }
void HeapRegionSeq::verify() { void HeapRegionManager::verify() {
guarantee(length() <= _allocated_heapregions_length, guarantee(length() <= _allocated_heapregions_length,
err_msg("invariant: _length: %u _allocated_length: %u", err_msg("invariant: _length: %u _allocated_length: %u",
length(), _allocated_heapregions_length)); length(), _allocated_heapregions_length));
@ -419,8 +415,8 @@ void HeapRegionSeq::verify() {
guarantee(!prev_committed || hr->bottom() == prev_end, guarantee(!prev_committed || hr->bottom() == prev_end,
err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT, err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
i, HR_FORMAT_PARAMS(hr), p2i(prev_end))); i, HR_FORMAT_PARAMS(hr), p2i(prev_end)));
guarantee(hr->hrs_index() == i, guarantee(hr->hrm_index() == i,
err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index())); err_msg("invariant: i: %u hrm_index(): %u", i, hr->hrm_index()));
// Asserts will fire if i is >= _length // Asserts will fire if i is >= _length
HeapWord* addr = hr->bottom(); HeapWord* addr = hr->bottom();
guarantee(addr_to_region(addr) == hr, "sanity"); guarantee(addr_to_region(addr) == hr, "sanity");
@ -443,7 +439,7 @@ void HeapRegionSeq::verify() {
} }
#ifndef PRODUCT #ifndef PRODUCT
void HeapRegionSeq::verify_optional() { void HeapRegionManager::verify_optional() {
verify(); verify();
} }
#endif // PRODUCT #endif // PRODUCT

View File

@ -22,8 +22,8 @@
* *
*/ */
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP
#include "gc_implementation/g1/g1BiasedArray.hpp" #include "gc_implementation/g1/g1BiasedArray.hpp"
#include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp"
@ -64,7 +64,7 @@ class G1HeapRegionTable : public G1BiasedMappedArray<HeapRegion*> {
// * max_length() returns the maximum number of regions the heap can have. // * max_length() returns the maximum number of regions the heap can have.
// //
class HeapRegionSeq: public CHeapObj<mtGC> { class HeapRegionManager: public CHeapObj<mtGC> {
friend class VMStructs; friend class VMStructs;
G1HeapRegionTable _regions; G1HeapRegionTable _regions;
@ -104,7 +104,7 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const; uint start_region_for_worker(uint worker_i, uint num_workers, uint num_regions) const;
// Find a contiguous set of empty or uncommitted regions of length num and return // Find a contiguous set of empty or uncommitted regions of length num and return
// the index of the first region or G1_NO_HRS_INDEX if the search was unsuccessful. // the index of the first region or G1_NO_HRM_INDEX if the search was unsuccessful.
// If only_empty is true, only empty regions are considered. // If only_empty is true, only empty regions are considered.
// Searches from bottom to top of the heap, doing a first-fit. // Searches from bottom to top of the heap, doing a first-fit.
uint find_contiguous(size_t num, bool only_empty); uint find_contiguous(size_t num, bool only_empty);
@ -117,7 +117,7 @@ class HeapRegionSeq: public CHeapObj<mtGC> {
// sequence could be found, otherwise res_idx contains the start index of this range. // sequence could be found, otherwise res_idx contains the start index of this range.
uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const; uint find_empty_from_idx_reverse(uint start_idx, uint* res_idx) const;
// Allocate a new HeapRegion for the given index. // Allocate a new HeapRegion for the given index.
HeapRegion* new_heap_region(uint hrs_index); HeapRegion* new_heap_region(uint hrm_index);
#ifdef ASSERT #ifdef ASSERT
public: public:
bool is_free(HeapRegion* hr) const; bool is_free(HeapRegion* hr) const;
@ -127,7 +127,7 @@ public:
public: public:
// Empty constructor, we'll initialize it with the initialize() method. // Empty constructor, we'll initialize it with the initialize() method.
HeapRegionSeq() : _regions(), _heap_mapper(NULL), _num_committed(0), HeapRegionManager() : _regions(), _heap_mapper(NULL), _num_committed(0),
_next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL), _next_bitmap_mapper(NULL), _prev_bitmap_mapper(NULL), _bot_mapper(NULL),
_allocated_heapregions_length(0), _available_map(), _allocated_heapregions_length(0), _available_map(),
_free_list("Free list", new MasterFreeRegionListMtSafeChecker()) _free_list("Free list", new MasterFreeRegionListMtSafeChecker())
@ -167,7 +167,7 @@ public:
if (hr != NULL) { if (hr != NULL) {
assert(hr->next() == NULL, "Single region should not have next"); assert(hr->next() == NULL, "Single region should not have next");
assert(is_available(hr->hrs_index()), "Must be committed"); assert(is_available(hr->hrm_index()), "Must be committed");
} }
return hr; return hr;
} }
@ -211,10 +211,10 @@ public:
uint expand_at(uint start, uint num_regions); uint expand_at(uint start, uint num_regions);
// Find a contiguous set of empty regions of length num. Returns the start index of // Find a contiguous set of empty regions of length num. Returns the start index of
// that set, or G1_NO_HRS_INDEX. // that set, or G1_NO_HRM_INDEX.
uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); } uint find_contiguous_only_empty(size_t num) { return find_contiguous(num, true); }
// Find a contiguous set of empty or unavailable regions of length num. Returns the // Find a contiguous set of empty or unavailable regions of length num. Returns the
// start index of that set, or G1_NO_HRS_INDEX. // start index of that set, or G1_NO_HRM_INDEX.
uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); } uint find_contiguous_empty_or_unavailable(size_t num) { return find_contiguous(num, false); }
HeapRegion* next_region_in_heap(const HeapRegion* r) const; HeapRegion* next_region_in_heap(const HeapRegion* r) const;
@ -235,5 +235,5 @@ public:
void verify_optional() PRODUCT_RETURN; void verify_optional() PRODUCT_RETURN;
}; };
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_HPP #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_HPP

View File

@ -22,14 +22,14 @@
* *
*/ */
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP #ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP
#include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/heapRegionSeq.hpp" #include "gc_implementation/g1/heapRegionManager.hpp"
#include "gc_implementation/g1/heapRegionSet.inline.hpp" #include "gc_implementation/g1/heapRegionSet.inline.hpp"
inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const { inline HeapRegion* HeapRegionManager::addr_to_region(HeapWord* addr) const {
assert(addr < heap_end(), assert(addr < heap_end(),
err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end()))); err_msg("addr: "PTR_FORMAT" end: "PTR_FORMAT, p2i(addr), p2i(heap_end())));
assert(addr >= heap_bottom(), assert(addr >= heap_bottom(),
@ -39,20 +39,20 @@ inline HeapRegion* HeapRegionSeq::addr_to_region(HeapWord* addr) const {
return hr; return hr;
} }
inline HeapRegion* HeapRegionSeq::at(uint index) const { inline HeapRegion* HeapRegionManager::at(uint index) const {
assert(is_available(index), "pre-condition"); assert(is_available(index), "pre-condition");
HeapRegion* hr = _regions.get_by_index(index); HeapRegion* hr = _regions.get_by_index(index);
assert(hr != NULL, "sanity"); assert(hr != NULL, "sanity");
assert(hr->hrs_index() == index, "sanity"); assert(hr->hrm_index() == index, "sanity");
return hr; return hr;
} }
inline void HeapRegionSeq::insert_into_free_list(HeapRegion* hr) { inline void HeapRegionManager::insert_into_free_list(HeapRegion* hr) {
_free_list.add_ordered(hr); _free_list.add_ordered(hr);
} }
inline void HeapRegionSeq::allocate_free_regions_starting_at(uint first, uint num_regions) { inline void HeapRegionManager::allocate_free_regions_starting_at(uint first, uint num_regions) {
_free_list.remove_starting_at(at(first), num_regions); _free_list.remove_starting_at(at(first), num_regions);
} }
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSEQ_INLINE_HPP #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONMANAGER_INLINE_HPP

View File

@ -27,7 +27,7 @@
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp" #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp" #include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "memory/padded.inline.hpp" #include "memory/padded.inline.hpp"
#include "memory/space.inline.hpp" #include "memory/space.inline.hpp"
@ -420,7 +420,7 @@ void OtherRegionsTable::print_from_card_cache() {
} }
void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) { void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
uint cur_hrs_ind = hr()->hrs_index(); uint cur_hrm_ind = hr()->hrm_index();
if (G1TraceHeapRegionRememberedSet) { if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
@ -435,10 +435,10 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
if (G1TraceHeapRegionRememberedSet) { if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)", gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
hr()->bottom(), from_card, hr()->bottom(), from_card,
FromCardCache::at((uint)tid, cur_hrs_ind)); FromCardCache::at((uint)tid, cur_hrm_ind));
} }
if (FromCardCache::contains_or_replace((uint)tid, cur_hrs_ind, from_card)) { if (FromCardCache::contains_or_replace((uint)tid, cur_hrm_ind, from_card)) {
if (G1TraceHeapRegionRememberedSet) { if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print_cr(" from-card cache hit."); gclog_or_tty->print_cr(" from-card cache hit.");
} }
@ -448,7 +448,7 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
// Note that this may be a continued H region. // Note that this may be a continued H region.
HeapRegion* from_hr = _g1h->heap_region_containing_raw(from); HeapRegion* from_hr = _g1h->heap_region_containing_raw(from);
RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrs_index(); RegionIdx_t from_hrs_ind = (RegionIdx_t) from_hr->hrm_index();
// If the region is already coarsened, return. // If the region is already coarsened, return.
if (_coarse_map.at(from_hrs_ind)) { if (_coarse_map.at(from_hrs_ind)) {
@ -495,7 +495,7 @@ void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
if (G1TraceHeapRegionRememberedSet) { if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print_cr(" [tid %d] sparse table entry " gclog_or_tty->print_cr(" [tid %d] sparse table entry "
"overflow(f: %d, t: %u)", "overflow(f: %d, t: %u)",
tid, from_hrs_ind, cur_hrs_ind); tid, from_hrs_ind, cur_hrm_ind);
} }
} }
@ -607,9 +607,9 @@ PerRegionTable* OtherRegionsTable::delete_region_table() {
guarantee(max != NULL, "Since _n_fine_entries > 0"); guarantee(max != NULL, "Since _n_fine_entries > 0");
// Set the corresponding coarse bit. // Set the corresponding coarse bit.
size_t max_hrs_index = (size_t) max->hr()->hrs_index(); size_t max_hrm_index = (size_t) max->hr()->hrm_index();
if (!_coarse_map.at(max_hrs_index)) { if (!_coarse_map.at(max_hrm_index)) {
_coarse_map.at_put(max_hrs_index, true); _coarse_map.at_put(max_hrm_index, true);
_n_coarse_entries++; _n_coarse_entries++;
if (G1TraceHeapRegionRememberedSet) { if (G1TraceHeapRegionRememberedSet) {
gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
@ -633,7 +633,7 @@ void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
BitMap* region_bm, BitMap* card_bm) { BitMap* region_bm, BitMap* card_bm) {
// First eliminated garbage regions from the coarse map. // First eliminated garbage regions from the coarse map.
if (G1RSScrubVerbose) { if (G1RSScrubVerbose) {
gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index()); gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index());
} }
assert(_coarse_map.size() == region_bm->size(), "Precondition"); assert(_coarse_map.size() == region_bm->size(), "Precondition");
@ -656,9 +656,9 @@ void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
// If the entire region is dead, eliminate. // If the entire region is dead, eliminate.
if (G1RSScrubVerbose) { if (G1RSScrubVerbose) {
gclog_or_tty->print_cr(" For other region %u:", gclog_or_tty->print_cr(" For other region %u:",
cur->hr()->hrs_index()); cur->hr()->hrm_index());
} }
if (!region_bm->at((size_t) cur->hr()->hrs_index())) { if (!region_bm->at((size_t) cur->hr()->hrm_index())) {
*prev = nxt; *prev = nxt;
cur->set_collision_list_next(NULL); cur->set_collision_list_next(NULL);
_n_fine_entries--; _n_fine_entries--;
@ -752,7 +752,7 @@ size_t OtherRegionsTable::fl_mem_size() {
} }
void OtherRegionsTable::clear_fcc() { void OtherRegionsTable::clear_fcc() {
FromCardCache::clear(hr()->hrs_index()); FromCardCache::clear(hr()->hrm_index());
} }
void OtherRegionsTable::clear() { void OtherRegionsTable::clear() {
@ -803,7 +803,7 @@ bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const {
bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const { bool OtherRegionsTable::contains_reference_locked(OopOrNarrowOopStar from) const {
HeapRegion* hr = _g1h->heap_region_containing_raw(from); HeapRegion* hr = _g1h->heap_region_containing_raw(from);
RegionIdx_t hr_ind = (RegionIdx_t) hr->hrs_index(); RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index();
// Is this region in the coarse map? // Is this region in the coarse map?
if (_coarse_map.at(hr_ind)) return true; if (_coarse_map.at(hr_ind)) return true;
@ -840,7 +840,7 @@ uint HeapRegionRemSet::num_par_rem_sets() {
HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa,
HeapRegion* hr) HeapRegion* hr)
: _bosa(bosa), : _bosa(bosa),
_m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrs_index()), true), _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true),
_code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) { _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) {
reset_for_par_iteration(); reset_for_par_iteration();
} }

View File

@ -39,11 +39,11 @@ void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
#ifndef PRODUCT #ifndef PRODUCT
void HeapRegionSetBase::verify_region(HeapRegion* hr) { void HeapRegionSetBase::verify_region(HeapRegion* hr) {
assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrs_index())); assert(hr->containing_set() == this, err_msg("Inconsistent containing set for %u", hr->hrm_index()));
assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrs_index())); // currently we don't use these sets for young regions assert(!hr->is_young(), err_msg("Adding young region %u", hr->hrm_index())); // currently we don't use these sets for young regions
assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrs_index(), name())); assert(hr->isHumongous() == regions_humongous(), err_msg("Wrong humongous state for region %u and set %s", hr->hrm_index(), name()));
assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrs_index(), name())); assert(hr->is_empty() == regions_empty(), err_msg("Wrong empty state for region %u and set %s", hr->hrm_index(), name()));
assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrs_index())); assert(hr->rem_set()->verify_ready_for_par_iteration(), err_msg("Wrong iteration state %u", hr->hrm_index()));
} }
#endif #endif
@ -158,7 +158,7 @@ void FreeRegionList::add_ordered(FreeRegionList* from_list) {
HeapRegion* curr_from = from_list->_head; HeapRegion* curr_from = from_list->_head;
while (curr_from != NULL) { while (curr_from != NULL) {
while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) { while (curr_to != NULL && curr_to->hrm_index() < curr_from->hrm_index()) {
curr_to = curr_to->next(); curr_to = curr_to->next();
} }
@ -183,7 +183,7 @@ void FreeRegionList::add_ordered(FreeRegionList* from_list) {
} }
} }
if (_tail->hrs_index() < from_list->_tail->hrs_index()) { if (_tail->hrm_index() < from_list->_tail->hrm_index()) {
_tail = from_list->_tail; _tail = from_list->_tail;
} }
} }
@ -309,8 +309,8 @@ void FreeRegionList::verify_list() {
if (curr->next() != NULL) { if (curr->next() != NULL) {
guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up");
} }
guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted"); guarantee(curr->hrm_index() == 0 || curr->hrm_index() > last_index, "List should be sorted");
last_index = curr->hrs_index(); last_index = curr->hrm_index();
capacity += curr->capacity(); capacity += curr->capacity();
@ -319,7 +319,7 @@ void FreeRegionList::verify_list() {
curr = curr->next(); curr = curr->next();
} }
guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrs_index(), prev0->hrs_index())); guarantee(_tail == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), _tail->hrm_index(), prev0->hrm_index()));
guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next"); guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next");
guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count)); guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count));
guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT,

View File

@ -238,14 +238,14 @@ public:
// Add hr to the list. The region should not be a member of another set. // Add hr to the list. The region should not be a member of another set.
// Assumes that the list is ordered and will preserve that order. The order // Assumes that the list is ordered and will preserve that order. The order
// is determined by hrs_index. // is determined by hrm_index.
inline void add_ordered(HeapRegion* hr); inline void add_ordered(HeapRegion* hr);
// Removes from head or tail based on the given argument. // Removes from head or tail based on the given argument.
HeapRegion* remove_region(bool from_head); HeapRegion* remove_region(bool from_head);
// Merge two ordered lists. The result is also ordered. The order is // Merge two ordered lists. The result is also ordered. The order is
// determined by hrs_index. // determined by hrm_index.
void add_ordered(FreeRegionList* from_list); void add_ordered(FreeRegionList* from_list);
// It empties the list by removing all regions from it. // It empties the list by removing all regions from it.

View File

@ -60,14 +60,14 @@ inline void FreeRegionList::add_ordered(HeapRegion* hr) {
if (_head != NULL) { if (_head != NULL) {
HeapRegion* curr; HeapRegion* curr;
if (_last != NULL && _last->hrs_index() < hr->hrs_index()) { if (_last != NULL && _last->hrm_index() < hr->hrm_index()) {
curr = _last; curr = _last;
} else { } else {
curr = _head; curr = _head;
} }
// Find first entry with a Region Index larger than entry to insert. // Find first entry with a Region Index larger than entry to insert.
while (curr != NULL && curr->hrs_index() < hr->hrs_index()) { while (curr != NULL && curr->hrm_index() < hr->hrm_index()) {
curr = curr->next(); curr = curr->next();
} }

View File

@ -453,7 +453,7 @@ size_t SparsePRT::mem_size() const {
bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) { bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
#if SPARSE_PRT_VERBOSE #if SPARSE_PRT_VERBOSE
gclog_or_tty->print_cr(" Adding card %d from region %d to region %u sparse.", gclog_or_tty->print_cr(" Adding card %d from region %d to region %u sparse.",
card_index, region_id, _hr->hrs_index()); card_index, region_id, _hr->hrm_index());
#endif #endif
if (_next->occupied_entries() * 2 > _next->capacity()) { if (_next->occupied_entries() * 2 > _next->capacity()) {
expand(); expand();
@ -505,7 +505,7 @@ void SparsePRT::expand() {
#if SPARSE_PRT_VERBOSE #if SPARSE_PRT_VERBOSE
gclog_or_tty->print_cr(" Expanded sparse table for %u to %d.", gclog_or_tty->print_cr(" Expanded sparse table for %u to %d.",
_hr->hrs_index(), _next->capacity()); _hr->hrm_index(), _next->capacity());
#endif #endif
for (size_t i = 0; i < last->capacity(); i++) { for (size_t i = 0; i < last->capacity(); i++) {
SparsePRTEntry* e = last->entry((int)i); SparsePRTEntry* e = last->entry((int)i);

View File

@ -26,7 +26,7 @@
#define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP #define SHARE_VM_GC_IMPLEMENTATION_G1_VMSTRUCTS_G1_HPP
#include "gc_implementation/g1/heapRegion.hpp" #include "gc_implementation/g1/heapRegion.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#define VM_STRUCTS_G1(nonstatic_field, static_field) \ #define VM_STRUCTS_G1(nonstatic_field, static_field) \
@ -42,10 +42,10 @@
nonstatic_field(G1HeapRegionTable, _bias, size_t) \ nonstatic_field(G1HeapRegionTable, _bias, size_t) \
nonstatic_field(G1HeapRegionTable, _shift_by, uint) \ nonstatic_field(G1HeapRegionTable, _shift_by, uint) \
\ \
nonstatic_field(HeapRegionSeq, _regions, G1HeapRegionTable) \ nonstatic_field(HeapRegionManager, _regions, G1HeapRegionTable) \
nonstatic_field(HeapRegionSeq, _num_committed, uint) \ nonstatic_field(HeapRegionManager, _num_committed, uint) \
\ \
nonstatic_field(G1CollectedHeap, _hrs, HeapRegionSeq) \ nonstatic_field(G1CollectedHeap, _hrm, HeapRegionManager) \
nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \ nonstatic_field(G1CollectedHeap, _summary_bytes_used, size_t) \
nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \ nonstatic_field(G1CollectedHeap, _g1mm, G1MonitoringSupport*) \
nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \ nonstatic_field(G1CollectedHeap, _old_set, HeapRegionSetBase) \
@ -72,7 +72,7 @@
\ \
declare_type(G1OffsetTableContigSpace, CompactibleSpace) \ declare_type(G1OffsetTableContigSpace, CompactibleSpace) \
declare_type(HeapRegion, G1OffsetTableContigSpace) \ declare_type(HeapRegion, G1OffsetTableContigSpace) \
declare_toplevel_type(HeapRegionSeq) \ declare_toplevel_type(HeapRegionManager) \
declare_toplevel_type(HeapRegionSetBase) \ declare_toplevel_type(HeapRegionSetBase) \
declare_toplevel_type(HeapRegionSetCount) \ declare_toplevel_type(HeapRegionSetCount) \
declare_toplevel_type(G1MonitoringSupport) \ declare_toplevel_type(G1MonitoringSupport) \

View File

@ -30,6 +30,8 @@
PSGenerationCounters::PSGenerationCounters(const char* name, PSGenerationCounters::PSGenerationCounters(const char* name,
int ordinal, int spaces, int ordinal, int spaces,
size_t min_capacity,
size_t max_capacity,
PSVirtualSpace* v): PSVirtualSpace* v):
_ps_virtual_space(v) { _ps_virtual_space(v) {
@ -52,11 +54,11 @@ PSGenerationCounters::PSGenerationCounters(const char* name,
cname = PerfDataManager::counter_name(_name_space, "minCapacity"); cname = PerfDataManager::counter_name(_name_space, "minCapacity");
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
_ps_virtual_space->committed_size(), CHECK); min_capacity, CHECK);
cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); cname = PerfDataManager::counter_name(_name_space, "maxCapacity");
PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes,
_ps_virtual_space->reserved_size(), CHECK); max_capacity, CHECK);
cname = PerfDataManager::counter_name(_name_space, "capacity"); cname = PerfDataManager::counter_name(_name_space, "capacity");
_current_size = PerfDataManager::create_variable(SUN_GC, cname, _current_size = PerfDataManager::create_variable(SUN_GC, cname,

View File

@ -41,7 +41,7 @@ class PSGenerationCounters: public GenerationCounters {
public: public:
PSGenerationCounters(const char* name, int ordinal, int spaces, PSGenerationCounters(const char* name, int ordinal, int spaces,
PSVirtualSpace* v); size_t min_capacity, size_t max_capacity, PSVirtualSpace* v);
void update_all() { void update_all() {
assert(_virtual_space == NULL, "Only one should be in use"); assert(_virtual_space == NULL, "Only one should be in use");

View File

@ -149,8 +149,8 @@ void PSOldGen::initialize_work(const char* perf_data_name, int level) {
void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) { void PSOldGen::initialize_performance_counters(const char* perf_data_name, int level) {
// Generation Counters, generation 'level', 1 subspace // Generation Counters, generation 'level', 1 subspace
_gen_counters = new PSGenerationCounters(perf_data_name, level, 1, _gen_counters = new PSGenerationCounters(perf_data_name, level, 1, _min_gen_size,
virtual_space()); _max_gen_size, virtual_space());
_space_counters = new SpaceCounters(perf_data_name, 0, _space_counters = new SpaceCounters(perf_data_name, 0,
virtual_space()->reserved_size(), virtual_space()->reserved_size(),
_object_space, _gen_counters); _object_space, _gen_counters);

View File

@ -101,7 +101,8 @@ void PSYoungGen::initialize_work() {
} }
// Generation Counters - generation 0, 3 subspaces // Generation Counters - generation 0, 3 subspaces
_gen_counters = new PSGenerationCounters("new", 0, 3, _virtual_space); _gen_counters = new PSGenerationCounters("new", 0, 3, _min_gen_size,
_max_gen_size, _virtual_space);
// Compute maximum space sizes for performance counters // Compute maximum space sizes for performance counters
ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();

View File

@ -62,11 +62,12 @@ void GenerationCounters::initialize(const char* name, int ordinal, int spaces,
GenerationCounters::GenerationCounters(const char* name, GenerationCounters::GenerationCounters(const char* name,
int ordinal, int spaces, int ordinal, int spaces,
size_t min_capacity, size_t max_capacity,
VirtualSpace* v) VirtualSpace* v)
: _virtual_space(v) { : _virtual_space(v) {
assert(v != NULL, "don't call this constructor if v == NULL"); assert(v != NULL, "don't call this constructor if v == NULL");
initialize(name, ordinal, spaces, initialize(name, ordinal, spaces,
v->committed_size(), v->reserved_size(), v->committed_size()); min_capacity, max_capacity, v->committed_size());
} }
GenerationCounters::GenerationCounters(const char* name, GenerationCounters::GenerationCounters(const char* name,

View File

@ -66,7 +66,7 @@ private:
public: public:
GenerationCounters(const char* name, int ordinal, int spaces, GenerationCounters(const char* name, int ordinal, int spaces,
VirtualSpace* v); size_t min_capacity, size_t max_capacity, VirtualSpace* v);
~GenerationCounters() { ~GenerationCounters() {
if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC); if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);

View File

@ -214,9 +214,11 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs,
_max_eden_size = size - (2*_max_survivor_size); _max_eden_size = size - (2*_max_survivor_size);
// allocate the performance counters // allocate the performance counters
GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
// Generation counters -- generation 0, 3 subspaces // Generation counters -- generation 0, 3 subspaces
_gen_counters = new GenerationCounters("new", 0, 3, &_virtual_space); _gen_counters = new GenerationCounters("new", 0, 3,
gcp->min_young_size(), gcp->max_young_size(), &_virtual_space);
_gc_counters = new CollectorCounters(policy, 0); _gc_counters = new CollectorCounters(policy, 0);
_eden_counters = new CSpaceCounters("eden", 0, _max_eden_size, _eden_space, _eden_counters = new CSpaceCounters("eden", 0, _max_eden_size, _eden_space,

View File

@ -445,7 +445,7 @@ void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
// close and remove the file. See bug 6372906. // close and remove the file. See bug 6372906.
close(); close();
remove(_full_path); remove(_full_path);
fail_stop("Unable to write to shared archive file.", NULL); fail_stop("Unable to write to shared archive file.");
} }
} }
_file_offset += nbytes; _file_offset += nbytes;
@ -463,7 +463,7 @@ void FileMapInfo::align_file_position() {
// that the written file is the correct length. // that the written file is the correct length.
_file_offset -= 1; _file_offset -= 1;
if (lseek(_fd, _file_offset, SEEK_SET) < 0) { if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
fail_stop("Unable to seek.", NULL); fail_stop("Unable to seek.");
} }
char zero = 0; char zero = 0;
write_bytes(&zero, 1); write_bytes(&zero, 1);
@ -534,7 +534,7 @@ ReservedSpace FileMapInfo::reserve_shared_memory() {
// other reserved memory (like the code cache). // other reserved memory (like the code cache).
ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr); ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
if (!rs.is_reserved()) { if (!rs.is_reserved()) {
fail_continue(err_msg("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr)); fail_continue("Unable to reserve shared space at required address " INTPTR_FORMAT, requested_addr);
return rs; return rs;
} }
// the reserved virtual memory is for mapping class data sharing archive // the reserved virtual memory is for mapping class data sharing archive
@ -558,7 +558,7 @@ char* FileMapInfo::map_region(int i) {
requested_addr, size, si->_read_only, requested_addr, size, si->_read_only,
si->_allow_exec); si->_allow_exec);
if (base == NULL || base != si->_base) { if (base == NULL || base != si->_base) {
fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i])); fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
return NULL; return NULL;
} }
#ifdef _WINDOWS #ifdef _WINDOWS
@ -584,7 +584,7 @@ void FileMapInfo::unmap_region(int i) {
void FileMapInfo::assert_mark(bool check) { void FileMapInfo::assert_mark(bool check) {
if (!check) { if (!check) {
fail_stop("Mark mismatch while restoring from shared file.", NULL); fail_stop("Mark mismatch while restoring from shared file.");
} }
} }
@ -709,7 +709,7 @@ void FileMapInfo::print_shared_spaces() {
void FileMapInfo::stop_sharing_and_unmap(const char* msg) { void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
FileMapInfo *map_info = FileMapInfo::current_info(); FileMapInfo *map_info = FileMapInfo::current_info();
if (map_info) { if (map_info) {
map_info->fail_continue(msg); map_info->fail_continue("%s", msg);
for (int i = 0; i < MetaspaceShared::n_regions; i++) { for (int i = 0; i < MetaspaceShared::n_regions; i++) {
if (map_info->_header->_space[i]._base != NULL) { if (map_info->_header->_space[i]._base != NULL) {
map_info->unmap_region(i); map_info->unmap_region(i);
@ -717,6 +717,6 @@ void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
} }
} }
} else if (DumpSharedSpaces) { } else if (DumpSharedSpaces) {
fail_stop(msg, NULL); fail_stop("%s", msg);
} }
} }

View File

@ -190,8 +190,8 @@ public:
bool remap_shared_readonly_as_readwrite(); bool remap_shared_readonly_as_readwrite();
// Errors. // Errors.
static void fail_stop(const char *msg, ...); static void fail_stop(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
static void fail_continue(const char *msg, ...); static void fail_continue(const char *msg, ...) ATTRIBUTE_PRINTF(1, 2);
// Return true if given address is in the mapped shared space. // Return true if given address is in the mapped shared space.
bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false); bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false);

View File

@ -3126,6 +3126,8 @@ void Metaspace::global_initialize() {
if (DumpSharedSpaces) { if (DumpSharedSpaces) {
#if INCLUDE_CDS #if INCLUDE_CDS
MetaspaceShared::estimate_regions_size();
SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment); SharedReadOnlySize = align_size_up(SharedReadOnlySize, max_alignment);
SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment); SharedReadWriteSize = align_size_up(SharedReadWriteSize, max_alignment);
SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment); SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment);

View File

@ -816,6 +816,7 @@ int MetaspaceShared::preload_and_dump(const char * class_list_path,
//tty->print_cr("Preload failed: %s", class_name); //tty->print_cr("Preload failed: %s", class_name);
} }
} }
fclose(file);
} else { } else {
char errmsg[JVM_MAXPATHLEN]; char errmsg[JVM_MAXPATHLEN];
os::lasterror(errmsg, JVM_MAXPATHLEN); os::lasterror(errmsg, JVM_MAXPATHLEN);
@ -1086,3 +1087,49 @@ bool MetaspaceShared::remap_shared_readonly_as_readwrite() {
} }
return true; return true;
} }
int MetaspaceShared::count_class(const char* classlist_file) {
if (classlist_file == NULL) {
return 0;
}
char class_name[256];
int class_count = 0;
FILE* file = fopen(classlist_file, "r");
if (file != NULL) {
while ((fgets(class_name, sizeof class_name, file)) != NULL) {
if (*class_name == '#') { // comment
continue;
}
class_count++;
}
fclose(file);
} else {
char errmsg[JVM_MAXPATHLEN];
os::lasterror(errmsg, JVM_MAXPATHLEN);
tty->print_cr("Loading classlist failed: %s", errmsg);
exit(1);
}
return class_count;
}
// the sizes are good for typical large applications that have a lot of shared
// classes
void MetaspaceShared::estimate_regions_size() {
int class_count = count_class(SharedClassListFile);
class_count += count_class(ExtraSharedClassListFile);
if (class_count > LargeThresholdClassCount) {
if (class_count < HugeThresholdClassCount) {
SET_ESTIMATED_SIZE(Large, ReadOnly);
SET_ESTIMATED_SIZE(Large, ReadWrite);
SET_ESTIMATED_SIZE(Large, MiscData);
SET_ESTIMATED_SIZE(Large, MiscCode);
} else {
SET_ESTIMATED_SIZE(Huge, ReadOnly);
SET_ESTIMATED_SIZE(Huge, ReadWrite);
SET_ESTIMATED_SIZE(Huge, MiscData);
SET_ESTIMATED_SIZE(Huge, MiscCode);
}
}
}

View File

@ -30,6 +30,19 @@
#include "utilities/exceptions.hpp" #include "utilities/exceptions.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#define LargeSharedArchiveSize (300*M)
#define HugeSharedArchiveSize (800*M)
#define ReadOnlyRegionPercentage 0.4
#define ReadWriteRegionPercentage 0.55
#define MiscDataRegionPercentage 0.03
#define MiscCodeRegionPercentage 0.02
#define LargeThresholdClassCount 5000
#define HugeThresholdClassCount 40000
#define SET_ESTIMATED_SIZE(type, region) \
Shared ##region## Size = FLAG_IS_DEFAULT(Shared ##region## Size) ? \
(type ## SharedArchiveSize * region ## RegionPercentage) : Shared ## region ## Size
class FileMapInfo; class FileMapInfo;
// Class Data Sharing Support // Class Data Sharing Support
@ -112,5 +125,8 @@ class MetaspaceShared : AllStatic {
static void link_one_shared_class(Klass* obj, TRAPS); static void link_one_shared_class(Klass* obj, TRAPS);
static void check_one_shared_class(Klass* obj); static void check_one_shared_class(Klass* obj);
static void link_and_cleanup_shared_classes(TRAPS); static void link_and_cleanup_shared_classes(TRAPS);
static int count_class(const char* classlist_file);
static void estimate_regions_size() NOT_CDS_RETURN;
}; };
#endif // SHARE_VM_MEMORY_METASPACE_SHARED_HPP #endif // SHARE_VM_MEMORY_METASPACE_SHARED_HPP

View File

@ -53,9 +53,11 @@ TenuredGeneration::TenuredGeneration(ReservedSpace rs,
// initialize performance counters // initialize performance counters
const char* gen_name = "old"; const char* gen_name = "old";
GenCollectorPolicy* gcp = (GenCollectorPolicy*) GenCollectedHeap::heap()->collector_policy();
// Generation Counters -- generation 1, 1 subspace // Generation Counters -- generation 1, 1 subspace
_gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space); _gen_counters = new GenerationCounters(gen_name, 1, 1,
gcp->min_old_size(), gcp->max_old_size(), &_virtual_space);
_gc_counters = new CollectorCounters("MSC", 1); _gc_counters = new CollectorCounters("MSC", 1);

View File

@ -68,7 +68,7 @@
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"

View File

@ -42,7 +42,7 @@
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"

View File

@ -38,7 +38,7 @@
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"
#include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"

View File

@ -51,7 +51,7 @@
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp" #include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp" #include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/g1/heapRegionManager.inline.hpp"
#include "gc_implementation/parNew/parOopClosures.inline.hpp" #include "gc_implementation/parNew/parOopClosures.inline.hpp"
#include "gc_implementation/parallelScavenge/psCompactionManager.hpp" #include "gc_implementation/parallelScavenge/psCompactionManager.hpp"
#include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp"

View File

@ -1708,8 +1708,8 @@ const TypeTuple *TypeTuple::LONG_CC_PAIR;
// Make a TypeTuple from the range of a method signature // Make a TypeTuple from the range of a method signature
const TypeTuple *TypeTuple::make_range(ciSignature* sig) { const TypeTuple *TypeTuple::make_range(ciSignature* sig) {
ciType* return_type = sig->return_type(); ciType* return_type = sig->return_type();
uint total_fields = TypeFunc::Parms + return_type->size(); uint arg_cnt = return_type->size();
const Type **field_array = fields(total_fields); const Type **field_array = fields(arg_cnt);
switch (return_type->basic_type()) { switch (return_type->basic_type()) {
case T_LONG: case T_LONG:
field_array[TypeFunc::Parms] = TypeLong::LONG; field_array[TypeFunc::Parms] = TypeLong::LONG;
@ -1734,26 +1734,26 @@ const TypeTuple *TypeTuple::make_range(ciSignature* sig) {
default: default:
ShouldNotReachHere(); ShouldNotReachHere();
} }
return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons(); return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
} }
// Make a TypeTuple from the domain of a method signature // Make a TypeTuple from the domain of a method signature
const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig) { const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig) {
uint total_fields = TypeFunc::Parms + sig->size(); uint arg_cnt = sig->size();
uint pos = TypeFunc::Parms; uint pos = TypeFunc::Parms;
const Type **field_array; const Type **field_array;
if (recv != NULL) { if (recv != NULL) {
total_fields++; arg_cnt++;
field_array = fields(total_fields); field_array = fields(arg_cnt);
// Use get_const_type here because it respects UseUniqueSubclasses: // Use get_const_type here because it respects UseUniqueSubclasses:
field_array[pos++] = get_const_type(recv)->join_speculative(TypePtr::NOTNULL); field_array[pos++] = get_const_type(recv)->join_speculative(TypePtr::NOTNULL);
} else { } else {
field_array = fields(total_fields); field_array = fields(arg_cnt);
} }
int i = 0; int i = 0;
while (pos < total_fields) { while (pos < TypeFunc::Parms + arg_cnt) {
ciType* type = sig->type_at(i); ciType* type = sig->type_at(i);
switch (type->basic_type()) { switch (type->basic_type()) {
@ -1780,7 +1780,8 @@ const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig)
} }
i++; i++;
} }
return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons();
return (TypeTuple*)(new TypeTuple(TypeFunc::Parms + arg_cnt, field_array))->hashcons();
} }
const TypeTuple *TypeTuple::make( uint cnt, const Type **fields ) { const TypeTuple *TypeTuple::make( uint cnt, const Type **fields ) {
@ -1789,6 +1790,7 @@ const TypeTuple *TypeTuple::make( uint cnt, const Type **fields ) {
//------------------------------fields----------------------------------------- //------------------------------fields-----------------------------------------
// Subroutine call type with space allocated for argument types // Subroutine call type with space allocated for argument types
// Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly
const Type **TypeTuple::fields( uint arg_cnt ) { const Type **TypeTuple::fields( uint arg_cnt ) {
const Type **flds = (const Type **)(Compile::current()->type_arena()->Amalloc_4((TypeFunc::Parms+arg_cnt)*sizeof(Type*) )); const Type **flds = (const Type **)(Compile::current()->type_arena()->Amalloc_4((TypeFunc::Parms+arg_cnt)*sizeof(Type*) ));
flds[TypeFunc::Control ] = Type::CONTROL; flds[TypeFunc::Control ] = Type::CONTROL;

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -635,6 +635,7 @@ public:
static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig); static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig);
// Subroutine call type with space allocated for argument types // Subroutine call type with space allocated for argument types
// Memory for Control, I_O, Memory, FramePtr, and ReturnAdr is allocated implicitly
static const Type **fields( uint arg_cnt ); static const Type **fields( uint arg_cnt );
virtual const Type *xmeet( const Type *t ) const; virtual const Type *xmeet( const Type *t ) const;

View File

@ -430,6 +430,8 @@ extern "C" {
} }
} }
jint volatile vm_getting_terminated = 0;
// Note: before_exit() can be executed only once, if more than one threads // Note: before_exit() can be executed only once, if more than one threads
// are trying to shutdown the VM at the same time, only one thread // are trying to shutdown the VM at the same time, only one thread
// can run before_exit() and all other threads must wait. // can run before_exit() and all other threads must wait.
@ -460,6 +462,8 @@ void before_exit(JavaThread * thread) {
} }
} }
OrderAccess::release_store(&vm_getting_terminated, 1);
// The only difference between this and Win32's _onexit procs is that // The only difference between this and Win32's _onexit procs is that
// this version is invoked before any threads get killed. // this version is invoked before any threads get killed.
ExitProc* current = exit_procs; ExitProc* current = exit_procs;

View File

@ -171,8 +171,9 @@ class MallocMemorySnapshot : public ResourceObj {
// Total malloc'd memory used by arenas // Total malloc'd memory used by arenas
size_t total_arena() const; size_t total_arena() const;
inline size_t thread_count() { inline size_t thread_count() const {
return by_type(mtThreadStack)->malloc_count(); MallocMemorySnapshot* s = const_cast<MallocMemorySnapshot*>(this);
return s->by_type(mtThreadStack)->malloc_count();
} }
void reset(); void reset();

View File

@ -70,15 +70,13 @@ int compare_virtual_memory_site(const VirtualMemoryAllocationSite& s1,
*/ */
class MallocAllocationSiteWalker : public MallocSiteWalker { class MallocAllocationSiteWalker : public MallocSiteWalker {
private: private:
SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> SortedLinkedList<MallocSite, compare_malloc_size> _malloc_sites;
_malloc_sites;
size_t _count; size_t _count;
// Entries in MallocSiteTable with size = 0 and count = 0, // Entries in MallocSiteTable with size = 0 and count = 0,
// when the malloc site is not longer there. // when the malloc site is not longer there.
public: public:
MallocAllocationSiteWalker(Arena* arena) : _count(0), _malloc_sites(arena) { MallocAllocationSiteWalker() : _count(0) { }
}
inline size_t count() const { return _count; } inline size_t count() const { return _count; }
@ -109,13 +107,12 @@ int compare_virtual_memory_base(const ReservedMemoryRegion& r1, const ReservedMe
// Walk all virtual memory regions for baselining // Walk all virtual memory regions for baselining
class VirtualMemoryAllocationWalker : public VirtualMemoryWalker { class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
private: private:
SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base, ResourceObj::ARENA> SortedLinkedList<ReservedMemoryRegion, compare_virtual_memory_base>
_virtual_memory_regions; _virtual_memory_regions;
size_t _count; size_t _count;
public: public:
VirtualMemoryAllocationWalker(Arena* a) : _count(0), _virtual_memory_regions(a) { VirtualMemoryAllocationWalker() : _count(0) { }
}
bool do_allocation_site(const ReservedMemoryRegion* rgn) { bool do_allocation_site(const ReservedMemoryRegion* rgn) {
if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) { if (rgn->size() >= MemBaseline::SIZE_THRESHOLD) {
@ -136,39 +133,30 @@ class VirtualMemoryAllocationWalker : public VirtualMemoryWalker {
bool MemBaseline::baseline_summary() { bool MemBaseline::baseline_summary() {
assert(_malloc_memory_snapshot == NULL, "Malloc baseline not yet reset"); MallocMemorySummary::snapshot(&_malloc_memory_snapshot);
assert(_virtual_memory_snapshot == NULL, "Virtual baseline not yet reset"); VirtualMemorySummary::snapshot(&_virtual_memory_snapshot);
_malloc_memory_snapshot = new (arena()) MallocMemorySnapshot();
_virtual_memory_snapshot = new (arena()) VirtualMemorySnapshot();
if (_malloc_memory_snapshot == NULL || _virtual_memory_snapshot == NULL) {
return false;
}
MallocMemorySummary::snapshot(_malloc_memory_snapshot);
VirtualMemorySummary::snapshot(_virtual_memory_snapshot);
return true; return true;
} }
bool MemBaseline::baseline_allocation_sites() { bool MemBaseline::baseline_allocation_sites() {
assert(arena() != NULL, "Just check");
// Malloc allocation sites // Malloc allocation sites
MallocAllocationSiteWalker malloc_walker(arena()); MallocAllocationSiteWalker malloc_walker;
if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) { if (!MallocSiteTable::walk_malloc_site(&malloc_walker)) {
return false; return false;
} }
_malloc_sites.set_head(malloc_walker.malloc_sites()->head()); _malloc_sites.move(malloc_walker.malloc_sites());
// The malloc sites are collected in size order // The malloc sites are collected in size order
_malloc_sites_order = by_size; _malloc_sites_order = by_size;
// Virtual memory allocation sites // Virtual memory allocation sites
VirtualMemoryAllocationWalker virtual_memory_walker(arena()); VirtualMemoryAllocationWalker virtual_memory_walker;
if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) { if (!VirtualMemoryTracker::walk_virtual_memory(&virtual_memory_walker)) {
return false; return false;
} }
// Virtual memory allocations are collected in call stack order // Virtual memory allocations are collected in call stack order
_virtual_memory_allocations.set_head(virtual_memory_walker.virtual_memory_allocations()->head()); _virtual_memory_allocations.move(virtual_memory_walker.virtual_memory_allocations());
if (!aggregate_virtual_memory_allocation_sites()) { if (!aggregate_virtual_memory_allocation_sites()) {
return false; return false;
@ -180,11 +168,6 @@ bool MemBaseline::baseline_allocation_sites() {
} }
bool MemBaseline::baseline(bool summaryOnly) { bool MemBaseline::baseline(bool summaryOnly) {
if (arena() == NULL) {
_arena = new (std::nothrow, mtNMT) Arena(mtNMT);
if (arena() == NULL) return false;
}
reset(); reset();
_class_count = InstanceKlass::number_of_instance_classes(); _class_count = InstanceKlass::number_of_instance_classes();
@ -211,8 +194,7 @@ int compare_allocation_site(const VirtualMemoryAllocationSite& s1,
} }
bool MemBaseline::aggregate_virtual_memory_allocation_sites() { bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site, ResourceObj::ARENA> SortedLinkedList<VirtualMemoryAllocationSite, compare_allocation_site> allocation_sites;
allocation_sites(arena());
VirtualMemoryAllocationIterator itr = virtual_memory_allocations(); VirtualMemoryAllocationIterator itr = virtual_memory_allocations();
const ReservedMemoryRegion* rgn; const ReservedMemoryRegion* rgn;
@ -230,12 +212,12 @@ bool MemBaseline::aggregate_virtual_memory_allocation_sites() {
site->commit_memory(rgn->committed_size()); site->commit_memory(rgn->committed_size());
} }
_virtual_memory_sites.set_head(allocation_sites.head()); _virtual_memory_sites.move(&allocation_sites);
return true; return true;
} }
MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) { MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
assert(!_malloc_sites.is_empty(), "Detail baseline?"); assert(!_malloc_sites.is_empty(), "Not detail baseline");
switch(order) { switch(order) {
case by_size: case by_size:
malloc_sites_to_size_order(); malloc_sites_to_size_order();
@ -251,7 +233,7 @@ MallocSiteIterator MemBaseline::malloc_sites(SortingOrder order) {
} }
VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) { VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order) {
assert(!_virtual_memory_sites.is_empty(), "Detail baseline?"); assert(!_virtual_memory_sites.is_empty(), "Not detail baseline");
switch(order) { switch(order) {
case by_size: case by_size:
virtual_memory_sites_to_size_order(); virtual_memory_sites_to_size_order();
@ -270,8 +252,7 @@ VirtualMemorySiteIterator MemBaseline::virtual_memory_sites(SortingOrder order)
// Sorting allocations sites in different orders // Sorting allocations sites in different orders
void MemBaseline::malloc_sites_to_size_order() { void MemBaseline::malloc_sites_to_size_order() {
if (_malloc_sites_order != by_size) { if (_malloc_sites_order != by_size) {
SortedLinkedList<MallocSite, compare_malloc_size, ResourceObj::ARENA> SortedLinkedList<MallocSite, compare_malloc_size> tmp;
tmp(arena());
// Add malloc sites to sorted linked list to sort into size order // Add malloc sites to sorted linked list to sort into size order
tmp.move(&_malloc_sites); tmp.move(&_malloc_sites);
@ -283,8 +264,7 @@ void MemBaseline::malloc_sites_to_size_order() {
void MemBaseline::malloc_sites_to_allocation_site_order() { void MemBaseline::malloc_sites_to_allocation_site_order() {
if (_malloc_sites_order != by_site) { if (_malloc_sites_order != by_site) {
SortedLinkedList<MallocSite, compare_malloc_site, ResourceObj::ARENA> SortedLinkedList<MallocSite, compare_malloc_site> tmp;
tmp(arena());
// Add malloc sites to sorted linked list to sort into site (address) order // Add malloc sites to sorted linked list to sort into site (address) order
tmp.move(&_malloc_sites); tmp.move(&_malloc_sites);
_malloc_sites.set_head(tmp.head()); _malloc_sites.set_head(tmp.head());
@ -295,8 +275,7 @@ void MemBaseline::malloc_sites_to_allocation_site_order() {
void MemBaseline::virtual_memory_sites_to_size_order() { void MemBaseline::virtual_memory_sites_to_size_order() {
if (_virtual_memory_sites_order != by_size) { if (_virtual_memory_sites_order != by_size) {
SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size, ResourceObj::ARENA> SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_size> tmp;
tmp(arena());
tmp.move(&_virtual_memory_sites); tmp.move(&_virtual_memory_sites);
@ -308,10 +287,9 @@ void MemBaseline::virtual_memory_sites_to_size_order() {
void MemBaseline::virtual_memory_sites_to_reservation_site_order() { void MemBaseline::virtual_memory_sites_to_reservation_site_order() {
if (_virtual_memory_sites_order != by_size) { if (_virtual_memory_sites_order != by_size) {
SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site, ResourceObj::ARENA> SortedLinkedList<VirtualMemoryAllocationSite, compare_virtual_memory_site> tmp;
tmp(arena());
tmp.add(&_virtual_memory_sites); tmp.move(&_virtual_memory_sites);
_virtual_memory_sites.set_head(tmp.head()); _virtual_memory_sites.set_head(tmp.head());
tmp.set_head(NULL); tmp.set_head(NULL);

View File

@ -61,28 +61,22 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
}; };
private: private:
// All baseline data is stored in this arena
Arena* _arena;
// Summary information // Summary information
MallocMemorySnapshot* _malloc_memory_snapshot; MallocMemorySnapshot _malloc_memory_snapshot;
VirtualMemorySnapshot* _virtual_memory_snapshot; VirtualMemorySnapshot _virtual_memory_snapshot;
size_t _class_count; size_t _class_count;
// Allocation sites information // Allocation sites information
// Malloc allocation sites // Malloc allocation sites
LinkedListImpl<MallocSite, ResourceObj::ARENA> LinkedListImpl<MallocSite> _malloc_sites;
_malloc_sites;
// All virtual memory allocations // All virtual memory allocations
LinkedListImpl<ReservedMemoryRegion, ResourceObj::ARENA> LinkedListImpl<ReservedMemoryRegion> _virtual_memory_allocations;
_virtual_memory_allocations;
// Virtual memory allocations by allocation sites, always in by_address // Virtual memory allocations by allocation sites, always in by_address
// order // order
LinkedListImpl<VirtualMemoryAllocationSite, ResourceObj::ARENA> LinkedListImpl<VirtualMemoryAllocationSite> _virtual_memory_sites;
_virtual_memory_sites;
SortingOrder _malloc_sites_order; SortingOrder _malloc_sites_order;
SortingOrder _virtual_memory_sites_order; SortingOrder _virtual_memory_sites_order;
@ -93,30 +87,23 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
// create a memory baseline // create a memory baseline
MemBaseline(): MemBaseline():
_baseline_type(Not_baselined), _baseline_type(Not_baselined),
_class_count(0), _class_count(0) {
_arena(NULL),
_malloc_memory_snapshot(NULL),
_virtual_memory_snapshot(NULL),
_malloc_sites(NULL) {
} }
~MemBaseline() { ~MemBaseline() {
reset(); reset();
if (_arena != NULL) {
delete _arena;
}
} }
bool baseline(bool summaryOnly = true); bool baseline(bool summaryOnly = true);
BaselineType baseline_type() const { return _baseline_type; } BaselineType baseline_type() const { return _baseline_type; }
MallocMemorySnapshot* malloc_memory_snapshot() const { MallocMemorySnapshot* malloc_memory_snapshot() {
return _malloc_memory_snapshot; return &_malloc_memory_snapshot;
} }
VirtualMemorySnapshot* virtual_memory_snapshot() const { VirtualMemorySnapshot* virtual_memory_snapshot() {
return _virtual_memory_snapshot; return &_virtual_memory_snapshot;
} }
MallocSiteIterator malloc_sites(SortingOrder order); MallocSiteIterator malloc_sites(SortingOrder order);
@ -133,10 +120,8 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
// memory // memory
size_t total_reserved_memory() const { size_t total_reserved_memory() const {
assert(baseline_type() != Not_baselined, "Not yet baselined"); assert(baseline_type() != Not_baselined, "Not yet baselined");
assert(_virtual_memory_snapshot != NULL, "No virtual memory snapshot"); size_t amount = _malloc_memory_snapshot.total() +
assert(_malloc_memory_snapshot != NULL, "No malloc memory snapshot"); _virtual_memory_snapshot.total_reserved();
size_t amount = _malloc_memory_snapshot->total() +
_virtual_memory_snapshot->total_reserved();
return amount; return amount;
} }
@ -144,32 +129,30 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
// virtual memory // virtual memory
size_t total_committed_memory() const { size_t total_committed_memory() const {
assert(baseline_type() != Not_baselined, "Not yet baselined"); assert(baseline_type() != Not_baselined, "Not yet baselined");
assert(_virtual_memory_snapshot != NULL, size_t amount = _malloc_memory_snapshot.total() +
"Not a snapshot"); _virtual_memory_snapshot.total_committed();
size_t amount = _malloc_memory_snapshot->total() +
_virtual_memory_snapshot->total_committed();
return amount; return amount;
} }
size_t total_arena_memory() const { size_t total_arena_memory() const {
assert(baseline_type() != Not_baselined, "Not yet baselined"); assert(baseline_type() != Not_baselined, "Not yet baselined");
assert(_malloc_memory_snapshot != NULL, "Not yet baselined"); return _malloc_memory_snapshot.total_arena();
return _malloc_memory_snapshot->total_arena();
} }
size_t malloc_tracking_overhead() const { size_t malloc_tracking_overhead() const {
assert(baseline_type() != Not_baselined, "Not yet baselined"); assert(baseline_type() != Not_baselined, "Not yet baselined");
return _malloc_memory_snapshot->malloc_overhead()->size(); MemBaseline* bl = const_cast<MemBaseline*>(this);
return bl->_malloc_memory_snapshot.malloc_overhead()->size();
} }
const MallocMemory* malloc_memory(MEMFLAGS flag) const { MallocMemory* malloc_memory(MEMFLAGS flag) {
assert(_malloc_memory_snapshot != NULL, "Not a snapshot"); assert(baseline_type() != Not_baselined, "Not yet baselined");
return _malloc_memory_snapshot->by_type(flag); return _malloc_memory_snapshot.by_type(flag);
} }
const VirtualMemory* virtual_memory(MEMFLAGS flag) const { VirtualMemory* virtual_memory(MEMFLAGS flag) {
assert(_virtual_memory_snapshot != NULL, "Not a snapshot"); assert(baseline_type() != Not_baselined, "Not yet baselined");
return _virtual_memory_snapshot->by_type(flag); return _virtual_memory_snapshot.by_type(flag);
} }
@ -180,24 +163,19 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
size_t thread_count() const { size_t thread_count() const {
assert(baseline_type() != Not_baselined, "Not yet baselined"); assert(baseline_type() != Not_baselined, "Not yet baselined");
assert(_malloc_memory_snapshot != NULL, "Baselined?"); return _malloc_memory_snapshot.thread_count();
return _malloc_memory_snapshot->thread_count();
} }
// reset the baseline for reuse // reset the baseline for reuse
void reset() { void reset() {
_baseline_type = Not_baselined; _baseline_type = Not_baselined;
_malloc_memory_snapshot = NULL; _malloc_memory_snapshot.reset();
_virtual_memory_snapshot = NULL; _virtual_memory_snapshot.reset();
_class_count = 0; _class_count = 0;
_malloc_sites = NULL; _malloc_sites.clear();
_virtual_memory_sites = NULL; _virtual_memory_sites.clear();
_virtual_memory_allocations = NULL; _virtual_memory_allocations.clear();
if (_arena != NULL) {
_arena->destruct_contents();
}
} }
private: private:
@ -210,8 +188,6 @@ class MemBaseline VALUE_OBJ_CLASS_SPEC {
// Aggregate virtual memory allocation by allocation sites // Aggregate virtual memory allocation by allocation sites
bool aggregate_virtual_memory_allocation_sites(); bool aggregate_virtual_memory_allocation_sites();
Arena* arena() { return _arena; }
// Sorting allocation sites in different orders // Sorting allocation sites in different orders
// Sort allocation sites in size order // Sort allocation sites in size order
void malloc_sites_to_size_order(); void malloc_sites_to_size_order();

View File

@ -35,7 +35,9 @@ import java.net.URLConnection;
* @summary "Tests unloading of anonymous classes." * @summary "Tests unloading of anonymous classes."
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @compile TestAnonymousClassUnloading.java * @compile TestAnonymousClassUnloading.java
* @run main ClassFileInstaller TestAnonymousClassUnloading sun.hotspot.WhiteBox * @run main ClassFileInstaller TestAnonymousClassUnloading
* sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestAnonymousClassUnloading * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestAnonymousClassUnloading
*/ */
public class TestAnonymousClassUnloading { public class TestAnonymousClassUnloading {

View File

@ -36,7 +36,7 @@ import java.net.URLClassLoader;
* @build WorkerClass * @build WorkerClass
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission * sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:+UseParallelGC -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation -XX:-UseCompressedOops -XX:CompileOnly=TestMethodUnloading::doWork TestMethodUnloading
*/ */
public class TestMethodUnloading { public class TestMethodUnloading {
private static final String workerClassName = "WorkerClass"; private static final String workerClassName = "WorkerClass";

View File

@ -54,16 +54,19 @@ public class TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking"); "-XX:+UseRTMLocking");
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, CommandLineOptionTest.verifyOptionValueForSameVM(optionName,
TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE,
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking", prepareOptionValue("true")); "-XX:-UseRTMLocking", prepareOptionValue("true"));
// verify that option could be turned on // verify that option could be turned on
CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true",
CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", prepareOptionValue("true")); "-XX:+UseRTMLocking", prepareOptionValue("true"));
} }

View File

@ -63,13 +63,16 @@ public class TestUseRTMDeoptOptionOnSupportedConfig
// verify default value // verify default value
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt",
TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE, TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking"); "-XX:+UseRTMLocking");
// verify that option is off when UseRTMLocking is off // verify that option is off when UseRTMLocking is off
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "false",
"false", "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt"); CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking", "-XX:+UseRTMDeopt");
// verify that option could be turned on // verify that option could be turned on
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "true",
"true", "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt"); CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:+UseRTMDeopt");
} }
public static void main(String args[]) throws Throwable { public static void main(String args[]) throws Throwable {

View File

@ -59,24 +59,31 @@ public class TestUseRTMLockingOptionOnSupportedConfig
new String[]{ new String[]{
RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
unrecongnizedOption unrecongnizedOption
}, ExitCode.OK, "-XX:+UseRTMLocking" }, ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking"
); );
CommandLineOptionTest.verifySameJVMStartup(null, CommandLineOptionTest.verifySameJVMStartup(null,
new String[]{ new String[]{
RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR,
unrecongnizedOption unrecongnizedOption
}, ExitCode.OK, "-XX:-UseRTMLocking" }, ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking"
); );
// verify that UseRTMLocking is of by default // verify that UseRTMLocking is of by default
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE); TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS);
// verify that we can change UseRTMLocking value // verify that we can change UseRTMLocking value
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE, TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:-UseRTMLocking"); "-XX:-UseRTMLocking");
CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking",
"true", "-XX:+UseRTMLocking"); "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
} }
public static void main(String args[]) throws Throwable { public static void main(String args[]) throws Throwable {

View File

@ -54,18 +54,22 @@ public class TestUseRTMLockingOptionWithBiasedLocking
// verify that we will not get a warning // verify that we will not get a warning
CommandLineOptionTest.verifySameJVMStartup(null, CommandLineOptionTest.verifySameJVMStartup(null,
new String[] { warningMessage }, ExitCode.OK, new String[] { warningMessage }, ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:-UseBiasedLocking"); "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking");
// verify that we will get a warning // verify that we will get a warning
CommandLineOptionTest.verifySameJVMStartup( CommandLineOptionTest.verifySameJVMStartup(
new String[] { warningMessage }, null, ExitCode.OK, new String[] { warningMessage }, null, ExitCode.OK,
CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
// verify that UseBiasedLocking is false when we use rtm locking // verify that UseBiasedLocking is false when we use rtm locking
CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
"false", "-XX:+UseRTMLocking"); "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking");
// verify that we can't turn on biased locking when // verify that we can't turn on biased locking when
// using rtm locking // using rtm locking
CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking",
"false", "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS,
"-XX:+UseRTMLocking", "-XX:+UseBiasedLocking");
} }
public static void main(String args[]) throws Throwable { public static void main(String args[]) throws Throwable {

View File

@ -22,9 +22,8 @@
*/ */
/** /**
* @ignore 8041506, 8041946, 8042051
* @test TestHumongousShrinkHeap * @test TestHumongousShrinkHeap
* @bug 8036025 * @bug 8036025 8056043
* @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects * @summary Verify that heap shrinks after GC in the presence of fragmentation due to humongous objects
* @library /testlibrary * @library /testlibrary
* @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap * @run main/othervm -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=50 -XX:+UseG1GC -XX:G1HeapRegionSize=1M -verbose:gc TestHumongousShrinkHeap

View File

@ -129,8 +129,19 @@ class TestStringDeduplicationTools {
return list; return list;
} }
/**
* Verifies that the given list contains expected number of unique strings.
* It's possible that deduplication hasn't completed yet, so the method
* will perform several attempts to check with a little pause between.
* The method throws RuntimeException to signal that verification failed.
*
* @param list strings to check
* @param uniqueExpected expected number of unique strings
* @throws RuntimeException if check fails
*/
private static void verifyStrings(ArrayList<String> list, int uniqueExpected) { private static void verifyStrings(ArrayList<String> list, int uniqueExpected) {
for (;;) { boolean passed = false;
for (int attempts = 0; attempts < 10; attempts++) {
// Check number of deduplicated strings // Check number of deduplicated strings
ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected); ArrayList<Object> unique = new ArrayList<Object>(uniqueExpected);
for (String string: list) { for (String string: list) {
@ -153,11 +164,11 @@ class TestStringDeduplicationTools {
", uniqueExpected=" + uniqueExpected); ", uniqueExpected=" + uniqueExpected);
if (unique.size() == uniqueExpected) { if (unique.size() == uniqueExpected) {
System.out.println("Deduplication completed"); System.out.println("Deduplication completed (as fast as " + attempts + " iterations)");
passed = true;
break; break;
} else { } else {
System.out.println("Deduplication not completed, waiting..."); System.out.println("Deduplication not completed, waiting...");
// Give the deduplication thread time to complete // Give the deduplication thread time to complete
try { try {
Thread.sleep(1000); Thread.sleep(1000);
@ -166,6 +177,9 @@ class TestStringDeduplicationTools {
} }
} }
} }
if (!passed) {
throw new RuntimeException("String verification failed");
}
} }
private static OutputAnalyzer runTest(String... extraArgs) throws Exception { private static OutputAnalyzer runTest(String... extraArgs) throws Exception {
@ -247,14 +261,20 @@ class TestStringDeduplicationTools {
forceDeduplication(ageThreshold, FullGC); forceDeduplication(ageThreshold, FullGC);
// Wait for deduplication to occur // Wait for deduplication to occur
while (getValue(dupString1) != getValue(baseString)) { for (int attempts = 0; attempts < 10; attempts++) {
if (getValue(dupString1) == getValue(baseString)) {
break;
}
System.out.println("Waiting..."); System.out.println("Waiting...");
try { try {
Thread.sleep(100); Thread.sleep(1000);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
if (getValue(dupString1) != getValue(baseString)) {
throw new RuntimeException("Deduplication has not occurred");
}
// Create a new duplicate of baseString // Create a new duplicate of baseString
StringBuilder sb2 = new StringBuilder(baseString); StringBuilder sb2 = new StringBuilder(baseString);

View File

@ -0,0 +1,69 @@
/*
* 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 TestWBGC
* @bug 8055098
* @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly.
* @library /testlibrary /testlibrary/whitebox
* @build TestWBGC
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run driver TestWBGC
*/
import com.oracle.java.testlibrary.*;
import sun.hotspot.WhiteBox;
public class TestWBGC {
public static void main(String args[]) throws Exception {
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
true,
"-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions",
"-XX:+WhiteBoxAPI",
"-XX:MaxTenuringThreshold=1",
"-XX:+PrintGC",
GCYoungTest.class.getName());
OutputAnalyzer output = new OutputAnalyzer(pb.start());
System.out.println(output.getStdout());
output.shouldHaveExitValue(0);
output.shouldContain("WhiteBox Initiated Young GC");
output.shouldNotContain("Full");
// To be sure that we don't provoke Full GC additionaly to young
}
public static class GCYoungTest {
static WhiteBox wb = WhiteBox.getWhiteBox();
public static Object obj;
public static void main(String args[]) {
obj = new Object();
Asserts.assertFalse(wb.isObjectInOldGen(obj));
wb.youngGC();
wb.youngGC();
// 2 young GC is needed to promote object into OldGen
Asserts.assertTrue(wb.isObjectInOldGen(obj));
}
}
}

View File

@ -26,7 +26,6 @@
* @bug 8024927 * @bug 8024927
* @summary Testing address of compressed class pointer space as best as possible. * @summary Testing address of compressed class pointer space as best as possible.
* @library /testlibrary * @library /testlibrary
* @ignore 8055164
*/ */
import com.oracle.java.testlibrary.*; import com.oracle.java.testlibrary.*;
@ -89,7 +88,6 @@ public class CompressedClassPointers {
"-version"); "-version");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
output.shouldContain("HeapBaseMinAddress must be at least"); output.shouldContain("HeapBaseMinAddress must be at least");
output.shouldContain("HotSpot");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
} }

View File

@ -26,7 +26,6 @@
* @key nmt * @key nmt
* @summary Empty argument to NMT should result in an informative error message * @summary Empty argument to NMT should result in an informative error message
* @library /testlibrary * @library /testlibrary
* @ignore 8055051
*/ */
import com.oracle.java.testlibrary.*; import com.oracle.java.testlibrary.*;

View File

@ -62,21 +62,18 @@ public class JcmdDetailDiff {
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)"); output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
output.shouldContain("WB_NMTReserveMemory");
wb.NMTCommitMemory(addr, commitSize); wb.NMTCommitMemory(addr, commitSize);
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"}); pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB +256KB, committed=128KB +128KB)"); output.shouldContain("Test (reserved=256KB +256KB, committed=128KB +128KB)");
output.shouldContain("WB_NMTReserveMemory");
wb.NMTUncommitMemory(addr, commitSize); wb.NMTUncommitMemory(addr, commitSize);
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"}); pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)"); output.shouldContain("Test (reserved=256KB +256KB, committed=0KB)");
output.shouldContain("WB_NMTReserveMemory");
wb.NMTReleaseMemory(addr, reserveSize); wb.NMTReleaseMemory(addr, reserveSize);
pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"}); pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "detail.diff", "scale=KB"});

View File

@ -22,10 +22,9 @@
*/ */
/* /*
* @key stress
* @test * @test
* @summary Test corner case that overflows malloc site hashtable bucket * @summary Test corner case that overflows malloc site hashtable bucket
* @key nmt jcmd * @key nmt jcmd stress
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @ignore - This test is disabled since it will stress NMT and timeout during normal testing * @ignore - This test is disabled since it will stress NMT and timeout during normal testing
* @build MallocSiteHashOverflow * @build MallocSiteHashOverflow

View File

@ -22,10 +22,9 @@
*/ */
/* /*
* @key stress
* @test * @test
* @summary Stress test for malloc tracking * @summary Stress test for malloc tracking
* @key nmt jcmd * @key nmt jcmd stress
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build MallocStressTest * @build MallocStressTest
* @ignore - This test is disabled since it will stress NMT and timeout during normal testing * @ignore - This test is disabled since it will stress NMT and timeout during normal testing

View File

@ -34,14 +34,15 @@ public class NMTWithCDS {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ProcessBuilder pb; ProcessBuilder pb;
pb = ProcessTools.createJavaProcessBuilder("-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); pb = ProcessTools.createJavaProcessBuilder(
"-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump");
OutputAnalyzer output = new OutputAnalyzer(pb.start()); OutputAnalyzer output = new OutputAnalyzer(pb.start());
try { try {
output.shouldContain("Loading classes to share"); output.shouldContain("Loading classes to share");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);
pb = ProcessTools.createJavaProcessBuilder( pb = ProcessTools.createJavaProcessBuilder(
"-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version"); "-XX:+UnlockDiagnosticVMOptions", "-XX:NativeMemoryTracking=detail", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:on", "-version");
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("sharing"); output.shouldContain("sharing");
output.shouldHaveExitValue(0); output.shouldHaveExitValue(0);

View File

@ -26,7 +26,6 @@
* @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly * @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly
* @key nmt jcmd * @key nmt jcmd
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @ignore
* @build VirtualAllocCommitUncommitRecommit * @build VirtualAllocCommitUncommitRecommit
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitUncommitRecommit * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitUncommitRecommit
@ -43,8 +42,8 @@ public class VirtualAllocCommitUncommitRecommit {
public static void main(String args[]) throws Exception { public static void main(String args[]) throws Exception {
OutputAnalyzer output; OutputAnalyzer output;
long commitSize = 4 * 1024; // 4KB long commitSize = 128 * 1024; // 128KB
long reserveSize = 1024 * 1024; // 1024KB long reserveSize = 4 * 1024 * 1024; // 4096KB
long addr; long addr;
String pid = Integer.toString(ProcessTools.getProcessId()); String pid = Integer.toString(ProcessTools.getProcessId());
@ -63,11 +62,11 @@ public class VirtualAllocCommitUncommitRecommit {
"VM.native_memory", "detail" }); "VM.native_memory", "detail" });
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=0KB)"); output.shouldContain("Test (reserved=4096KB, committed=0KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
long addrA = addr; long addrA = addr;
@ -84,24 +83,24 @@ public class VirtualAllocCommitUncommitRecommit {
wb.NMTCommitMemory(addrD, commitSize); wb.NMTCommitMemory(addrD, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=16KB)"); output.shouldContain("Test (reserved=4096KB, committed=512KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// uncommit BC // uncommit BC
wb.NMTUncommitMemory(addrB, commitSize); wb.NMTUncommitMemory(addrB, commitSize);
wb.NMTUncommitMemory(addrC, commitSize); wb.NMTUncommitMemory(addrC, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=8KB)"); output.shouldContain("Test (reserved=4096KB, committed=256KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// commit EF // commit EF
@ -109,22 +108,22 @@ public class VirtualAllocCommitUncommitRecommit {
wb.NMTCommitMemory(addrF, commitSize); wb.NMTCommitMemory(addrF, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=16KB)"); output.shouldContain("Test (reserved=4096KB, committed=512KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// uncommit A // uncommit A
wb.NMTUncommitMemory(addrA, commitSize); wb.NMTUncommitMemory(addrA, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=12KB)"); output.shouldContain("Test (reserved=4096KB, committed=384KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// commit ABC // commit ABC
@ -133,11 +132,11 @@ public class VirtualAllocCommitUncommitRecommit {
wb.NMTCommitMemory(addrC, commitSize); wb.NMTCommitMemory(addrC, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=24KB)"); output.shouldContain("Test (reserved=4096KB, committed=768KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// uncommit ABCDEF // uncommit ABCDEF
@ -149,11 +148,11 @@ public class VirtualAllocCommitUncommitRecommit {
wb.NMTUncommitMemory(addrF, commitSize); wb.NMTUncommitMemory(addrF, commitSize);
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldContain("Test (reserved=1024KB, committed=0KB)"); output.shouldContain("Test (reserved=4096KB, committed=0KB)");
if (has_nmt_detail) { if (has_nmt_detail) {
output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + Long.toHexString(addr + reserveSize)
+ "\\] reserved 1024KB for Test"); + "\\] reserved 4096KB for Test");
} }
// release // release
@ -161,6 +160,6 @@ public class VirtualAllocCommitUncommitRecommit {
output = new OutputAnalyzer(pb.start()); output = new OutputAnalyzer(pb.start());
output.shouldNotContain("Test (reserved="); output.shouldNotContain("Test (reserved=");
output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*" output.shouldNotMatch("\\[0x[0]*" + Long.toHexString(addr) + " - 0x[0]*"
+ Long.toHexString(addr + reserveSize) + "\\] reserved"); + Long.toHexString(addr + reserveSize) + "\\] reserved 4096KB for Test");
} }
} }

View File

@ -31,15 +31,14 @@
## @bug 8022301 ## @bug 8022301
## @bug 8025519 ## @bug 8025519
## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX ## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
## @ignore 8041727
## @run shell/timeout=60 Test8017498.sh ## @run shell/timeout=60 Test8017498.sh
## ##
if [ "${TESTSRC}" = "" ] if [ -z "${TESTSRC}" ]; then
then TESTSRC="${PWD}"
TESTSRC=${PWD}
echo "TESTSRC not set. Using "${TESTSRC}" as default" echo "TESTSRC not set. Using "${TESTSRC}" as default"
fi fi
echo "TESTSRC=${TESTSRC}" echo "TESTSRC=${TESTSRC}"
## Adding common setup Variables for running shell tests. ## Adding common setup Variables for running shell tests.
. ${TESTSRC}/../../test_env.sh . ${TESTSRC}/../../test_env.sh
@ -52,13 +51,13 @@ case "$OS" in
Linux) Linux)
echo "Testing on Linux" echo "Testing on Linux"
gcc_cmd=`which gcc` gcc_cmd=`which gcc`
if [ "x$gcc_cmd" == "x" ]; then if [ -z "$gcc_cmd" ]; then
echo "WARNING: gcc not found. Cannot execute test." 2>&1 echo "WARNING: gcc not found. Cannot execute test." 2>&1
exit 0; exit 0;
fi fi
MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}${VM_CPU}${FS}libjsig.so MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}${VM_CPU}${FS}libjsig.so
if [ "$VM_BITS" == "32" ] && [ "$VM_CPU" != "arm" ] && [ "$VM_CPU" != "ppc" ]; then if [ "$VM_BITS" = "32" ] && [ "$VM_CPU" != "arm" ] && [ "$VM_CPU" != "ppc" ]; then
EXTRA_CFLAG=-m32 EXTRA_CFLAG=-m32
fi fi
echo MY_LD_PRELOAD = ${MY_LD_PRELOAD} echo MY_LD_PRELOAD = ${MY_LD_PRELOAD}
;; ;;
@ -70,7 +69,7 @@ esac
THIS_DIR=. THIS_DIR=.
cp ${TESTSRC}${FS}*.java ${THIS_DIR} cp "${TESTSRC}${FS}"*.java "${THIS_DIR}"
${COMPILEJAVA}${FS}bin${FS}javac *.java ${COMPILEJAVA}${FS}bin${FS}javac *.java
$gcc_cmd -DLINUX -fPIC -shared \ $gcc_cmd -DLINUX -fPIC -shared \
@ -80,16 +79,19 @@ $gcc_cmd -DLINUX -fPIC -shared \
-I${COMPILEJAVA}${FS}include${FS}linux \ -I${COMPILEJAVA}${FS}include${FS}linux \
${TESTSRC}${FS}TestJNI.c ${TESTSRC}${FS}TestJNI.c
if [ $? -ne 0 ] ; then
echo "Compile failed, Ignoring failed compilation and forcing the test to pass"
exit 0
fi
# run the java test in the background # run the java test in the background
cmd="LD_PRELOAD=$MY_LD_PRELOAD \ cmd="LD_PRELOAD=$MY_LD_PRELOAD \
${TESTJAVA}${FS}bin${FS}java \ ${TESTJAVA}${FS}bin${FS}java \
-Djava.library.path=. -server TestJNI 100" -Djava.library.path=. -server TestJNI 100"
echo "$cmd > test.out 2>&1" echo "$cmd > test.out"
eval $cmd > test.out 2>&1 eval $cmd > test.out
grep "old handler" test.out > ${NULL} if grep "old handler" test.out > ${NULL}; then
if [ $? = 0 ]
then
echo "Test Passed" echo "Test Passed"
exit 0 exit 0
fi fi

View File

@ -271,3 +271,4 @@ f9c82769a6bc2b219a8f01c24afe5c91039267d7 jdk9-b19
a5aea8318ae4a9c2105228568688875142d70344 jdk9-b26 a5aea8318ae4a9c2105228568688875142d70344 jdk9-b26
2bfaf29cc90b19948938e3ef1a0983eee68806c7 jdk9-b27 2bfaf29cc90b19948938e3ef1a0983eee68806c7 jdk9-b27
dc1e26434b3fd7e9b8eeab149103c1e30965f95c jdk9-b28 dc1e26434b3fd7e9b8eeab149103c1e30965f95c jdk9-b28
30adcd13a313ea91e81164801a2f89282756d933 jdk9-b29

View File

@ -271,3 +271,4 @@ a31efe49556a7c12f9ea2c9ee8b4fae8aa67723a jdk9-b25
dde9f5cfde5f46e62ceb5fab81151578e5277aef jdk9-b26 dde9f5cfde5f46e62ceb5fab81151578e5277aef jdk9-b26
f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27 f0870554049807d3392bd7976ab114f7f2b7bafa jdk9-b27
1828f73b35cfe35e460e41fd6e087ab1f83e0621 jdk9-b28 1828f73b35cfe35e460e41fd6e087ab1f83e0621 jdk9-b28
2da27e8e2c865e154f0c2eb9009f011a44649b11 jdk9-b29

View File

@ -76,13 +76,24 @@ LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in
iw ja ko lt lv mk ms mt nl no pl pt ro ru sk sl sq sr sv \ iw ja ko lt lv mk ms mt nl no pl pt ro ru sk sl sq sr sv \
th tr uk vi zh th tr uk vi zh
LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \ LOCALEDATA_INCLUDES := sun/util/resources/provider/NonEnLocaleDataMetaInfo.class
LOCALEDATA_INCLUDES += $(addprefix sun/text/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) \
$(addprefix sun/util/resources/, $(LOCALEDATA_INCLUDE_LOCALES)) $(addprefix sun/util/resources/, $(LOCALEDATA_INCLUDE_LOCALES))
$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, , \ LOCALEDATA_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/localemetainfo
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata, \
LOCALEDATA_METAINF_SERVICES := $(LOCALEDATA_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
$(LOCALEDATA_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/localedata-services/sun.util.locale.provider.LocaleDataMetaInfo
$(install-file)
$(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR, \
$(LOCALEDATA_METAINF_SERVICES), \
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
$(LOCALEDATA_SERVICES_DIR), \
SUFFIXES := .class _dict _th, \ SUFFIXES := .class _dict _th, \
INCLUDES := $(LOCALEDATA_INCLUDES), \ INCLUDES := $(LOCALEDATA_INCLUDES), \
EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
JAR := $(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar, \ JAR := $(IMAGES_OUTPUTDIR)/lib/ext/localedata.jar, \
SKIP_METAINF := true)) SKIP_METAINF := true))
@ -210,6 +221,8 @@ RT_JAR_EXCLUDES += \
sun/tools/tree \ sun/tools/tree \
sun/tools/util \ sun/tools/util \
sun/util/cldr/CLDRLocaleDataMetaInfo.class \ sun/util/cldr/CLDRLocaleDataMetaInfo.class \
sun/util/resources/provider/NonEnLocaleDataMetaInfo.class \
META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo \
sun/util/resources/cldr \ sun/util/resources/cldr \
$(LOCALEDATA_INCLUDES) \ $(LOCALEDATA_INCLUDES) \
com/oracle/jrockit/jfr \ com/oracle/jrockit/jfr \
@ -429,13 +442,23 @@ include gensrc/GensrcCLDR.gmk
CLDRDATA_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar CLDRDATA_JAR_DST := $(IMAGES_OUTPUTDIR)/lib/ext/cldrdata.jar
$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, , \ CLDR_SERVICES_DIR := $(IMAGES_OUTPUTDIR)/cldrmetainfo
CLDR_METAINF_SERVICES := $(CLDR_SERVICES_DIR)/META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo
$(CLDR_METAINF_SERVICES): $(JDK_TOPDIR)/src/jdk.localedata/META-INF/cldrdata-services/sun.util.locale.provider.LocaleDataMetaInfo
$(install-file)
$(eval $(call SetupArchive,BUILD_CLDRDATA_JAR, \
$(CLDR_METAINF_SERVICES), \
SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \ SRCS := $(JDK_OUTPUTDIR)/modules/jdk.localedata \
$(JDK_OUTPUTDIR)/modules/java.base, \ $(JDK_OUTPUTDIR)/modules/java.base \
$(CLDR_SERVICES_DIR), \
SUFFIXES := .class, \ SUFFIXES := .class, \
INCLUDES := sun/text/resources/cldr \ INCLUDES := sun/text/resources/cldr \
sun/util/cldr/CLDRLocaleDataMetaInfo.class \ sun/util/cldr/CLDRLocaleDataMetaInfo.class \
sun/util/resources/cldr, \ sun/util/resources/cldr, \
EXTRA_FILES := META-INF/services/sun.util.locale.provider.LocaleDataMetaInfo, \
JAR := $(CLDRDATA_JAR_DST), \ JAR := $(CLDRDATA_JAR_DST), \
EXTRA_MANIFEST_ATTR := CLDR-Version: $(CLDRVERSION), \ EXTRA_MANIFEST_ATTR := CLDR-Version: $(CLDRVERSION), \
SKIP_METAINF := true)) SKIP_METAINF := true))

View File

@ -43,25 +43,6 @@ $(INCLUDE_DST_OS_DIR)/%.h: \
################################################################################ ################################################################################
ICCPROFILE_DEST_DIR := $(LIB_DST_DIR)/cmm
ifdef OPENJDK
ICCPROFILE_SRC_DIR := $(JDK_TOPDIR)/src/java.desktop/share/conf/cmm/lcms
else
ICCPROFILE_SRC_DIR := $(JDK_TOPDIR)/src/closed/java.desktop/share/conf/cmm/kcms
endif
ICCPROFILE_SRCS := $(wildcard $(ICCPROFILE_SRC_DIR)/*.pf)
ICCPROFILE_TARGET_FILES := $(subst $(ICCPROFILE_SRC_DIR),$(ICCPROFILE_DEST_DIR),$(ICCPROFILE_SRCS))
$(ICCPROFILE_DEST_DIR)%.pf: $(ICCPROFILE_SRC_DIR)%.pf
$(call install-file)
$(CHMOD) 444 $@
DESKTOP_CONF_FILES += $(ICCPROFILE_TARGET_FILES)
################################################################################
ifneq ($(FREETYPE_BUNDLE_LIB_PATH), ) ifneq ($(FREETYPE_BUNDLE_LIB_PATH), )
# We need to bundle the freetype library, so it will be available at runtime as well as link time. # We need to bundle the freetype library, so it will be available at runtime as well as link time.
# #

View File

@ -1,5 +1,5 @@
# #
# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,7 @@ formatVersion=1
# Version of the currency code information in this class. # Version of the currency code information in this class.
# It is a serial number that accompanies with each amendment. # It is a serial number that accompanies with each amendment.
dataVersion=156 dataVersion=159
# List of all valid ISO 4217 currency codes. # List of all valid ISO 4217 currency codes.
# To ensure compatibility, do not remove codes. # To ensure compatibility, do not remove codes.
@ -332,7 +332,7 @@ LY=LYD
# LIECHTENSTEIN # LIECHTENSTEIN
LI=CHF LI=CHF
# LITHUANIA # LITHUANIA
LT=LTL LT=LTL;2014-12-31-22-00-00;EUR
# LUXEMBOURG # LUXEMBOURG
LU=EUR LU=EUR
# MACAU # MACAU

View File

@ -58,7 +58,14 @@ EN_LOCALES := en%
# Locales that don't have any resource files should be included here. # Locales that don't have any resource files should be included here.
ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH ALL_NON_EN_LOCALES := ja-JP-JP nb-NO nn-NO th-TH-TH
SED_ARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g' SED_ENARGS := -e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g'
SED_NONENARGS := $(SED_ENARGS)
# Fill in the languages and package names
SED_ENARGS += -e 's/$(HASH)Lang$(HASH)/En/' \
-e 's/$(HASH)Package$(HASH)/sun.util.locale.provider/'
SED_NONENARGS += -e 's/$(HASH)Lang$(HASH)/NonEn/' \
-e 's/$(HASH)Package$(HASH)/sun.util.resources.provider/'
# This macro creates a sed expression that substitues for example: # This macro creates a sed expression that substitues for example:
# #FormatData_ENLocales# with: en% locales. # #FormatData_ENLocales# with: en% locales.
@ -78,8 +85,8 @@ define CaptureLocale
ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES) ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES)
# Don't sed in a space if there are no locales. # Don't sed in a space if there are no locales.
SED_ARGS += -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g' SED_ENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g'
SED_ARGS += -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g' SED_NONENARGS += -e 's/$$(HASH)$1_Locales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g'
endef endef
#sun.text.resources.FormatData #sun.text.resources.FormatData
@ -106,17 +113,25 @@ $(eval $(call CaptureLocale,CurrencyNames))
#sun.util.resources.CalendarData #sun.util.resources.CalendarData
$(eval $(call CaptureLocale,CalendarData)) $(eval $(call CaptureLocale,CalendarData))
SED_ARGS += -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g' SED_ENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_EN_LOCALES))/g'
SED_ARGS += -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g' SED_NONENARGS += -e 's/$(HASH)AvailableLocales_Locales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g'
$(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java: \ $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java: \
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template $(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
$(MKDIR) -p $(@D) $(MKDIR) -p $(@D)
$(ECHO) Creating sun/util/LocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources. $(ECHO) Creating sun/util/locale/provider/EnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources $(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
$(SED) $(SED_ARGS) $< > $@ $(SED) $(SED_ENARGS) $< > $@
GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/LocaleDataMetaInfo.java $(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java: \
$(JDK_TOPDIR)/src/java.base/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template
$(MKDIR) -p $(@D)
$(ECHO) Creating sun/util/resources/provider/NonEnLocaleDataMetaInfo.java from $(words $(LOCALE_RESOURCES)) found resources.
$(PRINTF) "PREV_LOCALE_RESOURCES:=$(LOCALE_RESOURCES)" > $(JDK_OUTPUTDIR)/gensrc/_the.locale_resources
$(SED) $(SED_NONENARGS) $< > $@
GENSRC_LOCALEDATAMETAINFO := $(JDK_OUTPUTDIR)/gensrc/java.base/sun/util/locale/provider/EnLocaleDataMetaInfo.java \
$(JDK_OUTPUTDIR)/gensrc/jdk.localedata/sun/util/resources/provider/NonEnLocaleDataMetaInfo.java
################################################################################ ################################################################################

View File

@ -168,11 +168,6 @@ FULL_JRE_LIB_FILES := \
$(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)t2k$(SHARED_LIBRARY_SUFFIX) \
$(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \ $(OPENJDK_TARGET_CPU_LEGACY_LIB)/$(LIBRARY_PREFIX)unpack$(SHARED_LIBRARY_SUFFIX) \
charsets.jar \ charsets.jar \
cmm/CIEXYZ.pf \
cmm/GRAY.pf \
cmm/LINEAR_RGB.pf \
cmm/PYCC.pf \
cmm/sRGB.pf \
ext/cldrdata.jar \ ext/cldrdata.jar \
ext/dnsns.jar \ ext/dnsns.jar \
ext/nashorn.jar \ ext/nashorn.jar \

View File

@ -431,7 +431,7 @@ public class CLDRConverter {
allLocales.addAll(metaInfo.get("LocaleNames")); allLocales.addAll(metaInfo.get("LocaleNames"));
allLocales.addAll(metaInfo.get("CalendarData")); allLocales.addAll(metaInfo.get("CalendarData"));
allLocales.addAll(metaInfo.get("FormatData")); allLocales.addAll(metaInfo.get("FormatData"));
metaInfo.put("All", allLocales); metaInfo.put("AvailableLocales", allLocales);
} }
bundleGenerator.generateMetaInfo(metaInfo); bundleGenerator.generateMetaInfo(metaInfo);

View File

@ -159,8 +159,10 @@ class ResourceBundleGenerator implements BundleGenerator {
out.println(CopyrightHeaders.getOpenJDKCopyright()); out.println(CopyrightHeaders.getOpenJDKCopyright());
out.println("package sun.util.cldr;\n\n" out.println("package sun.util.cldr;\n\n"
+ "import java.util.ListResourceBundle;\n"); + "import java.util.ListResourceBundle;\n"
out.printf("public class %s extends ListResourceBundle {\n", METAINFO_CLASS); + "import sun.util.locale.provider.LocaleProviderAdapter;\n"
+ "import sun.util.locale.provider.LocaleDataMetaInfo;\n");
out.printf("public class %s extends ListResourceBundle implements LocaleDataMetaInfo {\n", METAINFO_CLASS);
out.println(" @Override\n" + out.println(" @Override\n" +
" protected final Object[][] getContents() {\n" + " protected final Object[][] getContents() {\n" +
" final Object[][] data = new Object[][] {"); " final Object[][] data = new Object[][] {");
@ -168,7 +170,15 @@ class ResourceBundleGenerator implements BundleGenerator {
out.printf(" { \"%s\",\n", key); out.printf(" { \"%s\",\n", key);
out.printf(" \"%s\" },\n", toLocaleList(metaInfo.get(key))); out.printf(" \"%s\" },\n", toLocaleList(metaInfo.get(key)));
} }
out.println(" };\n return data;\n }\n}"); out.println(" };\n return data;\n }\n\n");
out.println(" public LocaleProviderAdapter.Type getType() {\n" +
" return LocaleProviderAdapter.Type.CLDR;\n" +
" }\n\n");
out.println(" public String availableLanguageTags(String category) {\n" +
" return getString(category);\n" +
" };\n}");
} }
} }

View File

@ -72,6 +72,7 @@ J2DANALYZER_CLASSES = \
J2DBENCH_RESOURCES = \ J2DBENCH_RESOURCES = \
$(CLASSES)/j2dbench/tests/iio/images \ $(CLASSES)/j2dbench/tests/iio/images \
$(CLASSES)/j2dbench/tests/cmm/images \
$(CLASSES)/j2dbench/tests/text/textdata $(CLASSES)/j2dbench/tests/text/textdata
SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files SCM_DIRs = .hg .svn CVS RCS SCCS Codemgr_wsdata deleted_files
@ -101,6 +102,10 @@ $(CLASSES)/j2dbench/tests/text/textdata: $(RESOURCES)/textdata
cp -r $< $@ cp -r $< $@
cd $@ && rm -rf $(SCM_DIRs) cd $@ && rm -rf $(SCM_DIRs)
$(CLASSES)/j2dbench/tests/cmm/images: $(RESOURCES)/cmm_images
cp -r $< $@
cd $@ && rm -rf $(SCM_DIRs)
$(CLASSES)/j2dbench.manifest: $(CLASSES)/j2dbench.manifest:
echo "Main-Class: j2dbench.J2DBench" > $@ echo "Main-Class: j2dbench.J2DBench" > $@
@ -115,7 +120,7 @@ $(CLASSES):
mkdirs: $(DIST) $(CLASSES) mkdirs: $(DIST) $(CLASSES)
$(CLASSES)/j2dbench/%.class: $(SOURCEPATH)/j2dbench/%.java $(CLASSES)/j2dbench/%.class: $(SOURCEPATH)/j2dbench/%.java
javac -source 1.2 -target 1.2 -d $(CLASSES) -sourcepath $(SOURCEPATH) $< javac -g:none -source 1.6 -target 1.6 -d $(CLASSES) -sourcepath $(SOURCEPATH) $<
clean: clean:
rm -rf $(CLASSES) rm -rf $(CLASSES)

View File

@ -19,10 +19,9 @@ from the results files generated by the J2DBench runs.
Minimum requirements Minimum requirements
----------------------------------------------------------------------- -----------------------------------------------------------------------
The benchmark requires at least jdk1.4 to compile and The benchmark requires at least jdk1.4 to compile and run. Note that
at least jdk1.2** to run. source/target is set to 1.6 in the makefile and build.xml, because of
support in jdk 9 compiler.
** Note: the goal is to make the benchmark run on 1.1.x as well.
----------------------------------------------------------------------- -----------------------------------------------------------------------
How To Compile How To Compile
@ -125,7 +124,7 @@ choosing the options and benchmarks to run.
After the options file is created, start J2DBench in batch mode to run After the options file is created, start J2DBench in batch mode to run
the benchmarks for the default pipeline: the benchmarks for the default pipeline:
#> java -jar dest/J2DBench.jar -batch -loadopts options/default.opt \ #> java -jar dist/J2DBench.jar -batch -loadopts options/default.opt \
-saveres default.res -title "Rendering - Default ppl" \ -saveres default.res -title "Rendering - Default ppl" \
-desc "Rendering tests with the default pipeline" -desc "Rendering tests with the default pipeline"
@ -136,13 +135,13 @@ file and save the result in default.res file.
"Run Tests" in the J2DBench dialog) "Run Tests" in the J2DBench dialog)
Now run the benchmark with opengl pipeline: Now run the benchmark with opengl pipeline:
#> java -Dsun.java2d.opengl=True -jar dest/J2DBench.jar -batch \ #> java -Dsun.java2d.opengl=True -jar dist/J2DBench.jar -batch \
-loadopts options/default.opt \ -loadopts options/default.opt \
-saveres opengl.res -title "Rendering - OpenGL" \ -saveres opengl.res -title "Rendering - OpenGL" \
-desc "Rendering tests with OpenGL pipeline" -desc "Rendering tests with OpenGL pipeline"
Now let's analyze the results using J2DAnalyzer: Now let's analyze the results using J2DAnalyzer:
#> java -jar dest/J2DAnalyzer.jar default.res opengl.res #> java -jar dist/J2DAnalyzer.jar default.res opengl.res
Note that you can compare more than two sets of results, see Note that you can compare more than two sets of results, see
J2DAnalyzer's help page. J2DAnalyzer's help page.

View File

@ -49,7 +49,7 @@
<target name="compile" depends="init" <target name="compile" depends="init"
description="compile the source " > description="compile the source " >
<!-- Compile the java code from ${src} into ${build} --> <!-- Compile the java code from ${src} into ${build} -->
<javac debug="flase" source="1.5" target="1.5" srcdir="${src}" destdir="${build}"/> <javac debug="off" source="1.6" target="1.6" srcdir="${src}" destdir="${build}"/>
</target> </target>
<target name="run" depends="dist" <target name="run" depends="dist"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -39,23 +39,24 @@
package j2dbench.tests.cmm; package j2dbench.tests.cmm;
import j2dbench.Group;
import j2dbench.Option;
import j2dbench.Result;
import j2dbench.Test;
import j2dbench.TestEnvironment;
import java.awt.color.ColorSpace; import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace; import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile; import java.awt.color.ICC_Profile;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import j2dbench.Group;
import j2dbench.Option;
import j2dbench.Result;
import j2dbench.Test;
import j2dbench.TestEnvironment;
public class CMMTests extends Test { public class CMMTests extends Test {
protected static Group cmmRoot; protected static Group cmmRoot;
protected static Group cmmOptRoot; protected static Group cmmOptRoot;
protected static Option csList; protected static Option csList;
protected static Option usePlatfromProfiles; protected static Option usePlatformProfiles;
public static void init() { public static void init() {
cmmRoot = new Group("cmm", "Color Management Benchmarks"); cmmRoot = new Group("cmm", "Color Management Benchmarks");
@ -64,9 +65,9 @@ public class CMMTests extends Test {
cmmOptRoot = new Group(cmmRoot, "opts", "General Options"); cmmOptRoot = new Group(cmmRoot, "opts", "General Options");
/* /*
usePlatfromProfiles = usePlatformProfiles =
new Option.Enable(cmmOptRoot, "csPlatfrom", new Option.Enable(cmmOptRoot, "csPlatform",
"Use Platfrom Profiles", false); "Use Platform Profiles", false);
*/ */
int[] colorspaces = new int[] { int[] colorspaces = new int[] {
ColorSpace.CS_sRGB, ColorSpace.CS_sRGB,
@ -92,10 +93,10 @@ public class CMMTests extends Test {
protected static ColorSpace getColorSpace(TestEnvironment env) { protected static ColorSpace getColorSpace(TestEnvironment env) {
ColorSpace cs; ColorSpace cs;
Boolean usePlatfrom = true; //(Boolean)env.getModifier(usePlatfromProfiles); boolean usePlatform = true; //(Boolean)env.getModifier(usePlatformProfiles);
int cs_code = env.getIntValue(csList); int cs_code = env.getIntValue(csList);
if (usePlatfrom) { if (usePlatform) {
cs = ColorSpace.getInstance(cs_code); cs = ColorSpace.getInstance(cs_code);
} else { } else {
String resource = "profiles/"; String resource = "profiles/";
@ -136,17 +137,14 @@ public class CMMTests extends Test {
addDependencies(cmmOptRoot, true); addDependencies(cmmOptRoot, true);
} }
@Override
public Object initTest(TestEnvironment te, Result result) { public Object initTest(TestEnvironment te, Result result) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }
@Override
public void runTest(Object o, int i) { public void runTest(Object o, int i) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }
@Override
public void cleanupTest(TestEnvironment te, Object o) { public void cleanupTest(TestEnvironment te, Object o) {
throw new UnsupportedOperationException("Not supported yet."); throw new UnsupportedOperationException("Not supported yet.");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -39,11 +39,6 @@
package j2dbench.tests.cmm; package j2dbench.tests.cmm;
import j2dbench.Group;
import j2dbench.Option;
import j2dbench.Result;
import j2dbench.TestEnvironment;
import j2dbench.tests.iio.IIOTests;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -53,15 +48,22 @@ import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp; import java.awt.image.ColorConvertOp;
import java.awt.image.Raster; import java.awt.image.Raster;
import java.awt.image.WritableRaster; import java.awt.image.WritableRaster;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import j2dbench.Group;
import j2dbench.Option;
import j2dbench.Result;
import j2dbench.TestEnvironment;
import j2dbench.tests.iio.IIOTests;
public class ColorConvertOpTests extends ColorConversionTests { public class ColorConvertOpTests extends ColorConversionTests {
private static enum ImageContent { private static class ImageContent {
BLANK("bank", "Blank (opaque black)"), static ImageContent BLANK = new ImageContent("bank", "Blank (opaque black)");
RANDOM("random", "Random"), static ImageContent RANDOM = new ImageContent("random", "Random");
VECTOR("vector", "Vector Art"), static ImageContent VECTOR = new ImageContent("vector", "Vector Art");
PHOTO("photo", "Photograph"); static ImageContent PHOTO= new ImageContent("photo", "Photograph");
public final String name; public final String name;
public final String descr; public final String descr;
@ -70,15 +72,19 @@ public class ColorConvertOpTests extends ColorConversionTests {
this.name = name; this.name = name;
this.descr = descr; this.descr = descr;
} }
public static ImageContent[] values() {
return new ImageContent[]{BLANK, RANDOM, VECTOR, PHOTO};
}
} }
private static enum ImageType { private static class ImageType {
INT_ARGB(BufferedImage.TYPE_INT_ARGB, "INT_ARGB", "TYPE_INT_ARGB"), static ImageType INT_ARGB = new ImageType(BufferedImage.TYPE_INT_ARGB, "INT_ARGB", "TYPE_INT_ARGB");
INT_RGB(BufferedImage.TYPE_INT_RGB, "INT_RGB", "TYPE_INT_RGB"), static ImageType INT_RGB = new ImageType(BufferedImage.TYPE_INT_RGB, "INT_RGB", "TYPE_INT_RGB");
INT_BGR(BufferedImage.TYPE_INT_BGR, "INT_BGR", "TYPE_INT_BGR"), static ImageType INT_BGR = new ImageType(BufferedImage.TYPE_INT_BGR, "INT_BGR", "TYPE_INT_BGR");
BYTE_3BYTE_BGR(BufferedImage.TYPE_3BYTE_BGR, "3BYTE_BGR", "TYPE_3BYTE_BGR"), static ImageType BYTE_3BYTE_BGR = new ImageType(BufferedImage.TYPE_3BYTE_BGR, "3BYTE_BGR", "TYPE_3BYTE_BGR");
BYTE_4BYTE_ABGR(BufferedImage.TYPE_4BYTE_ABGR, "4BYTE_BGR", "TYPE_4BYTE_BGR"), static ImageType BYTE_4BYTE_ABGR = new ImageType(BufferedImage.TYPE_4BYTE_ABGR, "4BYTE_BGR", "TYPE_4BYTE_BGR");
COMPATIBLE_DST(0, "Compatible", "Compatible destination"); static ImageType COMPATIBLE_DST = new ImageType(0, "Compatible", "Compatible destination");
private ImageType(int type, String abbr, String descr) { private ImageType(int type, String abbr, String descr) {
this.type = type; this.type = type;
@ -89,11 +95,16 @@ public class ColorConvertOpTests extends ColorConversionTests {
public final int type; public final int type;
public final String abbrev; public final String abbrev;
public final String descr; public final String descr;
public static ImageType[] values() {
return new ImageType[]{INT_ARGB, INT_RGB, INT_BGR,
BYTE_3BYTE_BGR, BYTE_4BYTE_ABGR, COMPATIBLE_DST};
}
} }
private static enum ListType { private static class ListType {
SRC("srcType", "Source Images"), static ListType SRC = new ListType("srcType", "Source Images");
DST("dstType", "Destination Images"); static ListType DST = new ListType("dstType", "Destination Images");
private ListType(String name, String description) { private ListType(String name, String description) {
this.name = name; this.name = name;
@ -320,64 +331,55 @@ public class ColorConvertOpTests extends ColorConversionTests {
BufferedImage image; BufferedImage image;
image = new BufferedImage(width, height, type); image = new BufferedImage(width, height, type);
boolean hasAlpha = image.getColorModel().hasAlpha(); boolean hasAlpha = image.getColorModel().hasAlpha();
switch (contentType) { if (contentType == ImageContent.RANDOM) {
case RANDOM: for (int y = 0; y < height; y++) {
for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) {
for (int x = 0; x < width; x++) { int rgb = (int) (Math.random() * 0xffffff);
int rgb = (int)(Math.random() * 0xffffff);
if (hasAlpha) {
rgb |= 0x7f000000;
}
image.setRGB(x, y, rgb);
}
}
break;
case VECTOR:
{
Graphics2D g = image.createGraphics();
if (hasAlpha) { if (hasAlpha) {
// fill background with a translucent color rgb |= 0x7f000000;
g.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC, 0.5f));
} }
g.setColor(Color.blue); image.setRGB(x, y, rgb);
g.fillRect(0, 0, width, height);
g.setComposite(AlphaComposite.Src);
g.setColor(Color.yellow);
g.fillOval(2, 2, width-4, height-4);
g.setColor(Color.red);
g.fillOval(4, 4, width-8, height-8);
g.setColor(Color.green);
g.fillRect(8, 8, width-16, height-16);
g.setColor(Color.white);
g.drawLine(0, 0, width, height);
g.drawLine(0, height, width, 0);
g.dispose();
break;
} }
case PHOTO: }
{ }
Image photo = null; if (contentType == ImageContent.VECTOR) {
try { Graphics2D g = image.createGraphics();
photo = ImageIO.read( if (hasAlpha) {
IIOTests.class.getResourceAsStream("images/photo.jpg")); // fill background with a translucent color
} catch (Exception e) { g.setComposite(AlphaComposite.getInstance(
System.err.println("error loading photo"); AlphaComposite.SRC, 0.5f));
e.printStackTrace(); }
} g.setColor(Color.blue);
Graphics2D g = image.createGraphics(); g.fillRect(0, 0, width, height);
if (hasAlpha) { g.setComposite(AlphaComposite.Src);
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, g.setColor(Color.yellow);
0.5f)); g.fillOval(2, 2, width-4, height-4);
} g.setColor(Color.red);
g.drawImage(photo, 0, 0, width, height, null); g.fillOval(4, 4, width-8, height-8);
g.dispose(); g.setColor(Color.green);
break; g.fillRect(8, 8, width-16, height-16);
} g.setColor(Color.white);
default: g.drawLine(0, 0, width, height);
break; g.drawLine(0, height, width, 0);
g.dispose();
}
if (contentType == ImageContent.PHOTO) {
Image photo = null;
try {
photo = ImageIO.read(
IIOTests.class.getResourceAsStream("images/photo.jpg"));
} catch (Exception e) {
System.err.println("error loading photo");
e.printStackTrace();
}
Graphics2D g = image.createGraphics();
if (hasAlpha) {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC,
0.5f));
}
g.drawImage(photo, 0, 0, width, height, null);
g.dispose();
} }
return image; return image;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -39,10 +39,11 @@
package j2dbench.tests.cmm; package j2dbench.tests.cmm;
import java.awt.color.ColorSpace;
import j2dbench.Group; import j2dbench.Group;
import j2dbench.Result; import j2dbench.Result;
import j2dbench.TestEnvironment; import j2dbench.TestEnvironment;
import java.awt.color.ColorSpace;
public class DataConversionTests extends ColorConversionTests { public class DataConversionTests extends ColorConversionTests {
@ -92,13 +93,11 @@ public class DataConversionTests extends ColorConversionTests {
} }
} }
@Override
public Object initTest(TestEnvironment env, Result result) { public Object initTest(TestEnvironment env, Result result) {
ColorSpace cs = getColorSpace(env); ColorSpace cs = getColorSpace(env);
return new Context(env, result, cs); return new Context(env, result, cs);
} }
@Override
public void cleanupTest(TestEnvironment te, Object o) { public void cleanupTest(TestEnvironment te, Object o) {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -39,16 +39,18 @@
package j2dbench.tests.cmm; package j2dbench.tests.cmm;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import j2dbench.Group; import j2dbench.Group;
import j2dbench.Option; import j2dbench.Option;
import j2dbench.Result; import j2dbench.Result;
import j2dbench.TestEnvironment; import j2dbench.TestEnvironment;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
/* This benchmark verifies how changes in cmm library affects image decoding */ /* This benchmark verifies how changes in cmm library affects image decoding */
public class EmbeddedProfileTests extends ColorConversionTests { public class EmbeddedProfileTests extends ColorConversionTests {
@ -68,10 +70,10 @@ public class EmbeddedProfileTests extends ColorConversionTests {
new ReadImageTest(); new ReadImageTest();
} }
private static enum IccImageResource { private static class IccImageResource {
SMALL("images/img_icc_small.jpg", "512x512", "Small: 512x512"), static IccImageResource SMALL = new IccImageResource("images/img_icc_small.jpg", "512x512", "Small: 512x512");
MEDIUM("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048"), static IccImageResource MEDIUM = new IccImageResource("images/img_icc_medium.jpg", "2048x2048", "Medium: 2048x2048");
LARGE("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096"); static IccImageResource LARGE = new IccImageResource("images/img_icc_large.jpg", "4096x4096", "Large: 4096x4096");
private IccImageResource(String file, String name, String description) { private IccImageResource(String file, String name, String description) {
this.url = CMMTests.class.getResource(file); this.url = CMMTests.class.getResource(file);
@ -82,6 +84,10 @@ public class EmbeddedProfileTests extends ColorConversionTests {
public final URL url; public final URL url;
public final String abbrev; public final String abbrev;
public final String description; public final String description;
public static IccImageResource[] values() {
return new IccImageResource[]{SMALL, MEDIUM, LARGE};
}
} }
private static Option createImageList() { private static Option createImageList() {
@ -145,7 +151,7 @@ public class EmbeddedProfileTests extends ColorConversionTests {
try { try {
iis = ImageIO.createImageInputStream(url.openStream()); iis = ImageIO.createImageInputStream(url.openStream());
reader = ImageIO.getImageReaders(iis).next(); reader = (ImageReader) ImageIO.getImageReaders(iis).next();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException("Unable to run the becnhmark", e); throw new RuntimeException("Unable to run the becnhmark", e);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -38,12 +38,12 @@
*/ */
package j2dbench.tests.cmm; package j2dbench.tests.cmm;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import j2dbench.Group; import j2dbench.Group;
import j2dbench.Result; import j2dbench.Result;
import j2dbench.TestEnvironment; import j2dbench.TestEnvironment;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
public class ProfileTests extends CMMTests { public class ProfileTests extends CMMTests {
@ -73,13 +73,11 @@ public class ProfileTests extends CMMTests {
} }
} }
@Override
public Object initTest(TestEnvironment env, Result res) { public Object initTest(TestEnvironment env, Result res) {
ICC_ColorSpace cs = (ICC_ColorSpace) getColorSpace(env); ICC_ColorSpace cs = (ICC_ColorSpace) getColorSpace(env);
return new Context(cs.getProfile(), env, res); return new Context(cs.getProfile(), env, res);
} }
@Override
public void cleanupTest(TestEnvironment env, Object o) { public void cleanupTest(TestEnvironment env, Object o) {
} }
@ -91,7 +89,6 @@ public class ProfileTests extends CMMTests {
"getData(icSigHead)"); "getData(icSigHead)");
} }
@Override
public void runTest(Object ctx, int numReps) { public void runTest(Object ctx, int numReps) {
final Context ictx = (Context) ctx; final Context ictx = (Context) ctx;
final ICC_Profile profile = ictx.profile; final ICC_Profile profile = ictx.profile;
@ -115,7 +112,6 @@ public class ProfileTests extends CMMTests {
"getNumComponents"); "getNumComponents");
} }
@Override
public void runTest(Object ctx, int numReps) { public void runTest(Object ctx, int numReps) {
final Context ictx = (Context) ctx; final Context ictx = (Context) ctx;
final ICC_Profile profile = ictx.profile; final ICC_Profile profile = ictx.profile;

View File

@ -407,7 +407,7 @@ public interface CompletionStage<T> {
/** /**
* Returns a new CompletionStage that, when this and the other * Returns a new CompletionStage that, when this and the other
* given stage complete normally, executes the given action using * given stage complete normally, executes the given action using
* the supplied executor * the supplied executor.
* *
* See the {@link CompletionStage} documentation for rules * See the {@link CompletionStage} documentation for rules
* covering exceptional completion. * covering exceptional completion.
@ -569,7 +569,7 @@ public interface CompletionStage<T> {
/** /**
* Returns a new CompletionStage that, when either this or the * Returns a new CompletionStage that, when either this or the
* other given stage complete normally, executes the given action * other given stage complete normally, executes the given action
* using supplied executor. * using the supplied executor.
* *
* See the {@link CompletionStage} documentation for rules * See the {@link CompletionStage} documentation for rules
* covering exceptional completion. * covering exceptional completion.
@ -649,10 +649,15 @@ public interface CompletionStage<T> {
(Function<Throwable, ? extends T> fn); (Function<Throwable, ? extends T> fn);
/** /**
* Returns a new CompletionStage with the same result or exception * Returns a new CompletionStage with the same result or exception as
* as this stage, and when this stage completes, executes the * this stage, that executes the given action when this stage completes.
* given action with the result (or {@code null} if none) and the *
* exception (or {@code null} if none) of this stage. * <p>When this stage is complete, the given action is invoked with the
* result (or {@code null} if none) and the exception (or {@code null}
* if none) of this stage as arguments. The returned stage is completed
* when the action returns. If the supplied action itself encounters an
* exception, then the returned stage exceptionally completes with this
* exception unless this stage also completed exceptionally.
* *
* @param action the action to perform * @param action the action to perform
* @return the new CompletionStage * @return the new CompletionStage
@ -661,12 +666,16 @@ public interface CompletionStage<T> {
(BiConsumer<? super T, ? super Throwable> action); (BiConsumer<? super T, ? super Throwable> action);
/** /**
* Returns a new CompletionStage with the same result or exception * Returns a new CompletionStage with the same result or exception as
* as this stage, and when this stage completes, executes the * this stage, that executes the given action using this stage's
* given action executes the given action using this stage's * default asynchronous execution facility when this stage completes.
* default asynchronous execution facility, with the result (or *
* {@code null} if none) and the exception (or {@code null} if * <p>When this stage is complete, the given action is invoked with the
* none) of this stage as arguments. * result (or {@code null} if none) and the exception (or {@code null}
* if none) of this stage as arguments. The returned stage is completed
* when the action returns. If the supplied action itself encounters an
* exception, then the returned stage exceptionally completes with this
* exception unless this stage also completed exceptionally.
* *
* @param action the action to perform * @param action the action to perform
* @return the new CompletionStage * @return the new CompletionStage
@ -675,11 +684,16 @@ public interface CompletionStage<T> {
(BiConsumer<? super T, ? super Throwable> action); (BiConsumer<? super T, ? super Throwable> action);
/** /**
* Returns a new CompletionStage with the same result or exception * Returns a new CompletionStage with the same result or exception as
* as this stage, and when this stage completes, executes using * this stage, that executes the given action using the supplied
* the supplied Executor, the given action with the result (or * Executor when this stage completes.
* {@code null} if none) and the exception (or {@code null} if *
* none) of this stage as arguments. * <p>When this stage is complete, the given action is invoked with the
* result (or {@code null} if none) and the exception (or {@code null}
* if none) of this stage as arguments. The returned stage is completed
* when the action returns. If the supplied action itself encounters an
* exception, then the returned stage exceptionally completes with this
* exception unless this stage also completed exceptionally.
* *
* @param action the action to perform * @param action the action to perform
* @param executor the executor to use for asynchronous execution * @param executor the executor to use for asynchronous execution
@ -693,9 +707,11 @@ public interface CompletionStage<T> {
* Returns a new CompletionStage that, when this stage completes * Returns a new CompletionStage that, when this stage completes
* either normally or exceptionally, is executed with this stage's * either normally or exceptionally, is executed with this stage's
* result and exception as arguments to the supplied function. * result and exception as arguments to the supplied function.
* The given function is invoked with the result (or {@code null} *
* if none) and the exception (or {@code null} if none) of this * <p>When this stage is complete, the given function is invoked
* stage when complete as arguments. * with the result (or {@code null} if none) and the exception (or
* {@code null} if none) of this stage as arguments, and the
* function's result is used to complete the returned stage.
* *
* @param fn the function to use to compute the value of the * @param fn the function to use to compute the value of the
* returned CompletionStage * returned CompletionStage
@ -710,9 +726,11 @@ public interface CompletionStage<T> {
* either normally or exceptionally, is executed using this stage's * either normally or exceptionally, is executed using this stage's
* default asynchronous execution facility, with this stage's * default asynchronous execution facility, with this stage's
* result and exception as arguments to the supplied function. * result and exception as arguments to the supplied function.
* The given function is invoked with the result (or {@code null} *
* if none) and the exception (or {@code null} if none) of this * <p>When this stage is complete, the given function is invoked
* stage when complete as arguments. * with the result (or {@code null} if none) and the exception (or
* {@code null} if none) of this stage as arguments, and the
* function's result is used to complete the returned stage.
* *
* @param fn the function to use to compute the value of the * @param fn the function to use to compute the value of the
* returned CompletionStage * returned CompletionStage
@ -726,10 +744,12 @@ public interface CompletionStage<T> {
* Returns a new CompletionStage that, when this stage completes * Returns a new CompletionStage that, when this stage completes
* either normally or exceptionally, is executed using the * either normally or exceptionally, is executed using the
* supplied executor, with this stage's result and exception as * supplied executor, with this stage's result and exception as
* arguments to the supplied function. The given function is * arguments to the supplied function.
* invoked with the result (or {@code null} if none) and the *
* exception (or {@code null} if none) of this stage when complete * <p>When this stage is complete, the given function is invoked
* as arguments. * with the result (or {@code null} if none) and the exception (or
* {@code null} if none) of this stage as arguments, and the
* function's result is used to complete the returned stage.
* *
* @param fn the function to use to compute the value of the * @param fn the function to use to compute the value of the
* returned CompletionStage * returned CompletionStage

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -158,8 +158,8 @@ public final class CertAndKeyGen {
// publicKey's format must be X.509 otherwise // publicKey's format must be X.509 otherwise
// the whole CertGen part of this class is broken. // the whole CertGen part of this class is broken.
if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) { if (!"X.509".equalsIgnoreCase(publicKey.getFormat())) {
throw new IllegalArgumentException("publicKey's is not X.509, but " throw new IllegalArgumentException("Public key format is "
+ publicKey.getFormat()); + publicKey.getFormat() + ", must be X.509");
} }
} }

View File

@ -25,20 +25,20 @@
package sun.util.cldr; package sun.util.cldr;
import java.io.File;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.text.spi.BreakIteratorProvider; import java.text.spi.BreakIteratorProvider;
import java.text.spi.CollatorProvider; import java.text.spi.CollatorProvider;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle; import java.util.ServiceLoader;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.spi.TimeZoneNameProvider;
import sun.util.locale.provider.JRELocaleProviderAdapter; import sun.util.locale.provider.JRELocaleProviderAdapter;
import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleProviderAdapter;
import sun.util.locale.provider.LocaleDataMetaInfo;
/** /**
* LocaleProviderAdapter implementation for the CLDR locale data. * LocaleProviderAdapter implementation for the CLDR locale data.
@ -47,26 +47,31 @@ import sun.util.locale.provider.LocaleProviderAdapter;
* @author Naoto Sato * @author Naoto Sato
*/ */
public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter { public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
private static final String LOCALE_DATA_JAR_NAME = "cldrdata.jar";
private final LocaleDataMetaInfo metaInfo;
public CLDRLocaleProviderAdapter() { public CLDRLocaleProviderAdapter() {
final String sep = File.separator; try {
String localeDataJar = java.security.AccessController.doPrivileged( metaInfo = AccessController.doPrivileged(new PrivilegedExceptionAction<LocaleDataMetaInfo>() {
new sun.security.action.GetPropertyAction("java.home"))
+ sep + "lib" + sep + "ext" + sep + LOCALE_DATA_JAR_NAME;
// Peek at the installed extension directory to see if the jar file for
// CLDR resources is installed or not.
final File f = new File(localeDataJar);
boolean result = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
@Override @Override
public Boolean run() { public LocaleDataMetaInfo run() {
return f.exists(); for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) {
if (ldmi.getType() == LocaleProviderAdapter.Type.CLDR) {
return ldmi;
}
}
return null;
} }
}); });
if (!result) { } catch (Exception e) {
throw new UnsupportedOperationException(); // Catch any exception, and fail gracefully as if CLDR locales do not exist.
// It's ok ignore it if something wrong happens because there always is the
// JRE or FALLBACK LocaleProviderAdapter that will do the right thing.
throw new UnsupportedOperationException(e);
}
if (metaInfo == null) {
throw new UnsupportedOperationException("CLDR locale data could not be found.");
} }
} }
@ -91,7 +96,7 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
@Override @Override
public Locale[] getAvailableLocales() { public Locale[] getAvailableLocales() {
Set<String> all = createLanguageTagSet("All"); Set<String> all = createLanguageTagSet("AvailableLocales");
Locale[] locs = new Locale[all.size()]; Locale[] locs = new Locale[all.size()];
int index = 0; int index = 0;
for (String tag : all) { for (String tag : all) {
@ -102,11 +107,10 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter {
@Override @Override
protected Set<String> createLanguageTagSet(String category) { protected Set<String> createLanguageTagSet(String category) {
ResourceBundle rb = ResourceBundle.getBundle("sun.util.cldr.CLDRLocaleDataMetaInfo", Locale.ROOT); String supportedLocaleString = metaInfo.availableLanguageTags(category);
if (rb.containsKey(category)) { if (supportedLocaleString == null) {
return Collections.emptySet(); return Collections.emptySet();
} }
String supportedLocaleString = rb.getString(category);
Set<String> tagset = new HashSet<>(); Set<String> tagset = new HashSet<>();
StringTokenizer tokens = new StringTokenizer(supportedLocaleString); StringTokenizer tokens = new StringTokenizer(supportedLocaleString);
while (tokens.hasMoreTokens()) { while (tokens.hasMoreTokens()) {

View File

@ -56,7 +56,7 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
/** /**
* SPI implementations map * SPI implementations map
*/ */
private ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap = private final ConcurrentMap<Class<? extends LocaleServiceProvider>, LocaleServiceProvider> providersMap =
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();
/** /**
@ -167,7 +167,6 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
avail.addAll(Arrays.asList(lsp.getAvailableLocales())); avail.addAll(Arrays.asList(lsp.getAvailableLocales()));
} }
} }
availableLocales = avail.toArray(new Locale[0]);
} }
// assuming caller won't mutate the array. // assuming caller won't mutate the array.
@ -178,7 +177,7 @@ public abstract class AuxLocaleProviderAdapter extends LocaleProviderAdapter {
* A dummy locale service provider that indicates there is no * A dummy locale service provider that indicates there is no
* provider available * provider available
*/ */
private static NullProvider NULL_PROVIDER = new NullProvider(); private static final NullProvider NULL_PROVIDER = new NullProvider();
private static class NullProvider extends LocaleServiceProvider { private static class NullProvider extends LocaleServiceProvider {
@Override @Override
public Locale[] getAvailableLocales() { public Locale[] getAvailableLocales() {

Some files were not shown because too many files have changed in this diff Show More