diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 5c5b6f7ebe58d..a50c394d2146e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -105,7 +105,7 @@ class ShenandoahPretouchHeapTask : public WorkerTask { ShenandoahHeapRegion* r = _regions.next(); while (r != nullptr) { if (r->is_committed()) { - os::pretouch_memory(r->bottom(), r->end(), _page_size); + os::pretouch_memory_unsafe(r->bottom(), r->end(), _page_size); } r = _regions.next(); } @@ -133,7 +133,7 @@ class ShenandoahPretouchBitmapTask : public WorkerTask { assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); if (r->is_committed()) { - os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _page_size); + os::pretouch_memory_unsafe(_bitmap_base + start, _bitmap_base + end, _page_size); } r = _regions.next(); @@ -2352,7 +2352,7 @@ bool ShenandoahHeap::commit_bitmap_slice(ShenandoahHeapRegion* r) { } if (AlwaysPreTouch) { - os::pretouch_memory(start, start + len, _pretouch_bitmap_page_size); + os::pretouch_memory_unsafe(start, start + len, _pretouch_bitmap_page_size); } return true; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index 8a94b20670a9f..faa942fe73a01 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -627,7 +627,7 @@ void ShenandoahHeapRegion::do_commit() { report_java_out_of_memory("Unable to commit bitmaps for region"); } if (AlwaysPreTouch) { - os::pretouch_memory(bottom(), end(), heap->pretouch_heap_page_size()); + os::pretouch_memory_unsafe(bottom(), end(), heap->pretouch_heap_page_size()); } heap->increase_committed(ShenandoahHeapRegion::region_size_bytes()); } diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index 6cb57e9dcb6e5..217e6120dc396 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -2228,6 +2228,21 @@ void os::pretouch_memory(void* start, void* end, size_t page_size) { } } +void os::pretouch_memory_unsafe(void* start, void* end, size_t page_size) { + assert(start <= end, "invalid range: " PTR_FORMAT " -> " PTR_FORMAT, p2i(start), p2i(end)); + assert(is_power_of_2(page_size), "page size misaligned: %zu", page_size); + assert(page_size >= sizeof(int), "page size too small: %zu", page_size); + if (start < end) { + // This is not a concurrent safe pretouch, so we have to stay within the range. + const size_t pd_page_size = pd_pretouch_memory(start, end, page_size); + if (pd_page_size > 0) { + for (volatile char *p = (char*)start; p < (char*)end; p += page_size) { + *p = 0; + } + } + } +} + char* os::map_memory_to_file(size_t bytes, int file_desc, MEMFLAGS flag) { // Could have called pd_reserve_memory() followed by replace_existing_mapping_with_file_mapping(), // but AIX may use SHM in which case its more trouble to detach the segment and remap memory to the file. diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 63ea172166729..b26609356a414 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -495,6 +495,11 @@ class os: AllStatic { // Other threads may use the memory range concurrently with pretouch. static void pretouch_memory(void* start, void* end, size_t page_size = vm_page_size()); + // Same as pretouch_memory, but unsafe: writes into the pretouched memory, + // and so could only be used when callers are sure the memory does not carry + // anything useful. + static void pretouch_memory_unsafe(void* start, void* end, size_t page_size = vm_page_size()); + enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; static bool protect_memory(char* addr, size_t bytes, ProtType prot, bool is_committed = true);