src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java
equal
deleted
inserted
replaced
50 import java.util.List; |
50 import java.util.List; |
51 import java.util.Map; |
51 import java.util.Map; |
52 import java.util.Objects; |
52 import java.util.Objects; |
53 import java.util.Optional; |
53 import java.util.Optional; |
54 import java.util.Set; |
54 import java.util.Set; |
|
55 import java.util.TreeMap; |
55 import java.util.TreeSet; |
56 import java.util.TreeSet; |
56 import java.util.function.IntSupplier; |
57 import java.util.function.IntSupplier; |
57 import java.util.function.Supplier; |
58 import java.util.function.Supplier; |
58 import java.util.stream.Collectors; |
59 import java.util.stream.Collectors; |
59 |
60 |
923 // new Map$Entry[size] |
924 // new Map$Entry[size] |
924 pushInt(mv, map.size()); |
925 pushInt(mv, map.size()); |
925 mv.visitTypeInsn(ANEWARRAY, "java/util/Map$Entry"); |
926 mv.visitTypeInsn(ANEWARRAY, "java/util/Map$Entry"); |
926 |
927 |
927 int index = 0; |
928 int index = 0; |
928 for (Map.Entry<String, Set<String>> e : map.entrySet()) { |
929 for (var e : new TreeMap<>(map).entrySet()) { |
929 String name = e.getKey(); |
930 String name = e.getKey(); |
930 Set<String> s = e.getValue(); |
931 Set<String> s = e.getValue(); |
931 |
932 |
932 mv.visitInsn(DUP); |
933 mv.visitInsn(DUP); |
933 pushInt(mv, index); |
934 pushInt(mv, index); |
969 // use Set.of(Object) or Set.of(Object, Object) when fewer |
970 // use Set.of(Object) or Set.of(Object, Object) when fewer |
970 if (size > 2) { |
971 if (size > 2) { |
971 pushInt(mv, size); |
972 pushInt(mv, size); |
972 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
973 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
973 int i = 0; |
974 int i = 0; |
974 for (String element : set) { |
975 for (String element : sorted(set)) { |
975 mv.visitInsn(DUP); |
976 mv.visitInsn(DUP); |
976 pushInt(mv, i); |
977 pushInt(mv, i); |
977 mv.visitLdcInsn(element); |
978 mv.visitLdcInsn(element); |
978 mv.visitInsn(AASTORE); |
979 mv.visitInsn(AASTORE); |
979 i++; |
980 i++; |
983 "of", |
984 "of", |
984 "([Ljava/lang/Object;)Ljava/util/Set;", |
985 "([Ljava/lang/Object;)Ljava/util/Set;", |
985 true); |
986 true); |
986 } else { |
987 } else { |
987 StringBuilder sb = new StringBuilder("("); |
988 StringBuilder sb = new StringBuilder("("); |
988 for (String element : set) { |
989 for (String element : sorted(set)) { |
989 mv.visitLdcInsn(element); |
990 mv.visitLdcInsn(element); |
990 sb.append("Ljava/lang/Object;"); |
991 sb.append("Ljava/lang/Object;"); |
991 } |
992 } |
992 sb.append(")Ljava/util/Set;"); |
993 sb.append(")Ljava/util/Set;"); |
993 mv.visitMethodInsn(INVOKESTATIC, |
994 mv.visitMethodInsn(INVOKESTATIC, |
1144 void requires(Set<Requires> requires) { |
1145 void requires(Set<Requires> requires) { |
1145 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1146 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1146 pushInt(mv, requires.size()); |
1147 pushInt(mv, requires.size()); |
1147 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Requires"); |
1148 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Requires"); |
1148 int arrayIndex = 0; |
1149 int arrayIndex = 0; |
1149 for (Requires require : requires) { |
1150 for (Requires require : sorted(requires)) { |
1150 String compiledVersion = null; |
1151 String compiledVersion = null; |
1151 if (require.compiledVersion().isPresent()) { |
1152 if (require.compiledVersion().isPresent()) { |
1152 compiledVersion = require.compiledVersion().get().toString(); |
1153 compiledVersion = require.compiledVersion().get().toString(); |
1153 } |
1154 } |
1154 |
1155 |
1190 void exports(Set<Exports> exports) { |
1191 void exports(Set<Exports> exports) { |
1191 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1192 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1192 pushInt(mv, exports.size()); |
1193 pushInt(mv, exports.size()); |
1193 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Exports"); |
1194 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Exports"); |
1194 int arrayIndex = 0; |
1195 int arrayIndex = 0; |
1195 for (Exports export : exports) { |
1196 for (Exports export : sorted(exports)) { |
1196 mv.visitInsn(DUP); // arrayref |
1197 mv.visitInsn(DUP); // arrayref |
1197 pushInt(mv, arrayIndex++); |
1198 pushInt(mv, arrayIndex++); |
1198 newExports(export.modifiers(), export.source(), export.targets()); |
1199 newExports(export.modifiers(), export.source(), export.targets()); |
1199 mv.visitInsn(AASTORE); |
1200 mv.visitInsn(AASTORE); |
1200 } |
1201 } |
1243 void opens(Set<Opens> opens) { |
1244 void opens(Set<Opens> opens) { |
1244 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1245 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1245 pushInt(mv, opens.size()); |
1246 pushInt(mv, opens.size()); |
1246 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Opens"); |
1247 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Opens"); |
1247 int arrayIndex = 0; |
1248 int arrayIndex = 0; |
1248 for (Opens open : opens) { |
1249 for (Opens open : sorted(opens)) { |
1249 mv.visitInsn(DUP); // arrayref |
1250 mv.visitInsn(DUP); // arrayref |
1250 pushInt(mv, arrayIndex++); |
1251 pushInt(mv, arrayIndex++); |
1251 newOpens(open.modifiers(), open.source(), open.targets()); |
1252 newOpens(open.modifiers(), open.source(), open.targets()); |
1252 mv.visitInsn(AASTORE); |
1253 mv.visitInsn(AASTORE); |
1253 } |
1254 } |
1308 void provides(Collection<Provides> provides) { |
1309 void provides(Collection<Provides> provides) { |
1309 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1310 mv.visitVarInsn(ALOAD, BUILDER_VAR); |
1310 pushInt(mv, provides.size()); |
1311 pushInt(mv, provides.size()); |
1311 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Provides"); |
1312 mv.visitTypeInsn(ANEWARRAY, "java/lang/module/ModuleDescriptor$Provides"); |
1312 int arrayIndex = 0; |
1313 int arrayIndex = 0; |
1313 for (Provides provide : provides) { |
1314 for (Provides provide : sorted(provides)) { |
1314 mv.visitInsn(DUP); // arrayref |
1315 mv.visitInsn(DUP); // arrayref |
1315 pushInt(mv, arrayIndex++); |
1316 pushInt(mv, arrayIndex++); |
1316 newProvides(provide.service(), provide.providers()); |
1317 newProvides(provide.service(), provide.providers()); |
1317 mv.visitInsn(AASTORE); |
1318 mv.visitInsn(AASTORE); |
1318 } |
1319 } |
1418 newModuleHashesBuilder(); |
1419 newModuleHashesBuilder(); |
1419 |
1420 |
1420 // Invoke ModuleHashes.Builder::hashForModule |
1421 // Invoke ModuleHashes.Builder::hashForModule |
1421 recordedHashes |
1422 recordedHashes |
1422 .names() |
1423 .names() |
|
1424 .stream() |
|
1425 .sorted() |
1423 .forEach(mn -> hashForModule(mn, recordedHashes.hashFor(mn))); |
1426 .forEach(mn -> hashForModule(mn, recordedHashes.hashFor(mn))); |
1424 |
1427 |
1425 // Put ModuleHashes into the hashes array |
1428 // Put ModuleHashes into the hashes array |
1426 pushModuleHashes(); |
1429 pushModuleHashes(); |
1427 } |
1430 } |
1598 * for a given set of elements and assign to a local variable slot. |
1601 * for a given set of elements and assign to a local variable slot. |
1599 * When there is only one single reference to a Set<T>, |
1602 * When there is only one single reference to a Set<T>, |
1600 * it will reuse defaultVarIndex. For a Set with multiple references, |
1603 * it will reuse defaultVarIndex. For a Set with multiple references, |
1601 * it will use a new local variable retrieved from the nextLocalVar |
1604 * it will use a new local variable retrieved from the nextLocalVar |
1602 */ |
1605 */ |
1603 class SetBuilder<T> { |
1606 class SetBuilder<T extends Comparable<T>> { |
1604 private final Set<T> elements; |
1607 private final Set<T> elements; |
1605 private final int defaultVarIndex; |
1608 private final int defaultVarIndex; |
1606 private final IntSupplier nextLocalVar; |
1609 private final IntSupplier nextLocalVar; |
1607 private int refCount; |
1610 private int refCount; |
1608 private int localVarIndex; |
1611 private int localVarIndex; |
1658 |
1661 |
1659 private void generateSetOf(int index) { |
1662 private void generateSetOf(int index) { |
1660 if (elements.size() <= 10) { |
1663 if (elements.size() <= 10) { |
1661 // call Set.of(e1, e2, ...) |
1664 // call Set.of(e1, e2, ...) |
1662 StringBuilder sb = new StringBuilder("("); |
1665 StringBuilder sb = new StringBuilder("("); |
1663 for (T t : elements) { |
1666 for (T t : sorted(elements)) { |
1664 sb.append("Ljava/lang/Object;"); |
1667 sb.append("Ljava/lang/Object;"); |
1665 visitElement(t, mv); |
1668 visitElement(t, mv); |
1666 } |
1669 } |
1667 sb.append(")Ljava/util/Set;"); |
1670 sb.append(")Ljava/util/Set;"); |
1668 mv.visitMethodInsn(INVOKESTATIC, "java/util/Set", |
1671 mv.visitMethodInsn(INVOKESTATIC, "java/util/Set", |
1670 } else { |
1673 } else { |
1671 // call Set.of(E... elements) |
1674 // call Set.of(E... elements) |
1672 pushInt(mv, elements.size()); |
1675 pushInt(mv, elements.size()); |
1673 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1676 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1674 int arrayIndex = 0; |
1677 int arrayIndex = 0; |
1675 for (T t : elements) { |
1678 for (T t : sorted(elements)) { |
1676 mv.visitInsn(DUP); // arrayref |
1679 mv.visitInsn(DUP); // arrayref |
1677 pushInt(mv, arrayIndex); |
1680 pushInt(mv, arrayIndex); |
1678 visitElement(t, mv); // value |
1681 visitElement(t, mv); // value |
1679 mv.visitInsn(AASTORE); |
1682 mv.visitInsn(AASTORE); |
1680 arrayIndex++; |
1683 arrayIndex++; |
1688 |
1691 |
1689 /* |
1692 /* |
1690 * Generates bytecode to create one single instance of EnumSet |
1693 * Generates bytecode to create one single instance of EnumSet |
1691 * for a given set of modifiers and assign to a local variable slot. |
1694 * for a given set of modifiers and assign to a local variable slot. |
1692 */ |
1695 */ |
1693 class EnumSetBuilder<T> extends SetBuilder<T> { |
1696 class EnumSetBuilder<T extends Comparable<T>> extends SetBuilder<T> { |
1694 |
1697 |
1695 private final String className; |
1698 private final String className; |
1696 |
1699 |
1697 EnumSetBuilder(Set<T> modifiers, String className, |
1700 EnumSetBuilder(Set<T> modifiers, String className, |
1698 int defaultVarIndex, |
1701 int defaultVarIndex, |
1786 mv.visitCode(); |
1789 mv.visitCode(); |
1787 pushInt(mv, map.size()); |
1790 pushInt(mv, map.size()); |
1788 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1791 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1789 |
1792 |
1790 int index = 0; |
1793 int index = 0; |
1791 for (String moduleName : map.keySet()) { |
1794 for (String moduleName : sorted(map.keySet())) { |
1792 mv.visitInsn(DUP); // arrayref |
1795 mv.visitInsn(DUP); // arrayref |
1793 pushInt(mv, index); |
1796 pushInt(mv, index); |
1794 mv.visitLdcInsn(moduleName); |
1797 mv.visitLdcInsn(moduleName); |
1795 mv.visitInsn(AASTORE); |
1798 mv.visitInsn(AASTORE); |
1796 index++; |
1799 index++; |
1809 mv.visitCode(); |
1812 mv.visitCode(); |
1810 pushInt(mv, map.size()); |
1813 pushInt(mv, map.size()); |
1811 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1814 mv.visitTypeInsn(ANEWARRAY, "java/lang/String"); |
1812 |
1815 |
1813 index = 0; |
1816 index = 0; |
1814 for (String className : map.values()) { |
1817 for (String className : sorted(map.values())) { |
1815 mv.visitInsn(DUP); // arrayref |
1818 mv.visitInsn(DUP); // arrayref |
1816 pushInt(mv, index); |
1819 pushInt(mv, index); |
1817 mv.visitLdcInsn(className.replace('/', '.')); |
1820 mv.visitLdcInsn(className.replace('/', '.')); |
1818 mv.visitInsn(AASTORE); |
1821 mv.visitInsn(AASTORE); |
1819 index++; |
1822 index++; |
1827 String rn = "/java.base/" + SYSTEM_MODULES_MAP_CLASS + ".class"; |
1830 String rn = "/java.base/" + SYSTEM_MODULES_MAP_CLASS + ".class"; |
1828 ResourcePoolEntry e = ResourcePoolEntry.create(rn, cw.toByteArray()); |
1831 ResourcePoolEntry e = ResourcePoolEntry.create(rn, cw.toByteArray()); |
1829 out.add(e); |
1832 out.add(e); |
1830 |
1833 |
1831 return rn; |
1834 return rn; |
|
1835 } |
|
1836 |
|
1837 /** |
|
1838 * Returns a sorted copy of a collection. |
|
1839 * |
|
1840 * This is useful to ensure a deterministic iteration order. |
|
1841 * |
|
1842 * @return a sorted copy of the given collection. |
|
1843 */ |
|
1844 private static <T extends Comparable<T>> List<T> sorted(Collection<T> c) { |
|
1845 var l = new ArrayList<T>(c); |
|
1846 Collections.sort(l); |
|
1847 return l; |
1832 } |
1848 } |
1833 |
1849 |
1834 /** |
1850 /** |
1835 * Pushes an int constant |
1851 * Pushes an int constant |
1836 */ |
1852 */ |