--- a/hotspot/src/share/vm/memory/universe.cpp Fri Oct 25 11:13:11 2013 -0400
+++ b/hotspot/src/share/vm/memory/universe.cpp Fri Oct 25 15:19:29 2013 -0400
@@ -677,13 +677,13 @@
// HeapBased - Use compressed oops with heap base + encoding.
// 4Gb
-static const uint64_t NarrowOopHeapMax = (uint64_t(max_juint) + 1);
+static const uint64_t UnscaledOopHeapMax = (uint64_t(max_juint) + 1);
// 32Gb
-// OopEncodingHeapMax == NarrowOopHeapMax << LogMinObjAlignmentInBytes;
+// OopEncodingHeapMax == UnscaledOopHeapMax << LogMinObjAlignmentInBytes;
char* Universe::preferred_heap_base(size_t heap_size, size_t alignment, NARROW_OOP_MODE mode) {
assert(is_size_aligned((size_t)OopEncodingHeapMax, alignment), "Must be");
- assert(is_size_aligned((size_t)NarrowOopHeapMax, alignment), "Must be");
+ assert(is_size_aligned((size_t)UnscaledOopHeapMax, alignment), "Must be");
assert(is_size_aligned(heap_size, alignment), "Must be");
uintx heap_base_min_address_aligned = align_size_up(HeapBaseMinAddress, alignment);
@@ -702,20 +702,40 @@
// If the total size is small enough to allow UnscaledNarrowOop then
// just use UnscaledNarrowOop.
} else if ((total_size <= OopEncodingHeapMax) && (mode != HeapBasedNarrowOop)) {
- if ((total_size <= NarrowOopHeapMax) && (mode == UnscaledNarrowOop) &&
+ if ((total_size <= UnscaledOopHeapMax) && (mode == UnscaledNarrowOop) &&
(Universe::narrow_oop_shift() == 0)) {
// Use 32-bits oops without encoding and
// place heap's top on the 4Gb boundary
- base = (NarrowOopHeapMax - heap_size);
+ base = (UnscaledOopHeapMax - heap_size);
} else {
// Can't reserve with NarrowOopShift == 0
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
+
if (mode == UnscaledNarrowOop ||
- mode == ZeroBasedNarrowOop && total_size <= NarrowOopHeapMax) {
+ mode == ZeroBasedNarrowOop && total_size <= UnscaledOopHeapMax) {
+
// Use zero based compressed oops with encoding and
// place heap's top on the 32Gb boundary in case
// total_size > 4Gb or failed to reserve below 4Gb.
- base = (OopEncodingHeapMax - heap_size);
+ uint64_t heap_top = OopEncodingHeapMax;
+
+ // For small heaps, save some space for compressed class pointer
+ // space so it can be decoded with no base.
+ if (UseCompressedClassPointers && !UseSharedSpaces &&
+ OopEncodingHeapMax <= 32*G) {
+
+ uint64_t class_space = align_size_up(CompressedClassSpaceSize, alignment);
+ assert(is_size_aligned((size_t)OopEncodingHeapMax-class_space,
+ alignment), "difference must be aligned too");
+ uint64_t new_top = OopEncodingHeapMax-class_space;
+
+ if (total_size <= new_top) {
+ heap_top = new_top;
+ }
+ }
+
+ // Align base to the adjusted top of the heap
+ base = heap_top - heap_size;
}
}
} else {
@@ -737,7 +757,7 @@
// Set to a non-NULL value so the ReservedSpace ctor computes
// the correct no-access prefix.
// The final value will be set in initialize_heap() below.
- Universe::set_narrow_oop_base((address)NarrowOopHeapMax);
+ Universe::set_narrow_oop_base((address)UnscaledOopHeapMax);
#ifdef _WIN64
if (UseLargePages) {
// Cannot allocate guard pages for implicit checks in indexed
@@ -833,7 +853,7 @@
Universe::set_narrow_oop_use_implicit_null_checks(true);
}
#endif // _WIN64
- if((uint64_t)Universe::heap()->reserved_region().end() > NarrowOopHeapMax) {
+ if((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) {
// Can't reserve heap below 4Gb.
Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes);
} else {