32 #include "gc/shared/collectedHeap.hpp" |
32 #include "gc/shared/collectedHeap.hpp" |
33 #include "runtime/globals.hpp" |
33 #include "runtime/globals.hpp" |
34 |
34 |
35 // For UseCompressedOops. |
35 // For UseCompressedOops. |
36 NarrowPtrStruct CompressedOops::_narrow_oop = { NULL, 0, true }; |
36 NarrowPtrStruct CompressedOops::_narrow_oop = { NULL, 0, true }; |
37 |
37 MemRegion CompressedOops::_heap_address_range; |
38 address CompressedOops::_narrow_ptrs_base; |
|
39 |
38 |
40 // Choose the heap base address and oop encoding mode |
39 // Choose the heap base address and oop encoding mode |
41 // when compressed oops are used: |
40 // when compressed oops are used: |
42 // Unscaled - Use 32-bits oops without encoding when |
41 // Unscaled - Use 32-bits oops without encoding when |
43 // NarrowOopHeapBaseMin + heap_size < 4Gb |
42 // NarrowOopHeapBaseMin + heap_size < 4Gb |
44 // ZeroBased - Use zero based compressed oops with encoding when |
43 // ZeroBased - Use zero based compressed oops with encoding when |
45 // NarrowOopHeapBaseMin + heap_size < 32Gb |
44 // NarrowOopHeapBaseMin + heap_size < 32Gb |
46 // HeapBased - Use compressed oops with heap base + encoding. |
45 // HeapBased - Use compressed oops with heap base + encoding. |
47 void CompressedOops::initialize() { |
46 void CompressedOops::initialize(const ReservedHeapSpace& heap_space) { |
48 #ifdef _LP64 |
47 #ifdef _LP64 |
49 if (UseCompressedOops) { |
48 // Subtract a page because something can get allocated at heap base. |
50 // Subtract a page because something can get allocated at heap base. |
49 // This also makes implicit null checking work, because the |
51 // This also makes implicit null checking work, because the |
50 // memory+1 page below heap_base needs to cause a signal. |
52 // memory+1 page below heap_base needs to cause a signal. |
51 // See needs_explicit_null_check. |
53 // See needs_explicit_null_check. |
52 // Only set the heap base for compressed oops because it indicates |
54 // Only set the heap base for compressed oops because it indicates |
53 // compressed oops for pstack code. |
55 // compressed oops for pstack code. |
54 if ((uint64_t)heap_space.end() > UnscaledOopHeapMax) { |
56 if ((uint64_t)Universe::heap()->reserved_region().end() > UnscaledOopHeapMax) { |
55 // Didn't reserve heap below 4Gb. Must shift. |
57 // Didn't reserve heap below 4Gb. Must shift. |
56 set_shift(LogMinObjAlignmentInBytes); |
58 set_shift(LogMinObjAlignmentInBytes); |
57 } |
59 } |
58 if ((uint64_t)heap_space.end() <= OopEncodingHeapMax) { |
60 if ((uint64_t)Universe::heap()->reserved_region().end() <= OopEncodingHeapMax) { |
59 // Did reserve heap below 32Gb. Can use base == 0; |
61 // Did reserve heap below 32Gb. Can use base == 0; |
60 set_base(0); |
62 set_base(0); |
61 } else { |
63 } |
62 set_base((address)heap_space.compressed_oop_base()); |
64 AOTLoader::set_narrow_oop_shift(); |
63 } |
65 |
64 |
66 set_ptrs_base(base()); |
65 AOTLoader::set_narrow_oop_shift(); |
67 |
66 |
68 LogTarget(Info, gc, heap, coops) lt; |
67 _heap_address_range = heap_space.region(); |
69 if (lt.is_enabled()) { |
68 |
70 ResourceMark rm; |
69 LogTarget(Info, gc, heap, coops) lt; |
71 LogStream ls(lt); |
70 if (lt.is_enabled()) { |
72 print_mode(&ls); |
71 ResourceMark rm; |
73 } |
72 LogStream ls(lt); |
74 |
73 print_mode(&ls); |
75 // Tell tests in which mode we run. |
74 } |
76 Arguments::PropertyList_add(new SystemProperty("java.vm.compressedOopsMode", |
75 |
77 mode_to_string(mode()), |
76 // Tell tests in which mode we run. |
78 false)); |
77 Arguments::PropertyList_add(new SystemProperty("java.vm.compressedOopsMode", |
79 } |
78 mode_to_string(mode()), |
|
79 false)); |
|
80 |
80 // base() is one page below the heap. |
81 // base() is one page below the heap. |
81 assert((intptr_t)base() <= (intptr_t)(Universe::heap()->base() - os::vm_page_size()) || |
82 assert((intptr_t)base() <= ((intptr_t)_heap_address_range.start() - os::vm_page_size()) || |
82 base() == NULL, "invalid value"); |
83 base() == NULL, "invalid value"); |
83 assert(shift() == LogMinObjAlignmentInBytes || |
84 assert(shift() == LogMinObjAlignmentInBytes || |
84 shift() == 0, "invalid value"); |
85 shift() == 0, "invalid value"); |
85 #endif |
86 #endif |
86 } |
87 } |
97 void CompressedOops::set_use_implicit_null_checks(bool use) { |
98 void CompressedOops::set_use_implicit_null_checks(bool use) { |
98 assert(UseCompressedOops, "no compressed ptrs?"); |
99 assert(UseCompressedOops, "no compressed ptrs?"); |
99 _narrow_oop._use_implicit_null_checks = use; |
100 _narrow_oop._use_implicit_null_checks = use; |
100 } |
101 } |
101 |
102 |
102 void CompressedOops::set_ptrs_base(address addr) { |
103 bool CompressedOops::is_in(void* addr) { |
103 _narrow_ptrs_base = addr; |
104 return _heap_address_range.contains(addr); |
|
105 } |
|
106 |
|
107 bool CompressedOops::is_in(MemRegion mr) { |
|
108 return _heap_address_range.contains(mr); |
104 } |
109 } |
105 |
110 |
106 CompressedOops::Mode CompressedOops::mode() { |
111 CompressedOops::Mode CompressedOops::mode() { |
107 if (base_disjoint()) { |
112 if (base_disjoint()) { |
108 return DisjointBaseNarrowOop; |
113 return DisjointBaseNarrowOop; |
153 return _narrow_oop._base != NULL && !is_disjoint_heap_base_address(_narrow_oop._base); |
158 return _narrow_oop._base != NULL && !is_disjoint_heap_base_address(_narrow_oop._base); |
154 } |
159 } |
155 |
160 |
156 void CompressedOops::print_mode(outputStream* st) { |
161 void CompressedOops::print_mode(outputStream* st) { |
157 st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", |
162 st->print("Heap address: " PTR_FORMAT ", size: " SIZE_FORMAT " MB", |
158 p2i(Universe::heap()->base()), Universe::heap()->reserved_region().byte_size()/M); |
163 p2i(_heap_address_range.start()), _heap_address_range.byte_size()/M); |
159 |
164 |
160 st->print(", Compressed Oops mode: %s", mode_to_string(mode())); |
165 st->print(", Compressed Oops mode: %s", mode_to_string(mode())); |
161 |
166 |
162 if (base() != 0) { |
167 if (base() != 0) { |
163 st->print(": " PTR_FORMAT, p2i(base())); |
168 st->print(": " PTR_FORMAT, p2i(base())); |