RFR: 8288477: nmethod header size reduction [v4]

Vladimir Kozlov kvn at openjdk.org
Thu Jul 28 17:50:49 UTC 2022


On Thu, 28 Jul 2022 09:39:52 GMT, Boris Ulasevich <bulasevich at openjdk.org> wrote:

>> Each compiled method contains an nmethod header. In trivial case, the header takes up half the method payload: ~350 bytes. Over time, the header gets bigger. With this change, I suggest sorting the header data fields from largest to smallest to minimize header paddings, and using one byte for the CompilerType and CompLevel values.
>> 
>> Cleanup work: apply CompLevel type where applicable.
>> 
>> The change tested with jtreg tier1-3, :hotspot_compiler :hotspot_gc :hotspot_serviceability :hotspot_runtime
>> 
>> Renaissance benchmarks shows no performance regressions on x86 and aarch.
>> 
>> BEFORE:
>> 
>> (gdb) ptype /o CodeBlob
>> /* offset    |  size */  type = class CodeBlob {
>> /*    8      |     4 */    const CompilerType _type;    <<<<
>> /*   12      |     4 */    int _size;
>> /*   16      |     4 */    int _header_size;
>> /*   20      |     4 */    int _frame_complete_offset;
>> /*   24      |     4 */    int _data_offset;
>> /*   28      |     4 */    int _frame_size;
>> /*   32      |     8 */    address _code_begin;
>> /*   40      |     8 */    address _code_end;
>> /*   48      |     8 */    address _content_begin;
>> /*   56      |     8 */    address _data_end;
>> /*   64      |     8 */    address _relocation_begin;
>> /*   72      |     8 */    address _relocation_end;
>> /*   80      |     8 */    ImmutableOopMapSet *_oop_maps;
>> /*   88      |     1 */    bool _caller_must_gc_arguments;
>> /*   89      |     1 */    bool _is_compiled;
>> /* XXX  6-byte hole  */
>> /*   96      |     8 */    const char *_name;
>> /*  104      |     8 */    class AsmRemarks {
>> /*  104      |     8 */        AsmRemarkCollection *_remarks;
>>                            } _asm_remarks;
>> /*  112      |     8 */    class DbgStrings {
>> /*  112      |     8 */        DbgStringCollection *_strings;
>>                            } _dbg_strings;
>> 
>>                            /* total size (bytes):  120 */
>>                          }
>> 
>> AFTER:
>> 
>> (gdb) ptype /o CodeBlob
>> /* offset    |  size */  type = class CodeBlob {
>>                          protected:
>> /*    8      |     8 */    address _code_begin;
>> /*   16      |     8 */    address _code_end;
>> /*   24      |     8 */    address _content_begin;
>> /*   32      |     8 */    address _data_end;
>> /*   40      |     8 */    address _relocation_begin;
>> /*   48      |     8 */    address _relocation_end;
>> /*   56      |     8 */    ImmutableOopMapSet *_oop_maps;
>> /*   64      |     8 */    const char *_name;
>> /*   72      |     4 */    int _size;
>> /*   76      |     4 */    int _header_size;
>> /*   80      |     4 */    int _frame_complete_offset;
>> /*   84      |     4 */    int _data_offset;
>> /*   88      |     4 */    int _frame_size;
>> /*   92      |     1 */    bool _caller_must_gc_arguments;
>> /*   93      |     1 */    bool _is_compiled;
>> /*   94      |     1 */    const CompilerType _type;    <<<<
>> /* XXX  1-byte hole  */
>> /*   96      |     8 */    class AsmRemarks {
>> /*   96      |     8 */        AsmRemarkCollection *_remarks;
>>                            } _asm_remarks;
>> /*  104      |     8 */    class DbgStrings {
>> /*  104      |     8 */        DbgStringCollection *_strings;
>>                            } _dbg_strings;
>> 
>>                            /* total size (bytes):  112 */
>>                          }
>> 
>> BEFORE:
>> 
>> (gdb) ptype /o nmethod
>> /* offset    |  size */  type = class nmethod : public CompiledMethod {
>>                          private:
>> /*  208      |     4 */    int _entry_bci;
>> /* XXX  4-byte hole  */
>> /*  216      |     8 */    uint64_t _gc_epoch;
>> /*  224      |     8 */    nmethod *_osr_link;
>> /*  232      |     8 */    nmethod::oops_do_mark_link * volatile _oops_do_mark_link;
>> /*  240      |     8 */    address _entry_point;
>> /*  248      |     8 */    address _verified_entry_point;
>> /*  256      |     8 */    address _osr_entry_point;
>> /*  264      |     4 */    int _exception_offset;
>> /*  268      |     4 */    int _unwind_handler_offset;
>> /*  272      |     4 */    int _consts_offset;
>> /*  276      |     4 */    int _stub_offset;
>> /*  280      |     4 */    int _oops_offset;
>> /*  284      |     4 */    int _metadata_offset;
>> /*  288      |     4 */    int _scopes_data_offset;
>> /*  292      |     4 */    int _scopes_pcs_offset;
>> /*  296      |     4 */    int _dependencies_offset;
>> /*  300      |     4 */    int _handler_table_offset;
>> /*  304      |     4 */    int _nul_chk_table_offset;
>> /*  308      |     4 */    int _speculations_offset;
>> /*  312      |     4 */    int _jvmci_data_offset;
>> /*  316      |     4 */    int _nmethod_end_offset;
>> /*  320      |     4 */    int _orig_pc_offset;
>> /*  324      |     4 */    int _compile_id;
>> /*  328      |     4 */    int _comp_level;    <<<<
>> /*  332      |     1 */    bool _has_flushed_dependencies;
>> /*  333      |     1 */    bool _unload_reported;
>> /*  334      |     1 */    bool _load_reported;
>> /*  335      |     1 */    volatile signed char _state;
>> /*  336      |     1 */    bool _oops_are_stale;
>> /* XXX  3-byte hole  */
>> /*  340      |     4 */    RTMState _rtm_state;
>> /*  344      |     4 */    volatile jint _lock_count;
>> /* XXX  4-byte hole  */
>> /*  352      |     8 */    volatile int64_t _stack_traversal_mark;
>> /*  360      |     4 */    int _hotness_counter;
>> /*  364      |     1 */    volatile uint8_t _is_unloading_state;
>> /* XXX  3-byte hole  */
>> /*  368      |     4 */    ByteSize _native_receiver_sp_offset;
>> /*  372      |     4 */    ByteSize _native_basic_lock_sp_offset;
>> 
>>                            /* total size (bytes):  376 */
>>                          }						 
>> 
>> AFTER:
>> 
>> (gdb) ptype /o nmethod
>> /* offset    |  size */  type = class nmethod : public CompiledMethod {
>> /*  200      |     8 */    uint64_t _gc_epoch;
>> /*  208      |     8 */    volatile int64_t _stack_traversal_mark;
>> /*  216      |     8 */    nmethod *_osr_link;
>> /*  224      |     8 */    nmethod::oops_do_mark_link * volatile _oops_do_mark_link;
>> /*  232      |     8 */    address _entry_point;
>> /*  240      |     8 */    address _verified_entry_point;
>> /*  248      |     8 */    address _osr_entry_point;
>> /*  256      |     4 */    int _entry_bci;
>> /*  260      |     4 */    int _exception_offset;
>> /*  264      |     4 */    int _unwind_handler_offset;
>> /*  268      |     4 */    int _consts_offset;
>> /*  272      |     4 */    int _stub_offset;
>> /*  276      |     4 */    int _oops_offset;
>> /*  280      |     4 */    int _metadata_offset;
>> /*  284      |     4 */    int _scopes_data_offset;
>> /*  288      |     4 */    int _scopes_pcs_offset;
>> /*  292      |     4 */    int _dependencies_offset;
>> /*  296      |     4 */    int _handler_table_offset;
>> /*  300      |     4 */    int _nul_chk_table_offset;
>> /*  304      |     4 */    int _speculations_offset;
>> /*  308      |     4 */    int _jvmci_data_offset;
>> /*  312      |     4 */    int _nmethod_end_offset;
>> /*  316      |     4 */    int _orig_pc_offset;
>> /*  320      |     4 */    int _compile_id;
>> /*  324      |     4 */    RTMState _rtm_state;
>> /*  328      |     4 */    volatile jint _lock_count;
>> /*  332      |     4 */    int _hotness_counter;
>> /*  336      |     4 */    ByteSize _native_receiver_sp_offset;
>> /*  340      |     4 */    ByteSize _native_basic_lock_sp_offset;
>> /*  344      |     1 */    CompLevel _comp_level;    <<<<
>> /*  345      |     1 */    volatile uint8_t _is_unloading_state;
>> /*  346      |     1 */    bool _has_flushed_dependencies;
>> /*  347      |     1 */    bool _unload_reported;
>> /*  348      |     1 */    bool _load_reported;
>> /*  349      |     1 */    volatile signed char _state;
>> /*  350      |     1 */    bool _oops_are_stale;
>> 
>>                            /* total size (bytes):  352 */
>>                          }
>
> Boris Ulasevich has updated the pull request incrementally with one additional commit since the last revision:
> 
>   declare CompLevel properly in vmStructs

Marked as reviewed by kvn (Reviewer).

-------------

PR: https://git.openjdk.org/jdk/pull/9165


More information about the hotspot-dev mailing list