@@ -37,11 +37,21 @@ public final class RedactUtils {
3737 // Type descriptors like Lcom/company/Type;
3838 private static final Pattern TYPE_DESCRIPTOR = Pattern .compile ("L([A-Za-z$_][A-Za-z0-9$_/]*);" );
3939
40- // klass/interface references: - klass: 'com/company/Class'
41- private static final Pattern KLASS_REF = Pattern .compile ("((?: klass|interface) : ')([^']+)(') " );
40+ // klass references: - klass: 'com/company/Class'
41+ private static final Pattern KLASS_REF = Pattern .compile ("(klass: ')([^']+)' " );
4242
4343 // 'in 'class'' clause in {method} descriptor entries
44- private static final Pattern METHOD_IN_CLASS = Pattern .compile ("( in ')([^']+)(')" );
44+ private static final Pattern METHOD_IN_CLASS = Pattern .compile ("( in ')([^']+)'" );
45+
46+ // Object-reference field values in oop dumps: a 'com/company/Class'{0x...}
47+ private static final Pattern OBJ_FIELD_REF =
48+ Pattern .compile ("(a ')([A-Za-z$_][A-Za-z0-9$_/]*)'" );
49+
50+ // Class name in nmethod compiled-method output (JDK 11+):
51+ // "Compiled method (c2) ... com.company.Foo::methodName (N bytes)" (PRODUCT — dots)
52+ // "Compiled method (c2) ... com/company/Foo::methodName (N bytes)" (debug — slashes)
53+ private static final Pattern NMETHOD_CLASS =
54+ Pattern .compile ("([A-Za-z][A-Za-z0-9$]*(?:[./][A-Za-z][A-Za-z0-9$]*)+)::" );
4555
4656 // Library path in two formats produced by os::print_location():
4757 // <offset 0x...> in /path/to/lib.so at 0x... (no dladdr symbol)
@@ -106,6 +116,8 @@ private static String redactLine(String line, boolean isClassOop) {
106116 line = redactTypeDescriptors (line );
107117 line = redactKlassReference (line );
108118 line = redactMethodClass (line );
119+ line = redactObjFieldRef (line );
120+ line = redactNmethodClass (line );
109121 line = redactLibraryPath (line );
110122 line = redactStringOopRef (line , isClassOop );
111123 line = redactOopClassName (line );
@@ -140,39 +152,65 @@ static String redactStringTypeValue(String line) {
140152
141153 /**
142154 * Redacts the package of type descriptors in a line: <code>Lcom/company/Type;</code> to <code>
143- * Lredacted/redacted/Type ;</code>
155+ * Lredacted/Redacted ;</code>
144156 */
145157 static String redactTypeDescriptors (String line ) {
146158 return replaceAll (TYPE_DESCRIPTOR , line , m -> "L" + redactJvmClassName (m .group (1 )) + ";" );
147159 }
148160
149161 /**
150- * Redacts klass/interface references in a line: <code>klass: 'com/company/Class'</code> to <code>
151- * klass: 'redacted/redacted/Class '</code>
162+ * Redacts klass references in a line: <code>klass: 'com/company/Class'</code> to <code>
163+ * klass: 'redacted/Redacted '</code>
152164 */
153165 static String redactKlassReference (String line ) {
154166 return replaceAll (
155- KLASS_REF , line , m -> m .group (1 ) + redactJvmClassName (m .group (2 )) + m . group ( 3 ) );
167+ KLASS_REF , line , m -> m .group (1 ) + redactJvmClassName (m .group (2 )) + "'" );
156168 }
157169
158170 /**
159171 * Redacts the class in a method descriptor's {@code in 'class'} clause: <code>
160- * in 'com/company/Class'</code> to <code>in 'redacted/redacted/Class '</code>
172+ * in 'com/company/Class'</code> to <code>in 'redacted/Redacted '</code>
161173 */
162174 static String redactMethodClass (String line ) {
163175 return replaceAll (
164- METHOD_IN_CLASS , line , m -> m .group (1 ) + redactJvmClassName (m .group (2 )) + m . group ( 3 ) );
176+ METHOD_IN_CLASS , line , m -> m .group (1 ) + redactJvmClassName (m .group (2 )) + "'" );
165177 }
166178
167179 /**
168180 * Redacts all but the parent directory and filename from a library path. Handles both <code>
169181 * <offset 0x...> in /path/to/dir/lib.so</code> and <code>symbol+0 in
170- * /path/to/dir/lib.so</code> to <code>... in /redacted/redacted/ dir/lib.so</code>
182+ * /path/to/dir/lib.so</code> to <code>... in /redacted/dir/lib.so</code>
171183 */
172184 static String redactLibraryPath (String line ) {
173185 return replaceAll (LIBRARY_PATH , line , m -> m .group (1 ) + redactPath (m .group (2 )));
174186 }
175187
188+ /**
189+ * Redacts the class name in oop dump object-reference field values: <code>a
190+ * 'com/company/Class'</code> to <code>a 'redacted/Redacted'</code>.
191+ */
192+ static String redactObjFieldRef (String line ) {
193+ return replaceAll (
194+ OBJ_FIELD_REF , line , m -> m .group (1 ) + redactJvmClassName (m .group (2 )) + "'" );
195+ }
196+
197+ /**
198+ * Redacts the class name in nmethod {@code Compiled method} output (JDK 11+): <code>
199+ * com.company.Foo::methodName</code> to <code>redacted.Redacted::methodName</code>. Handles both
200+ * dot-separated (PRODUCT build) and slash-separated (debug build) class names.
201+ */
202+ static String redactNmethodClass (String line ) {
203+ return replaceAll (
204+ NMETHOD_CLASS ,
205+ line ,
206+ m -> {
207+ String cls = m .group (1 );
208+ String redacted =
209+ cls .indexOf ('/' ) >= 0 ? redactJvmClassName (cls ) : redactDottedClassName (cls );
210+ return redacted + "::" ;
211+ });
212+ }
213+
176214 /**
177215 * Redacts any {@code "value"\{0x...\}} OOP reference to {@code "REDACTED"\{0x...\}}. This is the
178216 * safe default for lines that are not part of a {@code java.lang.Class} oop dump, where the
@@ -186,7 +224,7 @@ static String redactDottedClassOopRef(String line) {
186224
187225 /**
188226 * Redacts the class name in {@code is an oop: ClassName}: <code>is an oop: com.company.Class
189- * </code> to <code>is an oop: redacted.redacted.Class </code>
227+ * </code> to <code>is an oop: redacted.Redacted </code>
190228 */
191229 static String redactOopClassName (String line ) {
192230 return replaceAll (IS_AN_OOP , line , m -> m .group (1 ) + redactDottedClassName (m .group (2 )));
0 commit comments