Overview

This is a design document for JDK-8236988 - VM flags: replace ALL_FLAGS macro with a modular design

Goals

Proposal

(Design contribution by Erik Österlund, Stefan Karlsson, Coleen Phillimore)

NOTE:

Before

product(intx, MaxLoopPad, (OptoLoopAlignment-1),                          \
         "Align a loop if padding size in bytes is less or equal to this " \
         "value")                                                          \
         range(0, max_jint)                                                \
                                                                           \
 develop(intx, OptoPrologueNops, 0,                                        \
         "Insert this many extra nop instructions "                        \
         "in the prologue of every nmethod")                               \
         range(0128)                                                     \
                                                                           \
 notproduct(bool, VerifyGraphEdges , false,                                \
         "Verify Bi-directional Edges")                                    \
                                                                           \
 product_pd(intx, InteriorEntryAlignment,                                  \
         "Code alignment for interior entry points "                       \
         "in generated code (in bytes)")                                   \
         constraint(InteriorEntryAlignmentConstraintFunc, AfterErgo)       \
                                                                           \
 diagnostic(bool, StressLCM, false,                                        \
         "Randomize instruction scheduling in LCM")                        \

Declaration Examplec2_globals.hpp (macros such as PRODUCT_FLAG are defined in jvmFlag.hpp)

// PRODUCT_FLAG -- always settable
// DEVELOP_FLAG -- settable only during development and are constant in the PRODUCT version
// NOTPROD_FLAG -- settable only during development and are *not* declared in the PRODUCT version
 
// mode      type     name              def-value     kind
PRODUCT_FLAG(bool,    StressLCM,        false,        None);
DEVELOP_FLAG(intx,    OptoPrologueNops, 0,            Range);
NOTPROD_FLAG(bool,    VerifyGraphEdges, false,        None);
PRODUCT_FLAG(intx,    MaxLoopPad,       (OptoLoopAlignment-1), Range);
 
// def-value is pd_InteriorEntryAlignment (defined in cpu/<arch>/c2_globals_<arch>.hpp
PRODUCT_FLAG_PD(intx, InteriorEntryAlignment,         Constraint);


Macros are expanded to

extern bool StressLCM;
const bool FLAG_DEFVAL_StressLCM = false;
extern ProductFlagNone<bool> FLAG_StressLCM;  // meta-info about the flag
 
extern intx MaxLoopPad;
const intx FLAG_DEFVAL_MaxLoopPad = (OptoLoopAlignment-1);
extern ProductFlagRange<intx> FLAG_MaxLoopPad;
 
extern intx OptoPrologueNops;    // debug build
const intx OptoPrologueNops = 0// product build
 
extern bool VerifyGraphEdges;    // debug build ONLY


Definition Example: c2_globals.cpp (macros such as DEFN_PRODUCT_FLAG are defined jvmFlag.inline.hpp)

DEFN_PRODUCT_FLAG(bool,   StressLCM, None, JVMFlag::DIAGNOSTIC,
                  "Randomize instruction scheduling in LCM");
DEFN_DEVELOP_FLAG(intx,   OptoPrologueNops, Range, 0,
                 "Insert this many extra nop instructions "
                 "in the prologue of every nmethod",
                 /* range */ 0128);
DEFN_PRODUCT_FLAG_PD(intx,   InteriorEntryAlignment, Constraint, 0,
                 "Code alignment for interior entry points "
                 "in generated code (in bytes)",
                 /* constraint */ (void*)InteriorEntryAlignmentConstraintFunc, JVMFlag::AfterErgo);


Macros are expanded to

bool StressLCM = FLAG_DEFVAL_StressLCM;
ProductFlagNone<bool> FLAG_StressLCM(
    JVMFlag::TYPE_bool,
    "StressLCM",                         // name of this flag (for parsing "-XX:+StressLCM")
    (JVMFlag::DIAGNOSTIC | JVMFlag::C2),
    &StressLCM,                          // addr to use for setting flag
    "Randomize .... in LCM");            // help string
 
ProductFlagRange<intx> FLAG_MaxLoopPad(
    JVMFlag::TYPE_intx, "MaxLoopPad",
    (0 | JVMFlag::C2), &MaxLoopPad,
    "Align a loop if padding size ......",
    0, max_jint)                          // range min/max


Iterating over all flags:


struct JVMFlag {
    static JVMFlag* _head;
    JVMFlag* _next;
    ... 
};
 
template <typename T>
class ProductFlagNone : /* a subclass of JVMFlag */ {
    ProductFlagNone(...) {
       /*effectively*/
       this->_next = _head;   // executed as C++ global constructor
       _head = this;
    }};
 
#define JVMFLAG_FOR_EACH(f) \
 for (f = JVMFlag::head(); f != NULL; f = f->next())


Alternatives