|
16 | 16 | import java.util.HashSet;
|
17 | 17 | import java.util.List;
|
18 | 18 | import java.util.Map;
|
| 19 | +import java.util.Map.Entry; |
19 | 20 | import java.util.Objects;
|
20 | 21 | import java.util.Set;
|
21 | 22 | import java.util.concurrent.Callable;
|
@@ -101,19 +102,16 @@ TransformedClassesBuildItem handleClassTransformation(List<BytecodeTransformerBu
|
101 | 102 | for (BytecodeTransformerBuildItem i : bytecodeTransformerBuildItems) {
|
102 | 103 | bytecodeTransformers.computeIfAbsent(i.getClassToTransform(), (h) -> new ArrayList<>())
|
103 | 104 | .add(i);
|
104 |
| - if (i.getRequireConstPoolEntry() == null || i.getRequireConstPoolEntry().isEmpty()) { |
105 |
| - noConstScanning.add(i.getClassToTransform()); |
106 |
| - } else { |
107 |
| - constScanning.computeIfAbsent(i.getClassToTransform(), (s) -> new HashSet<>()) |
108 |
| - .addAll(i.getRequireConstPoolEntry()); |
109 |
| - } |
110 | 105 | if (!i.isCacheable()) {
|
111 | 106 | nonCacheable.add(i.getClassToTransform());
|
112 | 107 | }
|
113 | 108 | classReaderOptions.merge(i.getClassToTransform(), i.getClassReaderOptions(),
|
114 | 109 | // class reader options are bit flags (see org.objectweb.asm.ClassReader)
|
115 | 110 | (oldValue, newValue) -> oldValue | newValue);
|
116 | 111 | }
|
| 112 | + |
| 113 | + initializeConstPoolScanningConfiguration(bytecodeTransformers, noConstScanning, constScanning); |
| 114 | + |
117 | 115 | QuarkusClassLoader cl = (QuarkusClassLoader) Thread.currentThread().getContextClassLoader();
|
118 | 116 | Map<String, Path> transformedToArchive = new ConcurrentHashMap<>();
|
119 | 117 | // now copy all the contents to the runner jar
|
@@ -288,6 +286,39 @@ public TransformedClassesBuildItem.TransformedClass call() throws Exception {
|
288 | 286 | return new TransformedClassesBuildItem(transformedClassesByJar);
|
289 | 287 | }
|
290 | 288 |
|
| 289 | + private static void initializeConstPoolScanningConfiguration( |
| 290 | + Map<String, List<BytecodeTransformerBuildItem>> bytecodeTransformers, Set<String> noConstScanning, |
| 291 | + Map<String, Set<String>> constScanning) { |
| 292 | + // this option is not widely used and it is mostly used by the Panache transformer AFAIK |
| 293 | + // in this case, we have all the Panache entities in the list, which might be quite a lot when you have a lot of entities |
| 294 | + // and it's worth avoiding copying the entries over and over as we used to create a new copy of the set for each entity |
| 295 | + for (Entry<String, List<BytecodeTransformerBuildItem>> bytecodeTransformersPerClassEntry : bytecodeTransformers |
| 296 | + .entrySet()) { |
| 297 | + List<BytecodeTransformerBuildItem> transformersRequiringConstPoolEntries = new ArrayList<>( |
| 298 | + bytecodeTransformersPerClassEntry.getValue().size()); |
| 299 | + int requiredConstPoolEntriesNumber = 0; |
| 300 | + for (BytecodeTransformerBuildItem transformer : bytecodeTransformersPerClassEntry.getValue()) { |
| 301 | + if (transformer.getRequireConstPoolEntry() != null && !transformer.getRequireConstPoolEntry().isEmpty()) { |
| 302 | + transformersRequiringConstPoolEntries.add(transformer); |
| 303 | + requiredConstPoolEntriesNumber += transformer.getRequireConstPoolEntry().size(); |
| 304 | + } |
| 305 | + } |
| 306 | + if (transformersRequiringConstPoolEntries.isEmpty()) { |
| 307 | + noConstScanning.add(bytecodeTransformersPerClassEntry.getKey()); |
| 308 | + } else if (transformersRequiringConstPoolEntries.size() == 1) { |
| 309 | + constScanning.put(bytecodeTransformersPerClassEntry.getKey(), |
| 310 | + transformersRequiringConstPoolEntries.get(0).getRequireConstPoolEntry()); |
| 311 | + } else { |
| 312 | + // we don't do that often, but let's avoid having to resize the underlying HashMap as it can be quite big |
| 313 | + Set<String> requiredConstPoolEntries = new HashSet<>((int) Math.ceil(requiredConstPoolEntriesNumber / 0.75f)); |
| 314 | + for (BytecodeTransformerBuildItem transformer : transformersRequiringConstPoolEntries) { |
| 315 | + requiredConstPoolEntries.addAll(transformer.getRequireConstPoolEntry()); |
| 316 | + } |
| 317 | + constScanning.put(bytecodeTransformersPerClassEntry.getKey(), requiredConstPoolEntries); |
| 318 | + } |
| 319 | + } |
| 320 | + } |
| 321 | + |
291 | 322 | private void copyTransformedClasses(Path originalClassesPath,
|
292 | 323 | Set<TransformedClassesBuildItem.TransformedClass> transformedClasses) {
|
293 | 324 | if ((transformedClasses == null) || transformedClasses.isEmpty()) {
|
|
0 commit comments