@@ -68,7 +68,7 @@ public static class Options {
68
68
public static final RuntimeOptionKey <String > RecordMetadata = new RuntimeOptionKey <>("" );
69
69
}
70
70
71
- private ConfigurationSet config ;
71
+ private volatile ConfigurationSet config ;
72
72
73
73
private Path recordMetadataPath ;
74
74
@@ -77,11 +77,20 @@ public static MetadataTracer singleton() {
77
77
return ImageSingletons .lookup (MetadataTracer .class );
78
78
}
79
79
80
+ /**
81
+ * Returns whether tracing is enabled at run time (using {@code -XX:RecordMetadata=path}).
82
+ */
80
83
public boolean enabled () {
81
84
VMError .guarantee (Options .MetadataTracingSupport .getValue ());
82
- return config != null ;
85
+ return recordMetadataPath != null ;
83
86
}
84
87
88
+ /**
89
+ * Marks the given type as reachable from reflection.
90
+ *
91
+ * @return the corresponding {@link ConfigurationType} or {@code null} if tracing is not active
92
+ * (e.g., during shutdown).
93
+ */
85
94
public ConfigurationType traceReflectionType (String className ) {
86
95
return traceReflectionTypeImpl (new NamedConfigurationTypeDescriptor (className ));
87
96
}
@@ -95,29 +104,59 @@ public void traceProxyType(List<String> interfaceNames) {
95
104
96
105
private ConfigurationType traceReflectionTypeImpl (ConfigurationTypeDescriptor typeDescriptor ) {
97
106
assert enabled ();
98
- return config .getReflectionConfiguration ().getOrCreateType (UnresolvedConfigurationCondition .alwaysTrue (), new NamedConfigurationTypeDescriptor (className ));
107
+ ConfigurationSet configurationSet = config ;
108
+ if (configurationSet != null ) {
109
+ return configurationSet .getReflectionConfiguration ().getOrCreateType (UnresolvedConfigurationCondition .alwaysTrue (), typeDescriptor );
110
+ }
111
+ return null ;
99
112
}
100
113
114
+ /**
115
+ * Marks the given type as reachable from JNI.
116
+ *
117
+ * @return the corresponding {@link ConfigurationType} or {@code null} if tracing is not active
118
+ * (e.g., during shutdown).
119
+ */
101
120
public ConfigurationType traceJNIType (String className ) {
102
121
assert enabled ();
103
122
ConfigurationType result = traceReflectionType (className );
104
- result .setJniAccessible ();
123
+ if (result != null ) {
124
+ result .setJniAccessible ();
125
+ }
105
126
return result ;
106
127
}
107
128
129
+ /**
130
+ * Marks the given resource within the given (optional) module as reachable.
131
+ */
108
132
public void traceResource (String resourceName , String moduleName ) {
109
133
assert enabled ();
110
- config .getResourceConfiguration ().addGlobPattern (UnresolvedConfigurationCondition .alwaysTrue (), resourceName , moduleName );
134
+ ConfigurationSet configurationSet = config ;
135
+ if (configurationSet != null ) {
136
+ configurationSet .getResourceConfiguration ().addGlobPattern (UnresolvedConfigurationCondition .alwaysTrue (), resourceName , moduleName );
137
+ }
111
138
}
112
139
140
+ /**
141
+ * Marks the given resource bundle within the given locale as reachable.
142
+ */
113
143
public void traceResourceBundle (String baseName ) {
114
144
assert enabled ();
115
- config .getResourceConfiguration ().addBundle (UnresolvedConfigurationCondition .alwaysTrue (), baseName , List .of ());
145
+ ConfigurationSet configurationSet = config ;
146
+ if (configurationSet != null ) {
147
+ configurationSet .getResourceConfiguration ().addBundle (UnresolvedConfigurationCondition .alwaysTrue (), baseName , List .of ());
148
+ }
116
149
}
117
150
151
+ /**
152
+ * Marks the given type as serializable.
153
+ */
118
154
public void traceSerializationType (String className ) {
119
155
assert enabled ();
120
- traceReflectionType (className ).setSerializable ();
156
+ ConfigurationType result = traceReflectionType (className );
157
+ if (result != null ) {
158
+ result .setSerializable ();
159
+ }
121
160
}
122
161
123
162
private static void initialize () {
@@ -141,6 +180,7 @@ private static void shutdown() {
141
180
assert Options .MetadataTracingSupport .getValue ();
142
181
MetadataTracer singleton = MetadataTracer .singleton ();
143
182
ConfigurationSet config = singleton .config ;
183
+ singleton .config = null ; // clear config so that shutdown events are not traced.
144
184
if (config != null ) {
145
185
try {
146
186
config .writeConfiguration (configFile -> singleton .recordMetadataPath .resolve (configFile .getFileName ()));
0 commit comments