1.1 --- a/src/share/vm/memory/universe.cpp Wed Mar 18 11:37:48 2009 -0400 1.2 +++ b/src/share/vm/memory/universe.cpp Thu Mar 19 09:13:24 2009 -0700 1.3 @@ -99,7 +99,8 @@ 1.4 size_t Universe::_heap_used_at_last_gc = 0; 1.5 1.6 CollectedHeap* Universe::_collectedHeap = NULL; 1.7 -address Universe::_heap_base = NULL; 1.8 + 1.9 +NarrowOopStruct Universe::_narrow_oop = { NULL, 0, true }; 1.10 1.11 1.12 void Universe::basic_type_classes_do(void f(klassOop)) { 1.13 @@ -729,6 +730,53 @@ 1.14 return JNI_OK; 1.15 } 1.16 1.17 +// Choose the heap base address and oop encoding mode 1.18 +// when compressed oops are used: 1.19 +// Unscaled - Use 32-bits oops without encoding when 1.20 +// NarrowOopHeapBaseMin + heap_size < 4Gb 1.21 +// ZeroBased - Use zero based compressed oops with encoding when 1.22 +// NarrowOopHeapBaseMin + heap_size < 32Gb 1.23 +// HeapBased - Use compressed oops with heap base + encoding. 1.24 + 1.25 +// 4Gb 1.26 +static const uint64_t NarrowOopHeapMax = (uint64_t(max_juint) + 1); 1.27 +// 32Gb 1.28 +static const uint64_t OopEncodingHeapMax = NarrowOopHeapMax << LogMinObjAlignmentInBytes; 1.29 + 1.30 +char* Universe::preferred_heap_base(size_t heap_size, NARROW_OOP_MODE mode) { 1.31 +#ifdef _LP64 1.32 + if (UseCompressedOops) { 1.33 + assert(mode == UnscaledNarrowOop || 1.34 + mode == ZeroBasedNarrowOop || 1.35 + mode == HeapBasedNarrowOop, "mode is invalid"); 1.36 + 1.37 + const size_t total_size = heap_size + HeapBaseMinAddress; 1.38 + if (total_size <= OopEncodingHeapMax && (mode != HeapBasedNarrowOop)) { 1.39 + if (total_size <= NarrowOopHeapMax && (mode == UnscaledNarrowOop) && 1.40 + (Universe::narrow_oop_shift() == 0)) { 1.41 + // Use 32-bits oops without encoding and 1.42 + // place heap's top on the 4Gb boundary 1.43 + return (char*)(NarrowOopHeapMax - heap_size); 1.44 + } else { 1.45 + // Can't reserve with NarrowOopShift == 0 1.46 + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); 1.47 + if (mode == UnscaledNarrowOop || 1.48 + mode == ZeroBasedNarrowOop && total_size <= NarrowOopHeapMax) { 1.49 + // Use zero based compressed oops with encoding and 1.50 + // place heap's top on the 32Gb boundary in case 1.51 + // total_size > 4Gb or failed to reserve below 4Gb. 1.52 + return (char*)(OopEncodingHeapMax - heap_size); 1.53 + } 1.54 + } 1.55 + } else { 1.56 + // Can't reserve below 32Gb. 1.57 + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); 1.58 + } 1.59 + } 1.60 +#endif 1.61 + return NULL; // also return NULL (don't care) for 32-bit VM 1.62 +} 1.63 + 1.64 jint Universe::initialize_heap() { 1.65 1.66 if (UseParallelGC) { 1.67 @@ -773,6 +821,8 @@ 1.68 if (status != JNI_OK) { 1.69 return status; 1.70 } 1.71 + 1.72 +#ifdef _LP64 1.73 if (UseCompressedOops) { 1.74 // Subtract a page because something can get allocated at heap base. 1.75 // This also makes implicit null checking work, because the 1.76 @@ -780,8 +830,49 @@ 1.77 // See needs_explicit_null_check. 1.78 // Only set the heap base for compressed oops because it indicates 1.79 // compressed oops for pstack code. 1.80 - Universe::_heap_base = Universe::heap()->base() - os::vm_page_size(); 1.81 + if (PrintCompressedOopsMode) { 1.82 + tty->cr(); 1.83 + tty->print("heap address: "PTR_FORMAT, Universe::heap()->base()); 1.84 + } 1.85 + if ((uint64_t)Universe::heap()->reserved_region().end() > OopEncodingHeapMax) { 1.86 + // Can't reserve heap below 32Gb. 1.87 + Universe::set_narrow_oop_base(Universe::heap()->base() - os::vm_page_size()); 1.88 + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); 1.89 + if (PrintCompressedOopsMode) { 1.90 + tty->print(", Compressed Oops with base: "PTR_FORMAT, Universe::narrow_oop_base()); 1.91 + } 1.92 + } else { 1.93 + Universe::set_narrow_oop_base(0); 1.94 + if (PrintCompressedOopsMode) { 1.95 + tty->print(", zero based Compressed Oops"); 1.96 + } 1.97 +#ifdef _WIN64 1.98 + if (!Universe::narrow_oop_use_implicit_null_checks()) { 1.99 + // Don't need guard page for implicit checks in indexed addressing 1.100 + // mode with zero based Compressed Oops. 1.101 + Universe::set_narrow_oop_use_implicit_null_checks(true); 1.102 + } 1.103 +#endif // _WIN64 1.104 + if((uint64_t)Universe::heap()->reserved_region().end() > NarrowOopHeapMax) { 1.105 + // Can't reserve heap below 4Gb. 1.106 + Universe::set_narrow_oop_shift(LogMinObjAlignmentInBytes); 1.107 + } else { 1.108 + assert(Universe::narrow_oop_shift() == 0, "use unscaled narrow oop"); 1.109 + if (PrintCompressedOopsMode) { 1.110 + tty->print(", 32-bits Oops"); 1.111 + } 1.112 + } 1.113 + } 1.114 + if (PrintCompressedOopsMode) { 1.115 + tty->cr(); 1.116 + tty->cr(); 1.117 + } 1.118 } 1.119 + assert(Universe::narrow_oop_base() == (Universe::heap()->base() - os::vm_page_size()) || 1.120 + Universe::narrow_oop_base() == NULL, "invalid value"); 1.121 + assert(Universe::narrow_oop_shift() == LogMinObjAlignmentInBytes || 1.122 + Universe::narrow_oop_shift() == 0, "invalid value"); 1.123 +#endif 1.124 1.125 // We will never reach the CATCH below since Exceptions::_throw will cause 1.126 // the VM to exit if an exception is thrown during initialization