@@ -197,7 +197,38 @@ private static String nodeFieldName(NodeExecutionData execution) {
197
197
198
198
/* Whether a new class should be generated for specialization instance fields. */
199
199
private static boolean useSpecializationClass (SpecializationData specialization ) {
200
- return specialization .hasMultipleInstances () && (specialization .getCaches ().size () > 3 || specialization .getMaximumNumberOfInstances () > 1 );
200
+ int size = 0 ;
201
+ for (CacheExpression expression : specialization .getCaches ()) {
202
+ TypeMirror type = expression .getParameter ().getType ();
203
+ if (ElementUtils .isPrimitive (type )) {
204
+ switch (type .getKind ()) {
205
+ case BOOLEAN :
206
+ case BYTE :
207
+ size ++;
208
+ break ;
209
+ case CHAR :
210
+ case SHORT :
211
+ size += 2 ;
212
+ break ;
213
+ case INT :
214
+ case FLOAT :
215
+ size += 4 ;
216
+ break ;
217
+ case LONG :
218
+ case DOUBLE :
219
+ size += 8 ;
220
+ break ;
221
+ }
222
+ } else {
223
+ size += 4 ;
224
+ }
225
+ }
226
+ // if we exceed the size of two references we generate a class
227
+ if (size > 8 ) {
228
+ return true ;
229
+ }
230
+ // we need a data class if we need to support multiple specialization instances
231
+ return specialization .getMaximumNumberOfInstances () > 1 ;
201
232
}
202
233
203
234
private static boolean needsFrame (List <SpecializationData > specializations ) {
@@ -392,7 +423,9 @@ private void createFields(CodeTypeElement clazz) {
392
423
Class <?> annotationType ;
393
424
if (useNode ) {
394
425
annotationType = Child .class ;
395
- cacheType .add (createNodeField (null , cacheType .asType (), "next_" , Child .class ));
426
+ if (specialization .getMaximumNumberOfInstances () > 1 ) {
427
+ cacheType .add (createNodeField (null , cacheType .asType (), "next_" , Child .class ));
428
+ }
396
429
397
430
CodeExecutableElement getNodeCost = new CodeExecutableElement (modifiers (PUBLIC ),
398
431
context .getType (NodeCost .class ), "getCost" );
@@ -401,7 +434,9 @@ private void createFields(CodeTypeElement clazz) {
401
434
cacheType .add (getNodeCost );
402
435
} else {
403
436
annotationType = CompilationFinal .class ;
404
- cacheType .add (createNodeField (null , cacheType .asType (), "next_" , null , FINAL ));
437
+ if (specialization .getMaximumNumberOfInstances () > 1 ) {
438
+ cacheType .add (createNodeField (null , cacheType .asType (), "next_" , null , FINAL ));
439
+ }
405
440
}
406
441
407
442
cacheType .getEnclosedElements ().addAll (fields );
@@ -1220,7 +1255,7 @@ private Element createGetCostMethod() {
1220
1255
1221
1256
List <CodeTree > additionalChecks = new ArrayList <>();
1222
1257
for (SpecializationData specialization : reachableSpecializations ) {
1223
- if (useSpecializationClass (specialization )) {
1258
+ if (useSpecializationClass (specialization ) && specialization . getMaximumNumberOfInstances () > 1 ) {
1224
1259
CodeTree check = builder .create ().string ("this." , createSpecializationFieldName (specialization ), " == null || " , "this." , createSpecializationFieldName (specialization ),
1225
1260
".next_ == null" ).build ();
1226
1261
additionalChecks .add (check );
@@ -1871,19 +1906,19 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
1871
1906
duplicationGuard = combineTrees (" && " , assumptionGuards );
1872
1907
}
1873
1908
1874
- String name = createSpecializationLocalName (specialization );
1909
+ String specializationLocalName = createSpecializationLocalName (specialization );
1875
1910
if (useSpecializationClass ) {
1876
1911
if (specialization .getMaximumNumberOfInstances () > 1 ) {
1877
1912
builder .declaration ("int" , countName , CodeTreeBuilder .singleString ("0" ));
1878
1913
}
1879
- builder .declaration (createSpecializationTypeName (specialization ), name , CodeTreeBuilder .singleString (createSpecializationFieldName (specialization )));
1914
+ builder .declaration (createSpecializationTypeName (specialization ), specializationLocalName , CodeTreeBuilder .singleString (createSpecializationFieldName (specialization )));
1880
1915
builder .startIf ().tree (stateCheck ).end ().startBlock ();
1881
1916
if (specialization .getMaximumNumberOfInstances () > 1 ) {
1882
1917
builder .startWhile ();
1883
1918
} else {
1884
1919
builder .startIf ();
1885
1920
}
1886
- builder .string (name , " != null" );
1921
+ builder .string (specializationLocalName , " != null" );
1887
1922
builder .end ();
1888
1923
builder .startBlock ();
1889
1924
} else {
@@ -1904,10 +1939,10 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
1904
1939
1905
1940
if (useSpecializationClass ) {
1906
1941
if (specialization .getMaximumNumberOfInstances () > 1 ) {
1907
- builder .startStatement ().string (name , " = " , name , ".next_" ).end ();
1942
+ builder .startStatement ().string (specializationLocalName , " = " , specializationLocalName , ".next_" ).end ();
1908
1943
builder .statement (countName + "++" );
1909
1944
} else {
1910
- builder .statement (name + " = null" );
1945
+ builder .statement (specializationLocalName + " = null" );
1911
1946
}
1912
1947
1913
1948
builder .end ();
@@ -1995,9 +2030,14 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
1995
2030
}
1996
2031
1997
2032
builder .startStatement ();
2033
+ if (specialization .getMaximumNumberOfInstances () <= 1 ) {
2034
+ builder .string (createSpecializationTypeName (specialization )).string (" " );
2035
+ }
1998
2036
builder .string (createSpecializationLocalName (specialization ), " = " );
1999
2037
builder .startNew (createSpecializationTypeName (specialization ));
2000
- builder .string (createSpecializationFieldName (specialization ));
2038
+ if (specialization .getMaximumNumberOfInstances () > 1 ) {
2039
+ builder .string (createSpecializationFieldName (specialization ));
2040
+ }
2001
2041
}
2002
2042
2003
2043
List <CodeTree > stateParameters = new ArrayList <>();
@@ -2149,7 +2189,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
2149
2189
CodeTree guards = methodGuardAndAssertions [0 ];
2150
2190
CodeTree guardAssertions = methodGuardAndAssertions [1 ];
2151
2191
2152
- if (useSpecializationClass ) {
2192
+ if (useSpecializationClass && specialization . getMaximumNumberOfInstances () > 1 ) {
2153
2193
String name = createSpecializationLocalName (specialization );
2154
2194
builder .declaration (createSpecializationTypeName (specialization ), name , CodeTreeBuilder .singleString (createSpecializationFieldName (specialization )));
2155
2195
builder .startWhile ();
@@ -2185,7 +2225,7 @@ private CodeTree visitSpecializationGroup(CodeTreeBuilder parent, Specialization
2185
2225
builder .end ();
2186
2226
}
2187
2227
2188
- if (useSpecializationClass ) {
2228
+ if (useSpecializationClass && specialization . getMaximumNumberOfInstances () > 1 ) {
2189
2229
String name = createSpecializationLocalName (specialization );
2190
2230
builder .startStatement ().string (name , " = " , name , ".next_" ).end ();
2191
2231
}
0 commit comments