-
Bug
-
Resolution: Fixed
-
P4
-
22
-
b24
### Failure analysis ###
Two components in `CodeCache::initialize_heaps` may cause the error:
1. The minimum size (`min_size = os::vm_page_size();`) for profiled and non-profiled code heaps is sometimes not large enough. Specifically, when `profiled_size` and/or `non_profiled_size` are set to `min_size` and `alignment > os::vm_page_size()`, the `align_down` below (from `CodeCache::initialize_heaps`) sets the size to 0.
```
const size_t alignment = MAX2(ps, os::vm_allocation_granularity());
non_nmethod_size = align_up(non_nmethod_size, alignment);
profiled_size = align_down(profiled_size, alignment);
non_profiled_size = align_down(non_profiled_size, alignment);
```
2. The calculation for default code heap sizes does not consider the edge case when `cache_size > non_nmethod_size > cache_size - 2 * min_size`.
### Original report ###
Working onJDK-8316653 exposed a code cache allocation bug. The bug appears for large values of `-XX:NMethodSizeLimit` (requires a debug build) but also depends on the underlying system.
Initially, I encountered the bug on a Windows server 2016 (x64) machine, running `java -XX:NMethodSizeLimit=351658240` (but any value larger than ReservedCodeCacheSize, approximately, will do). Output:
```
Error occurred during initialization of VM
Could not reserve enough space in CodeHeap 'profiled nmethods' (0K)
```
You can also run `java -XX:NMethodSizeLimit=351658240 -XX:+UseTransparentHugePages` to reproduce on Linux.
By careful tweaking of the flag, I managed to also trigger a separate but related edge case and reproduce the bug on my Linux system. Output for `java -XX:NMethodSizeLimit=224001703` on my Linux system:
```
Error occurred during initialization of VM
Could not reserve enough space in CodeHeap 'profiled nmethods' (0K)
```
The expected behavior is to gracefully handle all possible values of the flag and not exit early on VM initialization.
Two components in `CodeCache::initialize_heaps` may cause the error:
1. The minimum size (`min_size = os::vm_page_size();`) for profiled and non-profiled code heaps is sometimes not large enough. Specifically, when `profiled_size` and/or `non_profiled_size` are set to `min_size` and `alignment > os::vm_page_size()`, the `align_down` below (from `CodeCache::initialize_heaps`) sets the size to 0.
```
const size_t alignment = MAX2(ps, os::vm_allocation_granularity());
non_nmethod_size = align_up(non_nmethod_size, alignment);
profiled_size = align_down(profiled_size, alignment);
non_profiled_size = align_down(non_profiled_size, alignment);
```
2. The calculation for default code heap sizes does not consider the edge case when `cache_size > non_nmethod_size > cache_size - 2 * min_size`.
### Original report ###
Working on
Initially, I encountered the bug on a Windows server 2016 (x64) machine, running `java -XX:NMethodSizeLimit=351658240` (but any value larger than ReservedCodeCacheSize, approximately, will do). Output:
```
Error occurred during initialization of VM
Could not reserve enough space in CodeHeap 'profiled nmethods' (0K)
```
You can also run `java -XX:NMethodSizeLimit=351658240 -XX:+UseTransparentHugePages` to reproduce on Linux.
By careful tweaking of the flag, I managed to also trigger a separate but related edge case and reproduce the bug on my Linux system. Output for `java -XX:NMethodSizeLimit=224001703` on my Linux system:
```
Error occurred during initialization of VM
Could not reserve enough space in CodeHeap 'profiled nmethods' (0K)
```
The expected behavior is to gracefully handle all possible values of the flag and not exit early on VM initialization.
- blocks
-
JDK-8316653 Large NMethodSizeLimit triggers assert during C1 code buffer allocation
-
- Resolved
-
- relates to
-
JDK-8320302 compiler/arguments/TestC1Globals.java hits SIGSEGV in ContinuationEntry::set_enter_code
-
- Resolved
-
-
JDK-8320682 [AArch64] C1 compilation fails with "Field too big for insn"
-
- Resolved
-
-
JDK-8316653 Large NMethodSizeLimit triggers assert during C1 code buffer allocation
-
- Resolved
-
(1 links to)