72 * {@link JVMCIPermission}
73 */
74 @SuppressWarnings("unchecked")
75 public static <S> Iterable<S> load(Class<S> service) {
76 if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) {
77 List<?> list = servicesCache.get(service);
78 if (list != null) {
79 return (Iterable<S>) list;
80 }
81 if (IS_IN_NATIVE_IMAGE) {
82 throw new InternalError(String.format("No %s providers found when building native image", service.getName()));
83 }
84 }
85
86 Iterable<S> providers = load0(service);
87
88 if (IS_BUILDING_NATIVE_IMAGE) {
89 synchronized (servicesCache) {
90 ArrayList<S> providersList = new ArrayList<>();
91 for (S provider : providers) {
92 /*
93 * When building libgraal, we want providers that comes from the Graal community
94 * and enterprise modules but not those available on the native-image class
95 * path.
96 */
97 Module module = provider.getClass().getModule();
98 if (module.isNamed()) {
99 providersList.add(provider);
100 }
101 }
102 providers = providersList;
103 servicesCache.put(service, providersList);
104 return providers;
105 }
106 }
107
108 return providers;
109 }
110
111 protected static <S> Iterable<S> load0(Class<S> service) {
112 Iterable<S> iterable = ServiceLoader.load(service);
113 return new Iterable<>() {
114 @Override
115 public Iterator<S> iterator() {
116 Iterator<S> iterator = iterable.iterator();
117 return new Iterator<>() {
118 @Override
119 public boolean hasNext() {
120 return iterator.hasNext();
121 }
122
123 @Override
124 public S next() {
125 S provider = iterator.next();
126 // Allow Graal extensions to access JVMCI
127 openJVMCITo(provider.getClass());
128 return provider;
129 }
130
131 @Override
132 public void remove() {
203 public static InputStream getClassfileAsStream(Class<?> c) throws IOException {
204 String classfilePath = c.getName().replace('.', '/') + ".class";
205 return c.getModule().getResourceAsStream(classfilePath);
206 }
207
208 private static final Module JVMCI_MODULE = Services.class.getModule();
209
210 /**
211 * A JVMCI package dynamically exported to trusted modules.
212 */
213 private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime";
214 static {
215 assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE);
216 }
217
218 /**
219 * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run
220 * trusted code.
221 */
222 public static boolean isToStringTrusted(Class<?> c) {
223 Module module = c.getModule();
224 Module jvmciModule = JVMCI_MODULE;
225 assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime");
226 if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) {
227 // Can access non-statically-exported package in JVMCI
228 return true;
229 }
230 return false;
231 }
232
233 /**
234 * An implementation of {@link SpeculationReason} based on direct, unencoded values.
235 */
236 static final class DirectSpeculationReason implements SpeculationReason {
237 final int groupId;
238 final String groupName;
239 final Object[] context;
240 private SpeculationReasonEncoding encoding;
241
242 DirectSpeculationReason(int groupId, String groupName, Object[] context) {
|
72 * {@link JVMCIPermission}
73 */
74 @SuppressWarnings("unchecked")
75 public static <S> Iterable<S> load(Class<S> service) {
76 if (IS_IN_NATIVE_IMAGE || IS_BUILDING_NATIVE_IMAGE) {
77 List<?> list = servicesCache.get(service);
78 if (list != null) {
79 return (Iterable<S>) list;
80 }
81 if (IS_IN_NATIVE_IMAGE) {
82 throw new InternalError(String.format("No %s providers found when building native image", service.getName()));
83 }
84 }
85
86 Iterable<S> providers = load0(service);
87
88 if (IS_BUILDING_NATIVE_IMAGE) {
89 synchronized (servicesCache) {
90 ArrayList<S> providersList = new ArrayList<>();
91 for (S provider : providers) {
92 Module module = provider.getClass().getModule();
93 if (isHotSpotGraalModule(module.getName())) {
94 providersList.add(provider);
95 }
96 }
97 providers = providersList;
98 servicesCache.put(service, providersList);
99 return providers;
100 }
101 }
102
103 return providers;
104 }
105
106 /**
107 * Determines if the module named by {@code name} is part of Graal when it is configured as a
108 * HotSpot JIT compiler.
109 */
110 private static boolean isHotSpotGraalModule(String name) {
111 if (name != null) {
112 return name.equals("jdk.internal.vm.compiler") ||
113 name.equals("jdk.internal.vm.compiler.management") ||
114 name.equals("com.oracle.graal.graal_enterprise");
115 }
116 return false;
117 }
118
119 protected static <S> Iterable<S> load0(Class<S> service) {
120 Module module = GraalServices.class.getModule();
121 // Graal cannot know all the services used by another module
122 // (e.g. enterprise) so dynamically register the service use now.
123 if (!module.canUse(service)) {
124 module.addUses(service);
125 }
126
127 ModuleLayer layer = module.getLayer();
128 Iterable<S> iterable = ServiceLoader.load(layer, service);
129 return new Iterable<>() {
130 @Override
131 public Iterator<S> iterator() {
132 Iterator<S> iterator = iterable.iterator();
133 return new Iterator<>() {
134 @Override
135 public boolean hasNext() {
136 return iterator.hasNext();
137 }
138
139 @Override
140 public S next() {
141 S provider = iterator.next();
142 // Allow Graal extensions to access JVMCI
143 openJVMCITo(provider.getClass());
144 return provider;
145 }
146
147 @Override
148 public void remove() {
219 public static InputStream getClassfileAsStream(Class<?> c) throws IOException {
220 String classfilePath = c.getName().replace('.', '/') + ".class";
221 return c.getModule().getResourceAsStream(classfilePath);
222 }
223
224 private static final Module JVMCI_MODULE = Services.class.getModule();
225
226 /**
227 * A JVMCI package dynamically exported to trusted modules.
228 */
229 private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime";
230 static {
231 assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE);
232 }
233
234 /**
235 * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run
236 * trusted code.
237 */
238 public static boolean isToStringTrusted(Class<?> c) {
239 if (IS_IN_NATIVE_IMAGE) {
240 return true;
241 }
242
243 Module module = c.getModule();
244 Module jvmciModule = JVMCI_MODULE;
245 assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime");
246 if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) {
247 // Can access non-statically-exported package in JVMCI
248 return true;
249 }
250 return false;
251 }
252
253 /**
254 * An implementation of {@link SpeculationReason} based on direct, unencoded values.
255 */
256 static final class DirectSpeculationReason implements SpeculationReason {
257 final int groupId;
258 final String groupName;
259 final Object[] context;
260 private SpeculationReasonEncoding encoding;
261
262 DirectSpeculationReason(int groupId, String groupName, Object[] context) {
|