Skip to content

Commit 8097e82

Browse files
committed
[GR-65695] Replace streams with indexed for-loops in layer loader.
PullRequest: graal/21044
2 parents 2a3b5fd + b8c0a68 commit 8097e82

File tree

7 files changed

+327
-119
lines changed

7 files changed

+327
-119
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/HostedLayeredModuleSingleton.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,14 @@
2929
import java.util.HashSet;
3030
import java.util.Map;
3131
import java.util.Set;
32-
import java.util.stream.Collectors;
3332

3433
import com.oracle.svm.core.feature.AutomaticallyRegisteredImageSingleton;
3534
import com.oracle.svm.core.imagelayer.BuildingInitialLayerPredicate;
3635
import com.oracle.svm.core.jdk.LayeredModuleSingleton;
3736
import com.oracle.svm.core.layeredimagesingleton.ImageSingletonLoader;
3837
import com.oracle.svm.core.layeredimagesingleton.ImageSingletonWriter;
3938
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
40-
import com.oracle.svm.hosted.imagelayer.SVMImageLayerLoader;
39+
import com.oracle.svm.hosted.imagelayer.CapnProtoAdapters;
4140
import com.oracle.svm.hosted.imagelayer.SVMImageLayerSingletonLoader;
4241
import com.oracle.svm.hosted.imagelayer.SVMImageLayerWriter;
4342
import com.oracle.svm.hosted.imagelayer.SharedLayerSnapshotCapnProtoSchemaHolder.ModulePackages;
@@ -103,7 +102,7 @@ private static Map<String, Map<String, Set<String>>> getModulePackages(StructLis
103102
Map<String, Set<String>> packages = new HashMap<>();
104103
for (int j = 0; j < packagesReader.size(); ++j) {
105104
var packageEntryReader = packagesReader.get(j);
106-
HashSet<String> modules = SVMImageLayerLoader.streamStrings(packageEntryReader.getModules()).collect(Collectors.toCollection(HashSet::new));
105+
Set<String> modules = CapnProtoAdapters.toCollection(packageEntryReader.getModules(), HashSet::new);
107106
packages.put(packageEntryReader.getPackageKey().toString(), modules);
108107
}
109108
modulePackages.put(entryReader.getModuleKey().toString(), packages);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SharedLayerBootLayerModulesSingleton.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
*/
2525
package com.oracle.svm.hosted;
2626

27+
import java.util.ArrayList;
2728
import java.util.Collection;
2829
import java.util.EnumSet;
2930
import java.util.List;
3031
import java.util.stream.Stream;
3132

33+
import com.oracle.svm.hosted.imagelayer.CapnProtoAdapters;
3234
import org.graalvm.nativeimage.ImageSingletons;
3335
import org.graalvm.nativeimage.Platform;
3436
import org.graalvm.nativeimage.Platforms;
@@ -39,7 +41,6 @@
3941
import com.oracle.svm.core.layeredimagesingleton.ImageSingletonWriter;
4042
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingleton;
4143
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonBuilderFlags;
42-
import com.oracle.svm.hosted.imagelayer.SVMImageLayerLoader;
4344
import com.oracle.svm.hosted.imagelayer.SVMImageLayerSingletonLoader;
4445
import com.oracle.svm.hosted.imagelayer.SVMImageLayerWriter;
4546

@@ -91,7 +92,7 @@ public PersistFlags preparePersist(ImageSingletonWriter writer) {
9192
@SuppressWarnings("unused")
9293
public static Object createFromLoader(ImageSingletonLoader loader) {
9394
SVMImageLayerSingletonLoader.ImageSingletonLoaderImpl loaderImpl = (SVMImageLayerSingletonLoader.ImageSingletonLoaderImpl) loader;
94-
List<String> moduleNames = SVMImageLayerLoader.streamStrings(loaderImpl.getSnapshotReader().getSharedLayerBootLayerModules()).toList();
95+
List<String> moduleNames = CapnProtoAdapters.toCollection(loaderImpl.getSnapshotReader().getSharedLayerBootLayerModules(), ArrayList::new);
9596
return new SharedLayerBootLayerModulesSingleton(moduleNames);
9697
}
9798
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/RuntimeMetadataEncoderImpl.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@
6666
import java.util.TreeSet;
6767
import java.util.function.BiConsumer;
6868
import java.util.function.Consumer;
69-
import java.util.stream.Collectors;
7069

70+
import com.oracle.svm.hosted.imagelayer.CapnProtoAdapters;
7171
import org.graalvm.collections.Pair;
7272
import org.graalvm.nativeimage.AnnotationAccess;
7373
import org.graalvm.nativeimage.ImageSingletons;
@@ -104,7 +104,6 @@
104104
import com.oracle.svm.hosted.annotation.TypeAnnotationValue;
105105
import com.oracle.svm.hosted.image.NativeImageCodeCache.ReflectionMetadataEncoderFactory;
106106
import com.oracle.svm.hosted.image.NativeImageCodeCache.RuntimeMetadataEncoder;
107-
import com.oracle.svm.hosted.imagelayer.SVMImageLayerLoader;
108107
import com.oracle.svm.hosted.imagelayer.SVMImageLayerSingletonLoader;
109108
import com.oracle.svm.hosted.imagelayer.SVMImageLayerWriter;
110109
import com.oracle.svm.hosted.meta.HostedField;
@@ -1312,8 +1311,8 @@ public static Object createFromLoader(ImageSingletonLoader loader) {
13121311
SVMImageLayerSingletonLoader.ImageSingletonLoaderImpl loaderImpl = (SVMImageLayerSingletonLoader.ImageSingletonLoaderImpl) loader;
13131312
var reader = loaderImpl.getSnapshotReader().getLayeredRuntimeMetadataSingleton();
13141313

1315-
Set<Integer> registeredMethods = SVMImageLayerLoader.streamInts(reader.getMethods()).boxed().collect(Collectors.toCollection(HashSet::new));
1316-
Set<Integer> registeredFields = SVMImageLayerLoader.streamInts(reader.getFields()).boxed().collect(Collectors.toCollection(HashSet::new));
1314+
Set<Integer> registeredMethods = CapnProtoAdapters.toCollection(reader.getMethods(), Integer::valueOf, HashSet::new);
1315+
Set<Integer> registeredFields = CapnProtoAdapters.toCollection(reader.getFields(), Integer::valueOf, HashSet::new);
13171316
return new LayeredRuntimeMetadataSingleton(registeredMethods, registeredFields);
13181317
}
13191318
}
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*
2+
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.hosted.imagelayer;
26+
27+
import java.util.Collection;
28+
import java.util.function.Consumer;
29+
import java.util.function.Function;
30+
import java.util.function.IntConsumer;
31+
import java.util.function.IntFunction;
32+
import java.util.function.Supplier;
33+
import java.util.function.ToIntFunction;
34+
35+
import com.oracle.svm.hosted.imagelayer.SharedLayerSnapshotCapnProtoSchemaHolder.PrimitiveArray;
36+
import com.oracle.svm.shaded.org.capnproto.PrimitiveList;
37+
import com.oracle.svm.shaded.org.capnproto.StructList;
38+
import com.oracle.svm.shaded.org.capnproto.StructReader;
39+
import com.oracle.svm.shaded.org.capnproto.TextList;
40+
41+
/**
42+
* Collection of adapters to interact with the Cap'n Proto internal value representation.
43+
*/
44+
public class CapnProtoAdapters {
45+
/**
46+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Int} reader
47+
* and pass them to the action.
48+
*/
49+
static void forEach(PrimitiveList.Int.Reader reader, IntConsumer action) {
50+
for (int i = 0; i < reader.size(); i++) {
51+
action.accept(reader.get(i));
52+
}
53+
}
54+
55+
/**
56+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.TextList} reader and pass
57+
* them to the action.
58+
*/
59+
public static void forEach(TextList.Reader reader, Consumer<String> action) {
60+
for (int i = 0; i < reader.size(); i++) {
61+
action.accept(reader.get(i).toString());
62+
}
63+
}
64+
65+
/**
66+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Int} reader,
67+
* apply the mapping function, then store them in the supplied array at the same index.
68+
*/
69+
static <T> T[] toArray(PrimitiveList.Int.Reader reader, IntFunction<? extends T> mapper, IntFunction<T[]> arrayGenerator) {
70+
T[] array = arrayGenerator.apply(reader.size());
71+
for (int i = 0; i < reader.size(); i++) {
72+
array[i] = mapper.apply(reader.get(i));
73+
}
74+
return array;
75+
}
76+
77+
/**
78+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.StructList} reader, apply
79+
* the mapping function, then store them in the supplied array at the same index.
80+
*/
81+
static <R, T> T[] toArray(StructList.Reader<R> reader, Function<? super R, ? extends T> mapper, IntFunction<T[]> arrayGenerator) {
82+
T[] array = arrayGenerator.apply(reader.size());
83+
for (int i = 0; i < reader.size(); i++) {
84+
array[i] = mapper.apply(reader.get(i));
85+
}
86+
return array;
87+
}
88+
89+
/**
90+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.TextList} reader, convert
91+
* them to {@link String}, apply the mapping function, then store them in the supplied array at
92+
* the same index.
93+
*/
94+
static <T> T[] toArray(TextList.Reader reader, Function<String, ? extends T> mapper, IntFunction<T[]> arrayGenerator) {
95+
T[] array = arrayGenerator.apply(reader.size());
96+
for (int i = 0; i < reader.size(); i++) {
97+
array[i] = mapper.apply(reader.get(i).toString());
98+
}
99+
return array;
100+
}
101+
102+
/**
103+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Int} reader,
104+
* apply the mapping function, then collect them in the supplied collection.
105+
*/
106+
public static <T, U extends Collection<T>> U toCollection(PrimitiveList.Int.Reader reader, IntFunction<? extends T> mapper, Supplier<U> collectionFactory) {
107+
U collection = collectionFactory.get();
108+
for (int i = 0; i < reader.size(); i++) {
109+
collection.add(mapper.apply(reader.get(i)));
110+
}
111+
return collection;
112+
}
113+
114+
/**
115+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.TextList} reader, convert
116+
* them to {@link String}, then collect them in the supplied collection.
117+
*/
118+
public static <U extends Collection<String>> U toCollection(TextList.Reader reader, Supplier<U> collectionFactory) {
119+
return toCollection(reader, (s) -> s, collectionFactory);
120+
}
121+
122+
/**
123+
* Iterate values from a {@link com.oracle.svm.shaded.org.capnproto.TextList} reader, convert
124+
* them to {@link String}, apply the mapping function, then collect them in the supplied
125+
* collection.
126+
*/
127+
public static <T, U extends Collection<T>> U toCollection(TextList.Reader reader, Function<String, ? extends T> mapper, Supplier<U> collectionFactory) {
128+
U collection = collectionFactory.get();
129+
for (int i = 0; i < reader.size(); i++) {
130+
collection.add(mapper.apply(reader.get(i).toString()));
131+
}
132+
return collection;
133+
}
134+
135+
/**
136+
* Extract values from a {@link PrimitiveArray} reader to the corresponding Java primitive
137+
* array.
138+
*/
139+
static Object toArray(PrimitiveArray.Reader reader) {
140+
return switch (reader.which()) {
141+
case Z -> toBooleanArray(reader.getZ());
142+
case B -> toByteArray(reader.getB());
143+
case S -> toShortArray(reader.getS());
144+
case C -> toCharArray(reader.getC());
145+
case I -> toIntArray(reader.getI());
146+
case F -> toFloatArray(reader.getF());
147+
case J -> toLongArray(reader.getJ());
148+
case D -> toDoubleArray(reader.getD());
149+
case _NOT_IN_SCHEMA -> throw new IllegalArgumentException("Unsupported kind: " + reader.which());
150+
};
151+
}
152+
153+
/**
154+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Boolean}
155+
* reader to a {@code boolean[]} array.
156+
*/
157+
protected static boolean[] toBooleanArray(PrimitiveList.Boolean.Reader booleanReader) {
158+
boolean[] booleanArray = new boolean[booleanReader.size()];
159+
for (int i = 0; i < booleanReader.size(); i++) {
160+
booleanArray[i] = booleanReader.get(i);
161+
}
162+
return booleanArray;
163+
}
164+
165+
/**
166+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Byte} reader
167+
* to a {@code byte[]} array.
168+
*/
169+
static byte[] toByteArray(PrimitiveList.Byte.Reader byteReader) {
170+
byte[] byteArray = new byte[byteReader.size()];
171+
for (int i = 0; i < byteReader.size(); i++) {
172+
byteArray[i] = byteReader.get(i);
173+
}
174+
return byteArray;
175+
}
176+
177+
/**
178+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Short} reader
179+
* to a {@code short[]} array.
180+
*/
181+
static short[] toShortArray(PrimitiveList.Short.Reader shortReader) {
182+
short[] shortArray = new short[shortReader.size()];
183+
for (int i = 0; i < shortReader.size(); i++) {
184+
shortArray[i] = shortReader.get(i);
185+
}
186+
return shortArray;
187+
}
188+
189+
/**
190+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Short} reader
191+
* to a {@code char[]} array.
192+
*/
193+
static char[] toCharArray(PrimitiveList.Short.Reader charReader) {
194+
char[] charArray = new char[charReader.size()];
195+
for (int i = 0; i < charReader.size(); i++) {
196+
charArray[i] = (char) charReader.get(i);
197+
}
198+
return charArray;
199+
}
200+
201+
/**
202+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Int} reader to
203+
* a {@code int[]} array.
204+
*/
205+
public static int[] toIntArray(PrimitiveList.Int.Reader intReader) {
206+
int[] intArray = new int[intReader.size()];
207+
for (int i = 0; i < intReader.size(); i++) {
208+
intArray[i] = intReader.get(i);
209+
}
210+
return intArray;
211+
}
212+
213+
/**
214+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Float} reader
215+
* to a {@code float[]} array.
216+
*/
217+
static float[] toFloatArray(PrimitiveList.Float.Reader floatReader) {
218+
float[] floatArray = new float[floatReader.size()];
219+
for (int i = 0; i < floatReader.size(); i++) {
220+
floatArray[i] = floatReader.get(i);
221+
}
222+
return floatArray;
223+
}
224+
225+
/**
226+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Long} reader
227+
* to a {@code long[]} array.
228+
*/
229+
static long[] toLongArray(PrimitiveList.Long.Reader longReader) {
230+
long[] longArray = new long[longReader.size()];
231+
for (int i = 0; i < longReader.size(); i++) {
232+
longArray[i] = longReader.get(i);
233+
}
234+
return longArray;
235+
}
236+
237+
/**
238+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.PrimitiveList.Double} reader
239+
* to a {@code double[]} array.
240+
*/
241+
static double[] toDoubleArray(PrimitiveList.Double.Reader doubleReader) {
242+
double[] doubleArray = new double[doubleReader.size()];
243+
for (int i = 0; i < doubleReader.size(); i++) {
244+
doubleArray[i] = doubleReader.get(i);
245+
}
246+
return doubleArray;
247+
}
248+
249+
/**
250+
* Extract values from a {@link com.oracle.svm.shaded.org.capnproto.TextList} reader to a
251+
* {@code String[]} array.
252+
*/
253+
public static String[] toStringArray(TextList.Reader reader) {
254+
return toArray(reader, (s) -> s, String[]::new);
255+
}
256+
257+
/**
258+
* Find the value containing the given {@code key} in a
259+
* {@link com.oracle.svm.shaded.org.capnproto.StructList} reader, applying the
260+
* {@code keyExtractor} to searched values. The input list should be sorted by the {@code key}
261+
* and contain no duplicates.
262+
*
263+
* @return the found value or {@code null}
264+
*/
265+
static <T extends StructReader> T binarySearchUnique(int key, StructList.Reader<T> sortedList, ToIntFunction<T> keyExtractor) {
266+
int low = 0;
267+
int high = sortedList.size() - 1;
268+
269+
int prevMid = -1;
270+
int prevKey = 0;
271+
while (low <= high) {
272+
int mid = (low + high) >>> 1;
273+
T midStruct = sortedList.get(mid);
274+
int midKey = keyExtractor.applyAsInt(midStruct);
275+
276+
assert prevMid == -1 || (mid < prevMid && midKey < prevKey) || (mid > prevMid && midKey > prevKey) : "unsorted or contains duplicates";
277+
278+
if (midKey < key) {
279+
low = mid + 1;
280+
} else if (midKey > key) {
281+
high = mid - 1;
282+
} else {
283+
return midStruct;
284+
}
285+
286+
prevMid = mid;
287+
prevKey = midKey;
288+
}
289+
return null;
290+
}
291+
}

0 commit comments

Comments
 (0)