7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.options;
26
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Formatter;
30 import java.util.List;
31 import java.util.ServiceLoader;
32
33 import jdk.internal.vm.compiler.collections.EconomicMap;
34 import jdk.internal.vm.compiler.collections.MapCursor;
35
36 /**
37 * This class contains methods for parsing Graal options and matching them against a set of
38 * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}.
39 */
40 public class OptionsParser {
41
42 /**
43 * Gets an iterable composed of the {@link ServiceLoader}s to be used when looking for
44 * {@link OptionDescriptors} providers.
45 */
46 public static Iterable<OptionDescriptors> getOptionsLoader() {
47 boolean java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
48 ClassLoader loader;
49 if (java8OrEarlier) {
50 // On JDK 8, Graal and its extensions are loaded by same class loader.
51 loader = OptionDescriptors.class.getClassLoader();
52 } else {
53 /*
54 * The Graal module (i.e., jdk.internal.vm.compiler) is loaded by the platform class
55 * loader as of JDK 9. Modules that depend on and extend Graal are loaded by the app
56 * class loader. As such, we need to start the provider search at the app class loader
57 * instead of the platform class loader.
58 */
59 loader = ClassLoader.getSystemClassLoader();
60 }
61 return ServiceLoader.load(OptionDescriptors.class, loader);
62 }
63
64 /**
65 * Parses a map representing assignments of values to options.
66 *
67 * @param optionSettings option settings (i.e., assignments of values to options)
68 * @param values the object in which to store the parsed values
69 * @param loader source of the available {@link OptionDescriptors}
70 * @throws IllegalArgumentException if there's a problem parsing {@code option}
71 */
72 public static void parseOptions(EconomicMap<String, String> optionSettings, EconomicMap<OptionKey<?>, Object> values, Iterable<OptionDescriptors> loader) {
73 if (optionSettings != null && !optionSettings.isEmpty()) {
74 MapCursor<String, String> cursor = optionSettings.getEntries();
75 while (cursor.advance()) {
76 parseOption(cursor.getKey(), cursor.getValue(), values, loader);
77 }
78 }
79 }
80
81 /**
161 throw new IllegalArgumentException("Non empty value required for option '" + name + "'");
162 }
163 try {
164 if (optionType == Float.class) {
165 value = Float.parseFloat(valueString);
166 } else if (optionType == Double.class) {
167 value = Double.parseDouble(valueString);
168 } else if (optionType == Integer.class) {
169 value = Integer.valueOf((int) parseLong(valueString));
170 } else if (optionType == Long.class) {
171 value = Long.valueOf(parseLong(valueString));
172 } else {
173 throw new IllegalArgumentException("Wrong value for option '" + name + "'");
174 }
175 } catch (NumberFormatException nfe) {
176 throw new IllegalArgumentException("Value for option '" + name + "' has invalid number format: " + valueString);
177 }
178 }
179 }
180
181 desc.optionKey.update(values, value);
182 }
183
184 private static long parseLong(String v) {
185 String valueString = v.toLowerCase();
186 long scale = 1;
187 if (valueString.endsWith("k")) {
188 scale = 1024L;
189 } else if (valueString.endsWith("m")) {
190 scale = 1024L * 1024L;
191 } else if (valueString.endsWith("g")) {
192 scale = 1024L * 1024L * 1024L;
193 } else if (valueString.endsWith("t")) {
194 scale = 1024L * 1024L * 1024L * 1024L;
195 }
196
197 if (scale != 1) {
198 /* Remove trailing scale character. */
199 valueString = valueString.substring(0, valueString.length() - 1);
200 }
201
|
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.options;
26
27 import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE;
28 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
29
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Formatter;
33 import java.util.List;
34 import java.util.ServiceLoader;
35
36 import jdk.internal.vm.compiler.collections.EconomicMap;
37 import jdk.internal.vm.compiler.collections.MapCursor;
38
39 /**
40 * This class contains methods for parsing Graal options and matching them against a set of
41 * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded via a {@link ServiceLoader}.
42 */
43 public class OptionsParser {
44
45 private static volatile List<OptionDescriptors> cachedOptionDescriptors;
46
47 /**
48 * Gets an iterable of available {@link OptionDescriptors}.
49 */
50 public static Iterable<OptionDescriptors> getOptionsLoader() {
51 if (IS_IN_NATIVE_IMAGE || cachedOptionDescriptors != null) {
52 return cachedOptionDescriptors;
53 }
54 boolean java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0;
55 ClassLoader loader;
56 if (java8OrEarlier) {
57 // On JDK 8, Graal and its extensions are loaded by same class loader.
58 loader = OptionDescriptors.class.getClassLoader();
59 } else {
60 /*
61 * The Graal module (i.e., jdk.internal.vm.compiler) is loaded by the platform class
62 * loader as of JDK 9. Modules that depend on and extend Graal are loaded by the app
63 * class loader. As such, we need to start the provider search at the app class loader
64 * instead of the platform class loader.
65 */
66 loader = ClassLoader.getSystemClassLoader();
67 }
68 Iterable<OptionDescriptors> result = ServiceLoader.load(OptionDescriptors.class, loader);
69 if (IS_BUILDING_NATIVE_IMAGE) {
70 ArrayList<OptionDescriptors> optionDescriptors = new ArrayList<>();
71 for (OptionDescriptors descriptors : result) {
72 optionDescriptors.add(descriptors);
73 }
74 OptionsParser.cachedOptionDescriptors = optionDescriptors;
75 }
76 return result;
77 }
78
79 /**
80 * Parses a map representing assignments of values to options.
81 *
82 * @param optionSettings option settings (i.e., assignments of values to options)
83 * @param values the object in which to store the parsed values
84 * @param loader source of the available {@link OptionDescriptors}
85 * @throws IllegalArgumentException if there's a problem parsing {@code option}
86 */
87 public static void parseOptions(EconomicMap<String, String> optionSettings, EconomicMap<OptionKey<?>, Object> values, Iterable<OptionDescriptors> loader) {
88 if (optionSettings != null && !optionSettings.isEmpty()) {
89 MapCursor<String, String> cursor = optionSettings.getEntries();
90 while (cursor.advance()) {
91 parseOption(cursor.getKey(), cursor.getValue(), values, loader);
92 }
93 }
94 }
95
96 /**
176 throw new IllegalArgumentException("Non empty value required for option '" + name + "'");
177 }
178 try {
179 if (optionType == Float.class) {
180 value = Float.parseFloat(valueString);
181 } else if (optionType == Double.class) {
182 value = Double.parseDouble(valueString);
183 } else if (optionType == Integer.class) {
184 value = Integer.valueOf((int) parseLong(valueString));
185 } else if (optionType == Long.class) {
186 value = Long.valueOf(parseLong(valueString));
187 } else {
188 throw new IllegalArgumentException("Wrong value for option '" + name + "'");
189 }
190 } catch (NumberFormatException nfe) {
191 throw new IllegalArgumentException("Value for option '" + name + "' has invalid number format: " + valueString);
192 }
193 }
194 }
195
196 desc.getOptionKey().update(values, value);
197 }
198
199 private static long parseLong(String v) {
200 String valueString = v.toLowerCase();
201 long scale = 1;
202 if (valueString.endsWith("k")) {
203 scale = 1024L;
204 } else if (valueString.endsWith("m")) {
205 scale = 1024L * 1024L;
206 } else if (valueString.endsWith("g")) {
207 scale = 1024L * 1024L * 1024L;
208 } else if (valueString.endsWith("t")) {
209 scale = 1024L * 1024L * 1024L * 1024L;
210 }
211
212 if (scale != 1) {
213 /* Remove trailing scale character. */
214 valueString = valueString.substring(0, valueString.length() - 1);
215 }
216
|