Skip to content

Commit d7676c3

Browse files
committed
8354508: JFR: Strengthen metadata checks for labels
Reviewed-by: shade
1 parent 81d4c80 commit d7676c3

File tree

2 files changed

+72
-31
lines changed

2 files changed

+72
-31
lines changed

src/hotspot/share/jfr/metadata/metadata.xml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -453,10 +453,10 @@
453453
<Field type="ulong" contentType="bytes" name="regionEndWaste" label="Region End Wasted" description="Total memory wasted at the end of regions due to refill" />
454454
<Field type="uint" name="regionsRefilled" label="Region Refills" description="Number of regions refilled" />
455455
<Field type="ulong" name="numPlabsFilled" label="PLAB Fills" description="Number of PLABs filled" />
456-
<Field type="ulong" contentType="bytes" name="directAllocated" label="Allocated (direct)" description="Total memory allocated using direct allocation outside of PLABs" />
457-
<Field type="ulong" name="numDirectAllocated" label="Direct allocations" description="Number of direct allocations" />
458-
<Field type="ulong" contentType="bytes" name="failureUsed" label="Used (failure)" description="Total memory occupied by objects in regions where evacuation failed" />
459-
<Field type="ulong" contentType="bytes" name="failureWaste" label="Wasted (failure)" description="Total memory left unused in regions where evacuation failed" />
456+
<Field type="ulong" contentType="bytes" name="directAllocated" label="Allocated (Direct)" description="Total memory allocated using direct allocation outside of PLABs" />
457+
<Field type="ulong" name="numDirectAllocated" label="Direct Allocations" description="Number of direct allocations" />
458+
<Field type="ulong" contentType="bytes" name="failureUsed" label="Used (Failure)" description="Total memory occupied by objects in regions where evacuation failed" />
459+
<Field type="ulong" contentType="bytes" name="failureWaste" label="Wasted (Failure)" description="Total memory left unused in regions where evacuation failed" />
460460
</Type>
461461

462462
<Event name="G1EvacuationYoungStatistics" category="Java Virtual Machine, GC, Detailed" label="G1 Evacuation Statistics for Young" startTime="false"
@@ -523,7 +523,7 @@
523523
<Event name="PromotionFailed" category="Java Virtual Machine, GC, Detailed" label="Promotion Failed" startTime="false" description="Promotion of an object failed">
524524
<Field type="uint" name="gcId" label="GC Identifier" relation="GcId" />
525525
<Field type="CopyFailed" struct="true" name="promotionFailed" label="Promotion Failed Data" />
526-
<Field type="Thread" name="thread" label="Running thread" />
526+
<Field type="Thread" name="thread" label="Running Thread" />
527527
</Event>
528528

529529
<Event name="EvacuationFailed" category="Java Virtual Machine, GC, Detailed" label="Evacuation Failed" startTime="false" description="Evacuation of an object failed">
@@ -1007,7 +1007,7 @@
10071007
<Field type="ulong" contentType="bytes" name="nmethodsSize" label="Compilation Resulting Size" />
10081008
<Field type="ulong" contentType="bytes" name="nmethodCodeSize" label="Compilation Resulting Code Size" />
10091009
<Field type="long" contentType="millis" name="peakTimeSpent" label="Peak Time" />
1010-
<Field type="long" contentType="millis" name="totalTimeSpent" label="Total time" />
1010+
<Field type="long" contentType="millis" name="totalTimeSpent" label="Total Time" />
10111011
</Event>
10121012

10131013
<Event name="CompilerConfiguration" category="Java Virtual Machine, Compiler" label="Compiler Configuration" thread="false" period="endChunk" startTime="false">
@@ -1030,10 +1030,10 @@
10301030
<Event name="CodeCacheConfiguration" category="Java Virtual Machine, Code Cache" label="Code Cache Configuration" thread="false" period="endChunk" startTime="false">
10311031
<Field type="ulong" contentType="bytes" name="initialSize" label="Initial Size" />
10321032
<Field type="ulong" contentType="bytes" name="reservedSize" label="Reserved Size" />
1033-
<Field type="ulong" contentType="bytes" name="nonNMethodSize" label="Non-nmethod Size" />
1033+
<Field type="ulong" contentType="bytes" name="nonNMethodSize" label="Non-Nmethod Size" />
10341034
<Field type="ulong" contentType="bytes" name="profiledSize" label="Profiled Size" />
1035-
<Field type="ulong" contentType="bytes" name="nonProfiledSize" label="Non-profiled Size" />
1036-
<Field type="ulong" contentType="bytes" name="expansionSize" label="Expansion size" />
1035+
<Field type="ulong" contentType="bytes" name="nonProfiledSize" label="Non-Profiled Size" />
1036+
<Field type="ulong" contentType="bytes" name="expansionSize" label="Expansion Size" />
10371037
<Field type="ulong" contentType="bytes" name="minBlockLength" label="Minimum Block Length" />
10381038
<Field type="ulong" contentType="address" name="startAddress" label="Start Address" />
10391039
<Field type="ulong" contentType="address" name="reservedTopAddress" label="Reserved Top" />

test/jdk/jdk/jfr/event/metadata/TestEventMetadata.java

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
package jdk.jfr.event.metadata;
2525

26+
import java.util.Arrays;
2627
import java.util.HashSet;
2728
import java.util.List;
2829
import java.util.Set;
@@ -51,7 +52,7 @@ public class TestEventMetadata {
5152
* ----
5253
*
5354
* Symbolic name that is used to identify an event, or a field. Referred to
54-
* as "id" and "field" in trace.xml-files and @Name in the Java API. If it is
55+
* as "name" in metadata.xml and @Name in the Java API. If it is
5556
* the name of an event, the name should be prefixed "jdk.", which
5657
* happens automatically for native events.
5758
*
@@ -61,10 +62,10 @@ public class TestEventMetadata {
6162
* "allocationRate" for a field. Do not use "_" and don't add the word
6263
* "Event" to the event name.
6364
*
64-
* Abbreviations should be avoided, but may be acceptable if the name
65-
* becomes long, or if it is a well established acronym. Write whole words,
66-
* i.e. "allocation" instead of "alloc". The name should not be a reserved
67-
* Java keyword, i.e "void" or "class".
65+
* Abbreviations, such as info, alloc, num, gen, conf, stat, and evac, should
66+
* be avoided. For example, use "allocation" instead of "alloc". Acronyms should be
67+
* avoided unless they are well-established. The name should not be a reserved
68+
* Java keyword, such as "void" or "class".
6869
*
6970
* Label
7071
* -----
@@ -84,8 +85,8 @@ public class TestEventMetadata {
8485
* period should not be included.
8586
*
8687
*
87-
* Do not forget to set proper units for fields, i.e "NANOS", "MILLS",
88-
* "TICKSPAN" ,"BYETS", "PECENTAGE" etc. in native and @Timespan, @Timespan
88+
* Do not forget to set proper units for fields, such as "NANOS", "MILLIS",
89+
* "TICKSPAN", "BYTES", and "PERCENTAGE", in native and @Timespan, @Timespan
8990
* etc. in Java.
9091
*/
9192
public static void main(String[] args) throws Exception {
@@ -161,18 +162,63 @@ private static void verifyName(String name) {
161162
}
162163

163164
private static void verifyLabel(String label) {
165+
System.out.println("Verifying label: " + label);
164166
Asserts.assertNotEquals(label, null, "Label not allowed to be null");
165-
Asserts.assertTrue(label.length() > 1, "Name must be at least two characters");
166-
Asserts.assertTrue(label.length() < 45, "Label should not exceed 45 characters, use description to explain " + label);
167-
Asserts.assertTrue(label.length() == label.trim().length(), "Label should not have trim character at start and end");
168-
Asserts.assertTrue(Character.isUpperCase(label.charAt(0)), "Label should start with upper case letter");
169-
for (int i = 0; i < label.length(); i++) {
170-
char c = label.charAt(i);
171-
Asserts.assertTrue(Character.isDigit(c) || Character.isAlphabetic(label.charAt(i)) || c == ' ' || c == '(' || c == ')' || c == '-', "Label should only consist of letters or space, found '" + label.charAt(i)
172-
+ "'");
167+
Asserts.assertTrue(label.length() > 1, "Label must be at least two characters");
168+
Asserts.assertTrue(label.length() <= 45, "Label should not exceed 45 characters, use description to explain");
169+
Asserts.assertTrue(label.length() == label.trim().length(), "Label should not have superfluous whitespace at start or end");
170+
171+
String[] words = label.split(" ");
172+
String[] middleWords = words.length > 2 ? Arrays.copyOfRange(words, 1, words.length - 1) : new String[0];
173+
String firstWord = words[0];
174+
String lastWord = words[words.length - 1];
175+
Asserts.assertTrue(isCapitalized(firstWord), "Label should capitalize first word");
176+
177+
// The isNumeric check is a workaround so "GC Phase Pause Level 1" doesn't fail.
178+
if (!isNumeric(lastWord)) {
179+
Asserts.assertTrue(isCapitalized(lastWord), "Label should capitalize last word");
180+
}
181+
for (String word : words) {
182+
Asserts.assertFalse(word.endsWith("-") || word.startsWith("-"), "Word in label should not start or end with hyphen");
183+
Asserts.assertTrue(word.length() != 0, "Label should not contain superfluous whitespace");
184+
if (isCapitalized(word)) {
185+
for (String w : word.split("-")) {
186+
Asserts.assertTrue(isCapitalized(w), "Label should capitalize all words in a hyphenated word");
187+
}
188+
}
189+
}
190+
for (String word : middleWords) {
191+
if (isShortCommonPreposition(word)) {
192+
Asserts.assertFalse(isCapitalized(word), "Preposition in label should be lower case, unless first and last word");
193+
}
194+
}
195+
for (char c : label.toCharArray()) {
196+
Asserts.assertTrue(isAllowedCharacter(c), "Label should only consist of letters, numbers, hyphens, parentheses or whitespace, found '" + c + "'");
173197
}
174198
}
175199

200+
private static boolean isAllowedCharacter(char c) {
201+
return Character.isDigit(c) || Character.isAlphabetic(c) || c == ' ' || c == '(' || c == ')' || c == '-';
202+
}
203+
204+
private static boolean isCapitalized(String word) {
205+
String w = word.replace("(", "").replace(")", "");
206+
return !w.isEmpty() && Character.isUpperCase(w.charAt(0));
207+
}
208+
209+
private static boolean isNumeric(String word) {
210+
return word.chars().allMatch(Character::isDigit);
211+
}
212+
213+
private static boolean isShortCommonPreposition(String word) {
214+
String[] prepositions = { "in", "on", "at", "by", "to", "of" };
215+
return containsWord(prepositions, word);
216+
}
217+
218+
private static boolean containsWord(String[] words, String match) {
219+
return Arrays.asList(words).contains(match);
220+
}
221+
176222
private static void verifyEventType(EventType eventType) {
177223
System.out.println("Verifying event: " + eventType.getName());
178224
verifyDescription(eventType.getDescription());
@@ -182,7 +228,7 @@ private static void verifyEventType(EventType eventType) {
182228
String name = eventType.getName().substring(EventNames.PREFIX.length());
183229
Asserts.assertFalse(isReservedKeyword(name),"Name must not be reserved keyword in the Java language (" + name + ")");
184230
checkCommonAbbreviations(name);
185-
char firstChar = name.charAt(0);
231+
char firstChar = name.charAt(0);
186232
Asserts.assertFalse(name.contains("ID"), "'ID' should not be used in name, consider using 'Id'");
187233
Asserts.assertTrue(Character.isAlphabetic(firstChar), "Name " + name + " must start with a character");
188234
Asserts.assertTrue(Character.isUpperCase(firstChar), "Name " + name + " must start with upper case letter");
@@ -198,12 +244,7 @@ static boolean isReservedKeyword(String s) {
198244
"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum",
199245
"extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private",
200246
"protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while" };
201-
for (int i = 0; i < keywords.length; i++) {
202-
if (s.equals(keywords[i])) {
203-
return true;
204-
}
205-
}
206-
return false;
247+
return containsWord(keywords, s);
207248
}
208249

209250
private static void checkCommonAbbreviations(String name) {

0 commit comments

Comments
 (0)