@@ -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