Mercurial > hg > graal-compiler
diff src/share/vm/memory/universe.cpp @ 642:660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
Summary: Use zero based compressed oops if java heap is below 32gb and unscaled compressed oops if java heap is below 4gb.
Reviewed-by: never, twisti, jcoomes, coleenp
author | kvn |
---|---|
date | Thu, 12 Mar 2009 10:37:46 -0700 |
parents | d593294016c3 |
children | bd441136a5ce |
line wrap: on
line diff
--- a/src/share/vm/memory/universe.cpp Wed Mar 11 14:16:13 2009 -0700 +++ b/src/share/vm/memory/universe.cpp Thu Mar 12 10:37:46 2009 -0700 @@ -99,7 +99,8 @@ size_t Universe::_heap_used_at_last_gc = 0; CollectedHeap* Universe::_collectedHeap = NULL; -address Universe::_heap_base = NULL; + +NarrowOopStruct Universe::_narrow_oop = { NULL, 0, true }; void Universe::basic_type_classes_do(void f(klassOop)) { @@ -729,6 +730,53 @@ return JNI_OK; } +// Choose the heap base address and oop encoding mode +// when compressed oops are used: +// Unscaled - Use 32-bits oops without encoding when +// NarrowOopHeapBaseMin + heap_size < 4Gb +// ZeroBased - Use zero based compressed oops with encoding when +// NarrowOopHeapBaseMin + heap_size < 32Gb +// HeapBased - Use compressed oops with heap base + encoding. + +// 4Gb +static const uint64_t NarrowOopHeapMax = (uint64_t(max_juint) + 1); +// 32Gb +static const uint64_t OopEncodingHeapMax = NarrowOopHeapMax << LogMinObjAlignmentInBytes; + +char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) { +#ifdef _LP64 + if (UseCompressedOops) { + assert(mode == UnscaledNarrowOop || + mode == ZeroBasedNarrowOop || + mode == HeapBasedNarrowOop, "mode is invalid"); + + const size_t total_size = heap_size + HeapBaseMinAddress; + if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) { + if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) && + (Universe::narrow_oop_shift() == 0)) { + // Use 32-bits oops without encoding and + // place heap's top on the 4Gb boundary + return (char*)(NarrowOopHeapMax - heap_size); + } else { + // Can't reserve with NarrowOopShift == 0 + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); + if (mode == UnscaledNarrowOop || + mode == ZeroBasedNarrowOop && total_size <= NarrowOopHeapMax) { + // 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. + return (char*)(OopEncodingHeapMax - heap_size); + } + } + } else { + // Can't reserve below 32Gb. + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); + } + } +#endif + return NULL; // also return NULL (don't care) for 32-bit VM +} + jint Universe::initialize_heap() { if (UseParallelGC) { @@ -773,6 +821,8 @@ if (status != JNI_OK) { return status; } + +#ifdef _LP64 if (UseCompressedOops) { // Subtract a page because something can get allocated at heap base. // This also makes implicit null checking work, because the @@ -780,8 +830,49 @@ // See needs_explicit_null_check. // Only set the heap base for compressed oops because it indicates // compressed oops for pstack code. - Universe::_heap_base = Universe::heap()->base() - os::vm_page_size(); + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print("heap address: "PTR_FORMAT, Universe::heap()->base()); + } + if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) { + // Can't reserve heap below 32Gb. + Universe::set_narrow_oop_base(Universe::heap()->base() - os::vm_page_size()); + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); + if (PrintCompressedOopsMode) { + tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base()); + } + } else { + Universe::set_narrow_oop_base(0); + if (PrintCompressedOopsMode) { + tty->print(", zero based Compressed Oops"); + } +#ifdef _WIN64 + if (!Universe::narrow_oop_use_implicit_null_checks()) { + // Don't need guard page for implicit checks in indexed addressing + // mode with zero based Compressed Oops. + Universe::set_narrow_oop_use_implicit_null_checks(true); + } +#endif // _WIN64 + if((uint64_t)Universe::heap()->reserved_region().end() > NarrowOopHeapMax) { + // Can't reserve heap below 4Gb. + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); + } else { + assert(Universe::narrow_oop_shift() == 0, "use unscaled narrow oop"); + if (PrintCompressedOopsMode) { + tty->print(", 32-bits Oops"); + } + } + } + if (PrintCompressedOopsMode) { + tty->cr(); + tty->cr(); + } } + assert(Universe::narrow_oop_base() == (Universe::heap()->base() - os::vm_page_size()) || + Universe::narrow_oop_base() == NULL, "invalid value"); + assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes || + Universe::narrow_oop_shift() == 0, "invalid value"); +#endif // We will never reach the CATCH below since Exceptions::_throw will cause // the VM to exit if an exception is thrown during initialization