Skip to content

Commit c87b28c

Browse files
committed
[GR-69858] Publish reflection metadata atomically
1 parent 2fea0f1 commit c87b28c

1 file changed

Lines changed: 16 additions & 15 deletions

File tree

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ private void registerClass(AccessCondition condition, ConfigurationMemberAccessi
327327
types.compute(analysisType, (_, td) -> {
328328
TypeData typeData = td == null ? new TypeData() : td;
329329

330-
ConfigurationMemberAccessibility previous = typeData.registerAs(accessibility);
330+
ConfigurationMemberAccessibility previous = typeData.register(accessibility, cnd, preserved);
331331
if (previous == null) {
332332
registerTypesForHeapType(analysisType);
333333
typeData.registerLinkageError(linkType(analysisType));
@@ -340,7 +340,6 @@ private void registerClass(AccessCondition condition, ConfigurationMemberAccessi
340340
if (previous == null || !previous.includes(QUERIED)) {
341341
registerTypeForRuntimeAccess(analysisType);
342342
}
343-
typeData.updateDynamicAccessMetadata(cnd, preserved, accessibility);
344343
}
345344
if (accessibility == ACCESSED) {
346345
if (previous == null || !previous.includes(ACCESSED) || !preserved && typeData.dynamicAccess.isPreserved()) {
@@ -592,7 +591,7 @@ private void registerMethod(AccessCondition condition, ConfigurationMemberAccess
592591
methods.compute(analysisMethod, (aMethod, md) -> {
593592
ElementData data = md != null ? md : new ElementData();
594593

595-
ConfigurationMemberAccessibility previous = data.registerAs(accessibility);
594+
ConfigurationMemberAccessibility previous = data.register(accessibility, cnd, preserved);
596595
if (previous == null) {
597596
registerTypesForMethod(aMethod);
598597
}
@@ -607,9 +606,6 @@ private void registerMethod(AccessCondition condition, ConfigurationMemberAccess
607606
checkHidingMethods(aMethod);
608607
}
609608
}
610-
if (accessibility.includes(QUERIED)) {
611-
data.updateDynamicAccessMetadata(cnd, preserved, accessibility);
612-
}
613609
if (accessibility.includes(ACCESSED)) {
614610
if ((previous == null || !previous.includes(ACCESSED))) {
615611
registerMethodAccessor(aMethod);
@@ -775,7 +771,7 @@ private void registerField(AccessCondition condition, ConfigurationMemberAccessi
775771
abortIfSealed();
776772
ElementData data = fd != null ? fd : new ElementData();
777773

778-
ConfigurationMemberAccessibility previous = data.registerAs(accessibility);
774+
ConfigurationMemberAccessibility previous = data.register(accessibility, cnd, preserved);
779775
if (previous == null) {
780776
registerTypesForField(analysisField);
781777
}
@@ -791,9 +787,6 @@ private void registerField(AccessCondition condition, ConfigurationMemberAccessi
791787
checkHidingFields(analysisField);
792788
}
793789
}
794-
if (accessibility.includes(QUERIED)) {
795-
data.updateDynamicAccessMetadata(cnd, preserved, accessibility);
796-
}
797790
if (accessibility.includes(ACCESSED)) {
798791
if (previous == null || !previous.includes(ACCESSED)) {
799792
/*
@@ -1916,23 +1909,31 @@ private static class ElementData {
19161909
/* Query metadata keeps members discoverable but must not satisfy guarded access. */
19171910
boolean accessMetadata = false;
19181911

1919-
ConfigurationMemberAccessibility registerAs(ConfigurationMemberAccessibility newAccessibility) {
1912+
/*
1913+
* Registration tasks and feature queries run concurrently during analysis. Publish the
1914+
* accessibility and its dynamic-access metadata atomically so readers cannot observe a
1915+
* queried element before the corresponding metadata is installed.
1916+
*/
1917+
synchronized ConfigurationMemberAccessibility register(ConfigurationMemberAccessibility newAccessibility, AccessCondition condition, boolean preserved) {
19201918
ConfigurationMemberAccessibility previous = accessibility;
19211919
if (previous == null || !previous.includes(newAccessibility)) {
19221920
accessibility = newAccessibility;
19231921
}
1922+
if (newAccessibility.includes(QUERIED)) {
1923+
updateDynamicAccessMetadata(condition, preserved, newAccessibility);
1924+
}
19241925
return previous;
19251926
}
19261927

1927-
boolean isRegisteredAs(ConfigurationMemberAccessibility target) {
1928+
synchronized boolean isRegisteredAs(ConfigurationMemberAccessibility target) {
19281929
return accessibility != null && accessibility.includes(target);
19291930
}
19301931

1931-
ConfigurationMemberAccessibility getAccessibility() {
1932+
synchronized ConfigurationMemberAccessibility getAccessibility() {
19321933
return accessibility;
19331934
}
19341935

1935-
void updateDynamicAccessMetadata(AccessCondition condition, boolean preserved, ConfigurationMemberAccessibility newAccessibility) {
1936+
private void updateDynamicAccessMetadata(AccessCondition condition, boolean preserved, ConfigurationMemberAccessibility newAccessibility) {
19361937
boolean accessRegistration = newAccessibility.includes(ACCESSED);
19371938
if (dynamicAccess == null || accessRegistration && !accessMetadata) {
19381939
dynamicAccess = null;
@@ -1947,7 +1948,7 @@ void updateDynamicAccessMetadata(AccessCondition condition, boolean preserved, C
19471948
dynamicAccess = RuntimeDynamicAccessMetadata.addCondition(dynamicAccess, condition, true).withPreserved(metadataPreserved);
19481949
}
19491950

1950-
RuntimeDynamicAccessMetadata getDynamicAccessMetadata() {
1951+
synchronized RuntimeDynamicAccessMetadata getDynamicAccessMetadata() {
19511952
VMError.guarantee((dynamicAccess != null) == isRegisteredAs(QUERIED), "Dynamic access metadata should be present on queried elements");
19521953
return dynamicAccess != null ? dynamicAccess : RuntimeDynamicAccessMetadata.alwaysAvailable(false);
19531954
}

0 commit comments

Comments
 (0)