--- old/src/jdk.jcmd/share/classes/sun/tools/jstat/ColumnFormat.java 2018-03-27 23:39:29.649277248 +0900 +++ new/src/jdk.jcmd/share/classes/sun/tools/jstat/ColumnFormat.java 2018-03-27 23:39:29.298276150 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,7 @@ private String format; private String header; private Expression expression; + private boolean required = false; private Object previousValue; public ColumnFormat(int number) { @@ -71,6 +72,9 @@ // the raw data. format="0"; } + + // Adjust required flag + expression.setRequired(required); } public void setWidth(int width) { @@ -121,6 +125,14 @@ this.expression = e; } + public void setRequired(boolean r) { + this.required = r; + } + + public boolean isRequired() { + return this.required; + } + public void setPreviousValue(Object o) { this.previousValue = o; } @@ -141,7 +153,8 @@ System.out.println(indent + indentAmount + "name=" + name + ";data=" + expression.toString() + ";header=" + header + ";format=" + format + ";width=" + width - + ";scale=" + scale.toString() + ";align=" + align.toString()); + + ";scale=" + scale.toString() + ";align=" + align.toString() + + ";required=" + required); for (Iterator i = children.iterator(); i.hasNext(); /* empty */) { OptionFormat of = i.next(); --- old/src/jdk.jcmd/share/classes/sun/tools/jstat/Expression.java 2018-03-27 23:39:30.435279706 +0900 +++ new/src/jdk.jcmd/share/classes/sun/tools/jstat/Expression.java 2018-03-27 23:39:30.064278546 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ private Expression right; private Operator operator; private int ordinal = nextOrdinal++; + private boolean required = false; Expression() { if (debug) { @@ -52,6 +53,7 @@ System.out.println("Setting left on " + ordinal + " to " + left); } this.left = left; + this.left.setRequired(required); } Expression getLeft() { @@ -63,6 +65,7 @@ System.out.println("Setting right on " + ordinal + " to " + right); } this.right = right; + this.right.setRequired(required); } Expression getRight() { @@ -80,6 +83,20 @@ return operator; } + void setRequired(boolean r) { + this.required = r; + if (left != null) { + left.setRequired(required); + } + if (right != null) { + right.setRequired(required); + } + } + + boolean isRequired() { + return required; + } + public String toString() { StringBuilder b = new StringBuilder(); b.append('('); --- old/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java 2018-03-27 23:39:31.182282043 +0900 +++ new/src/jdk.jcmd/share/classes/sun/tools/jstat/ExpressionResolver.java 2018-03-27 23:39:30.811280883 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,7 +73,7 @@ System.err.println("Warning: Unresolved Symbol: " + id.getName() + " substituted NaN"); } - return new Literal(Double.valueOf(Double.NaN)); + return new Literal(e.isRequired() ? 0.0d : Double.NaN); } if (m.getVariability() == Variability.CONSTANT) { if (debug) { @@ -131,7 +131,9 @@ + " (right = " + rn.doubleValue() + ")" + " to literal value " + result); } - return new Literal(Double.valueOf(result)); + var literal = new Literal(result); + literal.setRequired(e.isRequired()); + return literal; } } --- old/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java 2018-03-27 23:39:32.007284623 +0900 +++ new/src/jdk.jcmd/share/classes/sun/tools/jstat/Parser.java 2018-03-27 23:39:31.624283425 +0900 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,13 +60,15 @@ private static final String FORMAT = "format"; private static final String ALIGN = "align"; private static final String SCALE = "scale"; + private static final String REQUIRED = "required"; private static final String START = OPTION; private static final Set scaleKeyWords = Scale.keySet(); private static final Set alignKeyWords = Alignment.keySet(); + private static final Set boolKeyWords = Set.of("true", "false"); private static String[] otherKeyWords = { - OPTION, COLUMN, DATA, HEADER, WIDTH, FORMAT, ALIGN, SCALE + OPTION, COLUMN, DATA, HEADER, WIDTH, FORMAT, ALIGN, SCALE, REQUIRED }; private static char[] infixOps = { @@ -445,6 +447,16 @@ } /** + * requiredstmt -> 'required' expression + */ + private void requiredStmt(ColumnFormat cf) throws ParserException, IOException { + match(REQUIRED); + Token t = matchOne(boolKeyWords); + cf.setRequired(Boolean.parseBoolean(t.sval)); + log(pdebug, "Parsed: required -> " + cf.isRequired()); + } + + /** * statementlist -> optionalstmt statementlist * optionalstmt -> 'data' expression * 'header' quotedstring @@ -452,6 +464,7 @@ * 'format' formatstring * 'align' alignspec * 'scale' scalespec + * 'required' boolean */ private void statementList(ColumnFormat cf) throws ParserException, IOException { @@ -472,6 +485,8 @@ alignStmt(cf); } else if (lookahead.sval.compareTo(SCALE) == 0) { scaleStmt(cf); + } else if (lookahead.sval.compareTo(REQUIRED) == 0) { + requiredStmt(cf); } else { return; } --- old/src/jdk.jcmd/share/classes/sun/tools/jstat/resources/jstat_options 2018-03-27 23:39:32.749286944 +0900 +++ new/src/jdk.jcmd/share/classes/sun/tools/jstat/resources/jstat_options 2018-03-27 23:39:32.397285843 +0900 @@ -277,6 +277,7 @@ width 8 scale sec format "0.000" + required true } } @@ -537,6 +538,7 @@ width 8 scale sec format "0.000" + required true } column { header "^LGCC" /* Last GC Cause */ @@ -835,6 +837,7 @@ width 8 scale sec format "0.000" + required true } } @@ -917,6 +920,7 @@ width 8 scale sec format "0.000" + required true } } @@ -1015,6 +1019,7 @@ width 8 scale sec format "0.000" + required true } } @@ -1121,6 +1126,7 @@ width 8 scale sec format "0.000" + required true } } --- old/test/hotspot/jtreg/ProblemList.txt 2018-03-27 23:39:33.862290426 +0900 +++ new/test/hotspot/jtreg/ProblemList.txt 2018-03-27 23:39:33.177288283 +0900 @@ -81,11 +81,6 @@ serviceability/sa/TestRevPtrsForInvokeDynamic.java 8191270 generic-all serviceability/sa/sadebugd/SADebugDTest.java 8163805 generic-all -serviceability/tmtools/jstat/GcTest01.java 8199519 generic-all -serviceability/tmtools/jstat/GcTest02.java 8199519 generic-all -serviceability/tmtools/jstat/GcCauseTest01.java 8199519 generic-all -serviceability/tmtools/jstat/GcCauseTest02.java 8199519 generic-all -serviceability/tmtools/jstat/GcCauseTest03.java 8199519 generic-all ############################################################################# --- old/test/hotspot/jtreg/serviceability/tmtools/jstat/utils/JstatGcCauseResults.java 2018-03-27 23:39:34.893293651 +0900 +++ new/test/hotspot/jtreg/serviceability/tmtools/jstat/utils/JstatGcCauseResults.java 2018-03-27 23:39:34.496292409 +0900 @@ -74,10 +74,18 @@ assertThat(GCT >= 0, "Incorrect time value for GCT"); assertThat(GCT >= YGCT, "GCT < YGCT (total garbage collection time < young generation garbage collection time)"); - int CGC = getIntValue("CGC"); - float CGCT = getFloatValue("CGCT"); - assertThat(CGCT >= 0, "Incorrect time value for CGCT"); + int CGC = 0; + float CGCT = 0.0f; + try { + CGC = getIntValue("CGC"); + } catch (NumberFormatException e) { + if (!e.getMessage().equals("Unparseable number: \"-\"")) { + throw e; + } + } if (CGC > 0) { + CGCT = getFloatValue("CGCT"); + assertThat(CGCT >= 0, "Incorrect time value for CGCT"); assertThat(CGCT > 0, "Number of concurrent GC events is " + CGC + ", but CGCT is 0"); } --- old/test/hotspot/jtreg/serviceability/tmtools/jstat/utils/JstatGcResults.java 2018-03-27 23:39:35.848296638 +0900 +++ new/test/hotspot/jtreg/serviceability/tmtools/jstat/utils/JstatGcResults.java 2018-03-27 23:39:35.311294958 +0900 @@ -103,10 +103,18 @@ assertThat(GCT >= 0, "Incorrect time value for GCT"); assertThat(GCT >= YGCT, "GCT < YGCT (total garbage collection time < young generation garbage collection time)"); - int CGC = getIntValue("CGC"); - float CGCT = getFloatValue("CGCT"); - assertThat(CGCT >= 0, "Incorrect time value for CGCT"); + int CGC = 0; + float CGCT = 0.0f; + try { + CGC = getIntValue("CGC"); + } catch (NumberFormatException e) { + if (!e.getMessage().equals("Unparseable number: \"-\"")) { + throw e; + } + } if (CGC > 0) { + CGCT = getFloatValue("CGCT"); + assertThat(CGCT >= 0, "Incorrect time value for CGCT"); assertThat(CGCT > 0, "Number of concurrent GC events is " + CGC + ", but CGCT is 0"); }