RFR: 8329433: Reduce nmethod header size
Vladimir Kozlov
kvn at openjdk.org
Fri Apr 12 23:19:47 UTC 2024
On Fri, 12 Apr 2024 22:43:15 GMT, Vladimir Kozlov <kvn at openjdk.org> wrote:
> This is part of changes which try to reduce size of `nmethod` and `codeblob` data vs code in CodeCache.
> These changes reduced size of `nmethod` header from 288 to 240 bytes. From 304 to 256 in optimized VM:
>
> Statistics for 1282 bytecoded nmethods for C2:
> total in heap = 5560352 (100%)
> header = 389728 (7.009053%)
>
> vs
>
> Statistics for 1298 bytecoded nmethods for C2:
> total in heap = 5766040 (100%)
> header = 332288 (5.762846%)
>
>
> Several unneeded fields in `nmethod` and `CodeBlob` were removed. Some fields were changed from `int` to `int16_t` with added corresponding asserts to make sure their values are fit into 16 bits.
>
> I did additional cleanup after recent `CompiledMethod` removal.
>
> Tested tier1-7,stress,xcomp and performance testing.
src/hotspot/share/code/codeBlob.cpp line 78:
> 76: #ifdef ASSERT
> 77: void CodeBlob::verify_parameters() {
> 78: assert(is_aligned(_size, oopSize), "unaligned size");
Asserts moved to only caller.
src/hotspot/share/code/codeBlob.cpp line 92:
> 90: CodeBlob::CodeBlob(const char* name, CodeBlobKind kind, int size, int header_size, int relocation_size,
> 91: int content_offset, int code_offset, int frame_complete_offset, int data_offset,
> 92: int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments) :
This was used only by `CompiledMethod` class.
src/hotspot/share/code/codeBlob.cpp line 129:
> 127: }
> 128:
> 129: void CodeBlob::purge() {
Arguments are not used.
src/hotspot/share/code/codeBlob.hpp line 228:
> 226: const ImmutableOopMap* oop_map_for_slot(int slot, address return_address) const;
> 227: const ImmutableOopMap* oop_map_for_return_address(address return_address) const;
> 228: virtual void preserve_callee_argument_oops(frame fr, const RegisterMap* reg_map, OopClosure* f) = 0;
This method is not empty only in `nmethod`. Converted to normal method there and added check` cb->is_nmethod()` in call sites.
src/hotspot/share/code/debugInfoRec.cpp line 251:
> 249: void print() {
> 250: tty->print_cr("Debug Data Chunks: %d, shared %d, non-SP's elided %d",
> 251: chunks_queried, chunks_shared, chunks_elided);
`chunks_reshared` is not used.
src/hotspot/share/code/dependencies.cpp line 391:
> 389: address end = nm->dependencies_end();
> 390: guarantee(end - beg >= (ptrdiff_t) size_in_bytes(), "bad sizing");
> 391: (void)memcpy(beg, content_bytes(), size_in_bytes());
To avoid false error reported by `GCC` only during product VM build for `linux-x64`:
inlined from 'void Dependencies::copy_to(nmethod*)' at src/hotspot/share/code/dependencies.cpp:391:23:
src/hotspot/cpu/x86/copy_x86.hpp:110:18: error: writing 8 bytes into a region of size 0 [-Werror=stringop-overflow=]
110 | case 8: to[7] = from[7];
| ~~~~~~^~~~~~~~~
src/hotspot/share/code/nmethod.cpp line 142:
> 140: uint size_gt_32k;
> 141: int size_max;
> 142:
Diagnostic code leftover from my work on [#18554](https://github.com/openjdk/jdk/pull/18554)
src/hotspot/share/code/nmethod.cpp line 1486:
> 1484: }
> 1485: #endif
> 1486: dependencies->copy_to(this);
Missed to revert back this change.
src/hotspot/share/code/nmethod.hpp line 208:
> 206: address _osr_entry_point; // entry point for on stack replacement
> 207: uint16_t _entry_offset; // entry point with class check
> 208: uint16_t _verified_entry_offset; // entry point without class check
Changed direct entry pointers (8 bytes each in 64-bit VM) to offsets (2 bytes) to `code_begin()`.
src/hotspot/share/code/nmethod.hpp line 234:
> 232: int _scopes_data_offset;
> 233: int _handler_table_offset;
> 234: int _nul_chk_table_offset;
Changed data sections offsets base from `header_begin()` to `data_begin()`.
Note, `ScopesPcs` and `ScopesData` data could be > 64Kb.
src/hotspot/share/code/nmethod.hpp line 237:
> 235: #if INCLUDE_JVMCI
> 236: int _speculations_offset;
> 237: int _jvmci_data_offset;
"Wasted space" when Graal is not used. May be address in future changes.
src/hotspot/share/code/nmethod.hpp line 274:
> 272: // used by jvmti to track if an event has been posted for this nmethod.
> 273: bool _load_reported;
> 274:
Converted to bit mask.
src/hotspot/share/code/nmethod.hpp line 724:
> 722: ExceptionCache* exception_cache() const { return _exception_cache; }
> 723: ExceptionCache* exception_cache_acquire() const;
> 724: void set_exception_cache(ExceptionCache *ec) { _exception_cache = ec; }
Not used.
src/hotspot/share/code/nmethod.hpp line 800:
> 798:
> 799: // Deallocate this nmethod - called by the GC
> 800: void purge(bool unregister_nmethod);
Only `unregister_nmethod` is used by code.
src/hotspot/share/memory/heap.hpp line 42:
> 40: struct Header {
> 41: uint32_t _length; // the length in segments
> 42: bool _used; // Used bit
The `Header` size is aligned up 8 bytes. With `size_t length;` the aligned size will be 16 bytes.
`HeapBlock/Header` is used by CodeCache only which has 2Gb limit. The `length` counts number of segments which smallest size (`CodeCacheSegmentSize`) is 64 bytes. 32 bits is enough to cover it.
src/hotspot/share/runtime/frame.cpp line 979:
> 977: if (reg_map->include_argument_oops() && _cb->is_nmethod()) {
> 978: // Only nmethod preserves outgoing arguments at call.
> 979: _cb->as_nmethod()->preserve_callee_argument_oops(*this, reg_map, f);
Only `nmethod` preserves arguments oops.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563303217
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563302110
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563303989
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563307999
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563310748
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563311696
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563313116
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563334063
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563317344
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563320172
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563321008
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563321437
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563321900
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563322669
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563331968
PR Review Comment: https://git.openjdk.org/jdk/pull/18768#discussion_r1563332602
More information about the hotspot-dev
mailing list