Skip to content

Commit

Permalink
Track JDK locales in the agent
Browse files Browse the repository at this point in the history
  • Loading branch information
loicottet committed Jan 25, 2024
1 parent e1a6add commit 568aa26
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -55,4 +55,6 @@ public interface RuntimeResourceSupport {
void addResourceBundles(ConfigurationCondition condition, String name);

void addResourceBundles(ConfigurationCondition condition, String basename, Collection<Locale> locales);

void addLocale(Locale locale);
}
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,13 @@ private static boolean getBundleImpl(JNIEnvironment jni, JNIObjectHandle thread,
return true;
}

private static boolean loadBundleOf(JNIEnvironment jni, JNIObjectHandle thread, Breakpoint bp, InterceptedState state) {
JNIObjectHandle callerClass = state.getDirectCallerClass();
JNIObjectHandle locale = getObjectArgument(thread, 1);
traceReflectBreakpoint(jni, nullHandle(), nullHandle(), callerClass, bp.specification.methodName, true, state.getFullStackTraceOrNull(), readLocaleTag(jni, locale));
return true;
}

private static String readLocaleTag(JNIEnvironment jni, JNIObjectHandle locale) {
JNIObjectHandle languageTag = Support.callObjectMethod(jni, locale, agent.handles().javaUtilLocaleToLanguageTag);
if (clearException(jni)) {
Expand Down Expand Up @@ -1559,6 +1566,9 @@ private interface BreakpointHandler {
"getBundleImpl",
"(Ljava/lang/Module;Ljava/lang/Module;Ljava/lang/String;Ljava/util/Locale;Ljava/util/ResourceBundle$Control;)Ljava/util/ResourceBundle;",
BreakpointInterceptor::getBundleImpl),
brk("sun/util/resources/Bundles", "loadBundleOf",
"(Ljava/lang/String;Ljava/util/Locale;Lsun/util/resources/Bundles$Strategy;)Ljava/util/ResourceBundle;",
BreakpointInterceptor::loadBundleOf),

// In Java 9+, these are Java methods that call private methods
optionalBrk("jdk/internal/misc/Unsafe", "objectFieldOffset", "(Ljava/lang/Class;Ljava/lang/String;)J", BreakpointInterceptor::objectFieldOffsetByName),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ public void addResourceBundles(ConfigurationCondition condition, String basename
public void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className) {

}

@Override
public void addLocale(Locale locale) {

}
};

ResourceConfigurationParser rcp = new ResourceConfigurationParser(registry, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ public void addResourceBundles(ConfigurationCondition condition, String basename
public void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className) {
configuration.addClassResourceBundle(condition, basename, className);
}

@Override
public void addLocale(Locale locale) {
configuration.addLocale(locale.toLanguageTag());
}
}

public static final class BundleConfiguration {
Expand All @@ -113,6 +118,8 @@ private BundleConfiguration(BundleConfiguration other) {
private final ConcurrentMap<ConditionalElement<String>, Pattern> ignoredResources = new ConcurrentHashMap<>();
private final ConcurrentMap<ConditionalElement<String>, BundleConfiguration> bundles = new ConcurrentHashMap<>();

private final Set<String> locales = ConcurrentHashMap.newKeySet();

public ResourceConfiguration() {
}

Expand All @@ -122,6 +129,7 @@ public ResourceConfiguration(ResourceConfiguration other) {
for (Map.Entry<ConditionalElement<String>, BundleConfiguration> entry : other.bundles.entrySet()) {
bundles.put(entry.getKey(), new BundleConfiguration(entry.getValue()));
}
locales.addAll(other.locales);
}

@Override
Expand All @@ -134,20 +142,23 @@ public void subtract(ResourceConfiguration other) {
addedResources.keySet().removeAll(other.addedResources.keySet());
ignoredResources.keySet().removeAll(other.ignoredResources.keySet());
bundles.keySet().removeAll(other.bundles.keySet());
locales.removeAll(other.locales);
}

@Override
protected void merge(ResourceConfiguration other) {
addedResources.putAll(other.addedResources);
ignoredResources.putAll(other.ignoredResources);
bundles.putAll(other.bundles);
locales.addAll(other.locales);
}

@Override
protected void intersect(ResourceConfiguration other) {
addedResources.keySet().retainAll(other.addedResources.keySet());
ignoredResources.keySet().retainAll(other.ignoredResources.keySet());
bundles.keySet().retainAll(other.bundles.keySet());
locales.retainAll(other.locales);
}

@Override
Expand All @@ -167,6 +178,7 @@ public void mergeConditional(ConfigurationCondition condition, ResourceConfigura
for (Map.Entry<ConditionalElement<String>, BundleConfiguration> entry : other.bundles.entrySet()) {
bundles.put(new ConditionalElement<>(condition, entry.getKey().getElement()), new BundleConfiguration(entry.getValue()));
}
locales.addAll(other.locales);
}

public void addResourcePattern(ConfigurationCondition condition, String pattern) {
Expand Down Expand Up @@ -197,6 +209,10 @@ public void addBundle(ConfigurationCondition condition, String baseName, String
config.locales.add(queriedLocale);
}

public void addLocale(String locale) {
locales.add(locale);
}

private BundleConfiguration getOrCreateBundleConfig(ConfigurationCondition condition, String baseName) {
ConditionalElement<String> key = new ConditionalElement<>(condition, baseName);
return bundles.computeIfAbsent(key, cond -> new BundleConfiguration(condition, baseName));
Expand Down Expand Up @@ -238,6 +254,9 @@ public void printJson(JsonWriter writer) throws IOException {
writer.append('}').append(',').newline();
writer.quote("bundles").append(':');
JsonPrinter.printCollection(writer, bundles.keySet(), ConditionalElement.comparator(), (p, w) -> printResourceBundle(bundles.get(p), w));
writer.append(',').newline();
writer.quote("locales").append(':');
JsonPrinter.printCollection(writer, locales, Comparator.naturalOrder(), (l, w) -> w.quote(l));
writer.unindent().newline().append('}');
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

import org.graalvm.collections.EconomicMap;
Expand All @@ -47,6 +48,7 @@
import jdk.vm.ci.meta.MetaUtil;

class ReflectionProcessor extends AbstractProcessor {
private static final List<String> DEFAULT_LOCALE_TAGS = List.of(Locale.ROOT.toLanguageTag(), Locale.ENGLISH.toLanguageTag(), Locale.US.toLanguageTag());
private final AccessAdvisor advisor;

ReflectionProcessor(AccessAdvisor advisor) {
Expand Down Expand Up @@ -266,6 +268,14 @@ public void processEntry(EconomicMap<String, ?> entry, ConfigurationSet configur
}
break;
}
case "loadBundleOf": {
expectSize(args, 1);
String localeTag = (String) args.get(0);
if (!DEFAULT_LOCALE_TAGS.contains(localeTag)) {
resourceConfiguration.addLocale(localeTag);
}
break;
}
case "allocateInstance": {
configuration.getOrCreateType(condition, clazz).setUnsafeAllocated();
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ public void parseAndRegister(Object json, URI origin) {
private void parseTopLevelObject(EconomicMap<String, Object> obj) {
Object resourcesObject = null;
Object bundlesObject = null;
Object localesObject = null;
MapCursor<String, Object> cursor = obj.getEntries();
while (cursor.advance()) {
if ("resources".equals(cursor.getKey())) {
resourcesObject = cursor.getValue();
} else if ("bundles".equals(cursor.getKey())) {
bundlesObject = cursor.getValue();
} else if ("locales".equals(cursor.getKey())) {
localesObject = cursor.getValue();
}
}
if (resourcesObject != null) {
Expand Down Expand Up @@ -95,6 +98,12 @@ private void parseTopLevelObject(EconomicMap<String, Object> obj) {
parseBundle(bundle);
}
}
if (localesObject != null) {
List<Object> locales = asList(localesObject, "Attribute 'locales' must be a list of locales");
for (Object locale : locales) {
registry.addLocale(parseLocale(locale));
}
}
}

private void parseBundle(Object bundle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
import com.oracle.svm.core.jdk.localization.LocalizationSupport;
import com.oracle.svm.core.jdk.localization.substitutions.modes.JvmLocaleMode;
import com.oracle.svm.core.jdk.localization.substitutions.modes.OptimizedLocaleMode;
import com.oracle.svm.core.jdk.resources.MissingResourceRegistrationUtils;

import sun.util.resources.Bundles.Strategy;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,11 @@ public void addResourceBundles(ConfigurationCondition condition, String basename
registerConditionalConfiguration(condition, () -> ImageSingletons.lookup(LocalizationFeature.class).prepareBundle(basename, locales));
}

@Override
public void addLocale(Locale locale) {
ImageSingletons.lookup(LocalizationFeature.class).addLocale(locale);
}

/*
* It is possible that one resource can be registered under different conditions
* (typeReachable). In some cases, few conditions will be satisfied, and we will try to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,10 @@ protected void addResourceBundles() {
}
}

public void addLocale(Locale locale) {
allLocales.add(locale);
}

@Platforms(Platform.HOSTED_ONLY.class)
private void processRequestedBundle(String input) {
int splitIndex = input.indexOf('_');
Expand Down

0 comments on commit 568aa26

Please sign in to comment.