• Home
    • View
    • Login
    This page
    • Normal
    • Export PDF
    • Page Information

    Loading...
  1. Dashboard
  2. Undefined Space
  3. HotSpot
  4. HotSpot Command-Line Flags Overhaul - Design Doc

HotSpot Command-Line Flags Overhaul - Design Doc

  • Created by Ioi Lam, last modified on Apr 08, 2020

Overview

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

  • Lots of files have changed. Please read this document first before heading over to the webrev
  • Preliminary webrev: http://cr.openjdk.java.net/~iklam/jdk15/vm_flags_overhaul.008/

Goals

  • Improve the implementation of JVM command-line flags (such as -XX:+UseCompressedOops)

  • Break up monolithic globals.hpp

    • No need to include all flags for GC, C1, C2, JVMCI, .....

    • Before:
      • #include "runtime/globals.hpp" + globals_shared.hpp  = declare all possible flags
    • After:
      • #include "gc/z/z_globals.hpp" (see also gc/z/z_globals.flags.hpp)
    • Future: subdivide globals.hpp into individual components:
      • (Not in this patch, but possible)
      • #include "memory/metaspaceShared_globals.hpp" (just flags related to CDS).
  • Remove complex macros for flags manipulation
    • Example: jvmFlags.cpp, globals_extension.hpp, jvmFlagRangeList.cpp
  • Hotspot command line switches should have multiple type attributes
    • See JDK-7123237
      • E.g., one can have a "manageable" switch and an "experimental" switch, but not a "manageable_experimental" switch.

  • Templatize duplicated flag processing code:
    • E.g., .(link to attachment)
  • Speed up range/constraint checking for flags
    • Avoid linear search for every -XX:NumericFlag=value argument in the command-line (jvmFlagRangeList.cpp)

Proposal

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

NOTE:

  • Most of the current patch is generated by a script, so it's easy to change the design
  • Summary of changes: 14748 lines changed: 6837 ins; 6204 del; 1707 mod; 33867 unchg

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(0, 128)                                                     \
                                                                           \
 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 Example: c2_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 */ 0, 128);
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

  • Declare flags in template files with custom syntax
    • flag type = bool, name = UseCompressedOops, default = false, help = "Use 32-bit object references in 64-bit VM.", type = product | lp64;

    • Or XML, or ....

  • Auto-generation of header files from templates

  • Pros:
    • Can generate more compact code that current proposal (see below)
    • Flags can be pre-sorted, hashed, etc
  • Cons:
    • More complex build (nowhere as bad as .ad files, but affects all developers, not just JIT compiler geeks)
    • Not understood by IDE tools
Overview
Content Tools
ThemeBuilder
  • No labels

Terms of Use
• License: GPLv2
• Privacy • Trademarks • Contact Us

Powered by a free Atlassian Confluence Open Source Project License granted to https://www.atlassian.com/software/views/opensource-community-additional-license-offer. Evaluate Confluence today.

  • Kolekti ThemeBuilder Powered by Atlassian Confluence 8.5.21
  • Kolekti ThemeBuilder printed.by.atlassian.confluence
  • Report a bug
  • Atlassian News
Atlassian
Kolekti ThemeBuilder EngineAtlassian Confluence
{"serverDuration": 210, "requestCorrelationId": "0f916703672d73c7"}