225 .version()
226 .orElseThrow(() -> new PluginException("No version defined in "
227 + "the java.base being linked"));
228 return Runtime.Version.parse(version.toString());
229 }
230
231 private void readTraceConfig(Stream<String> lines) {
232 // Use TreeSet/TreeMap to keep things sorted in a deterministic
233 // order to avoid scrambling the layout on small changes and to
234 // ease finding methods in the generated code
235 speciesTypes = new TreeSet<>(speciesTypes);
236 invokerTypes = new TreeSet<>(invokerTypes);
237 TreeMap<String, Set<String>> newDMHMethods = new TreeMap<>();
238 for (Map.Entry<String, Set<String>> entry : dmhMethods.entrySet()) {
239 newDMHMethods.put(entry.getKey(), new TreeSet<>(entry.getValue()));
240 }
241 dmhMethods = newDMHMethods;
242 lines.map(line -> line.split(" "))
243 .forEach(parts -> {
244 switch (parts[0]) {
245 case "[BMH_RESOLVE]":
246 speciesTypes.add(expandSignature(parts[1]));
247 break;
248 case "[LF_RESOLVE]":
249 String methodType = parts[3];
250 validateMethodType(methodType);
251 if (parts[1].contains("Invokers")) {
252 invokerTypes.add(methodType);
253 } else if (parts[1].contains("DirectMethodHandle")) {
254 String dmh = parts[2];
255 // ignore getObject etc for now (generated
256 // by default)
257 if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {
258 addDMHMethodType(dmh, methodType);
259 }
260 }
261 break;
262 default: break; // ignore
263 }
264 });
265 }
266
432 ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
433 out.add(ndata);
434
435 bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
436 ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);
437 out.add(ndata);
438 } catch (Exception ex) {
439 throw new PluginException(ex);
440 }
441 }
442 private static final String DIRECT_METHOD_HOLDER_ENTRY =
443 "/java.base/" + DIRECT_HOLDER + ".class";
444 private static final String DELEGATING_METHOD_HOLDER_ENTRY =
445 "/java.base/" + DELEGATING_HOLDER + ".class";
446 private static final String BASIC_FORMS_HOLDER_ENTRY =
447 "/java.base/" + BASIC_FORMS_HOLDER + ".class";
448 private static final String INVOKERS_HOLDER_ENTRY =
449 "/java.base/" + INVOKERS_HOLDER + ".class";
450
451 // Convert LL -> LL, L3 -> LLL
452 private static String expandSignature(String signature) {
453 StringBuilder sb = new StringBuilder();
454 char last = 'X';
455 int count = 0;
456 for (int i = 0; i < signature.length(); i++) {
457 char c = signature.charAt(i);
458 if (c >= '0' && c <= '9') {
459 count *= 10;
460 count += (c - '0');
461 } else {
462 requireBasicType(c);
463 for (int j = 1; j < count; j++) {
464 sb.append(last);
465 }
466 sb.append(c);
467 last = c;
468 count = 0;
469 }
470 }
471
472 // ended with a number, e.g., "L2": append last char count - 1 times
|
225 .version()
226 .orElseThrow(() -> new PluginException("No version defined in "
227 + "the java.base being linked"));
228 return Runtime.Version.parse(version.toString());
229 }
230
231 private void readTraceConfig(Stream<String> lines) {
232 // Use TreeSet/TreeMap to keep things sorted in a deterministic
233 // order to avoid scrambling the layout on small changes and to
234 // ease finding methods in the generated code
235 speciesTypes = new TreeSet<>(speciesTypes);
236 invokerTypes = new TreeSet<>(invokerTypes);
237 TreeMap<String, Set<String>> newDMHMethods = new TreeMap<>();
238 for (Map.Entry<String, Set<String>> entry : dmhMethods.entrySet()) {
239 newDMHMethods.put(entry.getKey(), new TreeSet<>(entry.getValue()));
240 }
241 dmhMethods = newDMHMethods;
242 lines.map(line -> line.split(" "))
243 .forEach(parts -> {
244 switch (parts[0]) {
245 case "[SPECIES_RESOLVE]":
246 // Allow for new types of species data classes being resolved here
247 if (parts.length == 3 && parts[1].startsWith("java.lang.invoke.BoundMethodHandle$Species_")) {
248 String species = parts[1].substring("java.lang.invoke.BoundMethodHandle$Species_".length());
249 if (!"L".equals(species)) {
250 speciesTypes.add(expandSignature(species));
251 }
252 }
253 break;
254 case "[LF_RESOLVE]":
255 String methodType = parts[3];
256 validateMethodType(methodType);
257 if (parts[1].contains("Invokers")) {
258 invokerTypes.add(methodType);
259 } else if (parts[1].contains("DirectMethodHandle")) {
260 String dmh = parts[2];
261 // ignore getObject etc for now (generated
262 // by default)
263 if (DMH_METHOD_TYPE_MAP.containsKey(dmh)) {
264 addDMHMethodType(dmh, methodType);
265 }
266 }
267 break;
268 default: break; // ignore
269 }
270 });
271 }
272
438 ndata = ResourcePoolEntry.create(INVOKERS_HOLDER_ENTRY, bytes);
439 out.add(ndata);
440
441 bytes = JLIA.generateBasicFormsClassBytes(BASIC_FORMS_HOLDER);
442 ndata = ResourcePoolEntry.create(BASIC_FORMS_HOLDER_ENTRY, bytes);
443 out.add(ndata);
444 } catch (Exception ex) {
445 throw new PluginException(ex);
446 }
447 }
448 private static final String DIRECT_METHOD_HOLDER_ENTRY =
449 "/java.base/" + DIRECT_HOLDER + ".class";
450 private static final String DELEGATING_METHOD_HOLDER_ENTRY =
451 "/java.base/" + DELEGATING_HOLDER + ".class";
452 private static final String BASIC_FORMS_HOLDER_ENTRY =
453 "/java.base/" + BASIC_FORMS_HOLDER + ".class";
454 private static final String INVOKERS_HOLDER_ENTRY =
455 "/java.base/" + INVOKERS_HOLDER + ".class";
456
457 // Convert LL -> LL, L3 -> LLL
458 public static String expandSignature(String signature) {
459 StringBuilder sb = new StringBuilder();
460 char last = 'X';
461 int count = 0;
462 for (int i = 0; i < signature.length(); i++) {
463 char c = signature.charAt(i);
464 if (c >= '0' && c <= '9') {
465 count *= 10;
466 count += (c - '0');
467 } else {
468 requireBasicType(c);
469 for (int j = 1; j < count; j++) {
470 sb.append(last);
471 }
472 sb.append(c);
473 last = c;
474 count = 0;
475 }
476 }
477
478 // ended with a number, e.g., "L2": append last char count - 1 times
|