Skip to content

Commit cf86e02

Browse files
committed
Fix lambda stable names check.
1 parent 835ee7b commit cf86e02

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/lambda/LambdaProxyRenamingSubstitutionProcessor.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ private LambdaSubstitutionType getSubstitution(ResolvedJavaType original) {
7171
}
7272

7373
/**
74-
* Finds a unique name for a lambda proxies with a same target originating from the same class.
75-
*
76-
* NOTE: the name truly stable only in a single threaded build.
74+
* Finds a unique name for lambda proxies with the same target originating from the same class.
75+
* Method {@link LambdaUtils#findStableLambdaName(ResolvedJavaType)} hashes over a lambda type
76+
* descriptor (invoked methods, constructor parameters, implemented interfaces) in an effort to
77+
* find enough differences that can yield a unique name. However, this can still lead to
78+
* conflicts. To create unique names when conflicts are found the naming scheme uses a counter:
79+
* first a 0 is added to the end of the generated lambda name, and it is incremented until a
80+
* unique name is found. This also means that the name is truly stable only in a single threaded
81+
* build, i.e., when conflicts are discovered in the same order. Since the conflict counter
82+
* doesn't have an upper limit the generated lambda name length can vary but the base hash is
83+
* always 32 hex digits long.
7784
*/
7885
private String findUniqueLambdaProxyName(String lambdaTargetName) {
7986
synchronized (uniqueLambdaProxyNames) {
@@ -91,7 +98,22 @@ private String findUniqueLambdaProxyName(String lambdaTargetName) {
9198
}
9299
}
93100

101+
/**
102+
* Find the base name generated by {@link LambdaUtils#findStableLambdaName(ResolvedJavaType)} by
103+
* subtracting the counter injected by {@link #findUniqueLambdaProxyName(String)}. Note that the
104+
* counter can be on multiple digits but the base hash is always 32 hex digits long.
105+
*/
106+
private static String getBaseName(String lambdaTargetName) {
107+
int startIndexOfHash = lambdaTargetName.indexOf(LambdaUtils.ADDRESS_PREFIX) + LambdaUtils.ADDRESS_PREFIX.length();
108+
return lambdaTargetName.substring(0, startIndexOfHash + 32);
109+
}
110+
111+
/**
112+
* Check if this lambda's name conflicted with any other entries, i.e., if the conflict counter
113+
* ever got to 1.
114+
*/
94115
public boolean isNameAlwaysStable(String lambdaTargetName) {
95-
return !uniqueLambdaProxyNames.contains(lambdaTargetName.substring(0, lambdaTargetName.length() - 1) + "1;");
116+
String baseName = getBaseName(lambdaTargetName);
117+
return !uniqueLambdaProxyNames.contains(baseName + "1;");
96118
}
97119
}

0 commit comments

Comments
 (0)