- Loading...
This document describes ....Latest Webrev: http://cr.openjdk.java.net/~iklam/jdk16/8243208-cleanup-jvmflag-impl.v00/
...
| Code Block |
|---|
#define RUNTIME_FLAGS(develop, \
develop_pd, \
product, \
product_pd, \
/* REMOVED diagnostic, */\
/* REMOVED diagnostic_pd, */ \
/* REMOVED experimental, */\
notproduct, \
/* REMOVED manageable, */ \
/* REMOVED product_rw, */\
/* REMOVED lp64_product, */\
range, \
constraint) \
.....
develop(bool, CleanChunkPoolAsync, true, /* no attr */ \
"Clean the chunk pool asynchronously") \
\
product(uint, HandshakeTimeout, 0, /* attr= */DIAGNOSTIC, \
"If nonzero set a timeout in milliseconds for handshakes") \
\
product(bool, AlwaysSafeConstructors, false, /* attr= */ EXPERIMENTAL, \
"Force safe construction, as if all fields are final.") .... |
The flags metadata is defined using overloaded constructors (around lin 679 of jvmFlag.cpp)
| Code Block |
|---|
constexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name,
size_t name_len, void* addr, int extra_flags,
int flagsattrs, const char* doc) :
_type(type), _name(name), _addr(addr), NOT_PRODUCT_ARG(COMMA _doc(doc)) {}
_flags(Flags(flags | extra_flags | DEFAULT | flag_group(flag_enum))), _name_len(name_len) {}
constexpr JVMFlagconstexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name,
size_t name_len, void* addr, int extra_flags,
const char* const char* doc) :
JVMFlag(flag_enum, type, name, name_len, addr, extra_flags, /*flagsattrs*/0, doc) {}
....
#define DEVELOP_FLAG_INIT( type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), ...snip..., __VA_ARGS__),
#define DEVELOP_FLAG_INIT_PD(type, name, ...) JVMFlag(FLAG_MEMBER_ENUM(name), ...snip..., __VA_ARGS__),
...snip....
static JVMFlag flagTable[1 + NUM_JVMFlagsEnum + 1] = {
......
ALL_FLAGS(DEVELOP_FLAG_INIT,
DEVELOP_FLAG_INIT_PD,
PRODUCT_FLAG_INIT,
PRODUCT_FLAG_INIT_PD,
NOTPROD_FLAG_INIT,
IGNORE_RANGE,
IGNORE_CONSTRAINT)
....
// NOTE: ALL_FLAGS() calls RUNTIME_FLAGS() |
...
The new code (see here for webrev):
If your constexpr's are too complex, the C compiler may decide to generate runtime code (instead of generating the data that your constexpr's compute). A good way to A good way to check is to build the .o with something like "gcc -save-temps" and look at the .s file. Here's an example of jvmFlagLimit.s. The following is the C++ global constructor section. It's very small, so it's good.
| Code Block |
|---|
_GLOBAL__sub_I_jvmFlagLimit.cpp:
.LFB6450:
.cfi_startproc
pxor %xmm0, %xmm0
movaps %xmm0, 1776+_ZL14flagLimitTable(%rip)
movaps %xmm0, 1792+_ZL14flagLimitTable(%rip)
movaps %xmm0, 1808+_ZL14flagLimitTable(%rip)
movaps %xmm0, 1824+_ZL14flagLimitTable(%rip)
ret
.cfi_endproc
.LFE6450:
.size _GLOBAL__sub_I_jvmFlagLimit.cpp, .-_GLOBAL__sub_I_jvmFlagLimit.cpp
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_jvmFlagLimit.cpp |
The content of the flagLimitTable is completely determined at build time (except for the 4 slots above which are null'ed at runtime. I don't know why.
You can see that the content of the flagLimitTable is also completely determined at build time (it's in the "ro" section):
| Code Block |
|---|
.section .data.rel.ro.local,"aw"
.align 32
.type _ZL14flagLimitTable, @object
.size _ZL14flagLimitTable, 9728
_ZL14flagLimitTable: |
| Code Block |
.section .data.rel.local .align 32 .type _ZL14flagLimitTable, @object .size _ZL14flagLimitTable, 9728 _ZL14flagLimitTable: .quad 0 .quad 0 .quad 0 .quad _ZL28limit_ObjectAlignmentInBytes .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 .quad 0 .quad _ZL18limit_JVMCIThreads0 .quad _ZL22limitZL28limit_JVMCIHostThreadsObjectAlignmentInBytes .quad _ZL24limit_JVMCIEventLogLevel0 .quad _ZL21limit_JVMCITraceLevel0 .quad _ZL22limit_JVMCICounterSize0 .quad 0 .quad 0 .quad _ZL27limit_JVMCINMethodSizeLimit0 .quad 0 .quad 0_ZL18limit_JVMCIThreads .quad 0 .quad 0 _ZL22limit_JVMCIHostThreads .... |