comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java @ 18753:f6b8787dc113

Truffle-DSL: replace complex factory system with a much simpler version
author Christian Humer <christian.humer@gmail.com>
date Mon, 29 Dec 2014 23:38:21 +0100
parents 1acaa69ff61b
children 59bf50cc5a32
comparison
equal deleted inserted replaced
18752:1acaa69ff61b 18753:f6b8787dc113
30 import javax.lang.model.element.*; 30 import javax.lang.model.element.*;
31 import javax.lang.model.type.*; 31 import javax.lang.model.type.*;
32 import javax.lang.model.util.*; 32 import javax.lang.model.util.*;
33 33
34 import com.oracle.truffle.api.nodes.*; 34 import com.oracle.truffle.api.nodes.*;
35 import com.oracle.truffle.dsl.processor.*;
35 import com.oracle.truffle.dsl.processor.java.*; 36 import com.oracle.truffle.dsl.processor.java.*;
36 import com.oracle.truffle.dsl.processor.java.model.*; 37 import com.oracle.truffle.dsl.processor.java.model.*;
37 import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; 38 import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror;
38 import com.oracle.truffle.dsl.processor.model.*; 39 import com.oracle.truffle.dsl.processor.model.*;
39 import com.oracle.truffle.dsl.processor.parser.*; 40 import com.oracle.truffle.dsl.processor.parser.*;
40 41
41 class SpecializedNodeFactory extends NodeBaseFactory { 42 class SpecializedNodeFactory extends NodeBaseFactory {
42 43
43 protected final CodeTypeElement nodeGen; 44 protected final CodeTypeElement nodeGen;
44 45
45 public SpecializedNodeFactory(CodeTypeElement nodeGen) { 46 public SpecializedNodeFactory(ProcessorContext context, NodeData node, SpecializationData specialization, CodeTypeElement nodeGen) {
47 super(context, node, specialization);
46 this.nodeGen = nodeGen; 48 this.nodeGen = nodeGen;
47 } 49 }
48 50
49 @Override 51 @Override
50 public CodeTypeElement create(SpecializationData specialization) { 52 public CodeTypeElement create() {
51 NodeData node = specialization.getNode();
52 TypeMirror baseType = node.getNodeType(); 53 TypeMirror baseType = node.getNodeType();
53 if (nodeGen != null) { 54 if (nodeGen != null) {
54 baseType = nodeGen.asType(); 55 baseType = nodeGen.asType();
55 } 56 }
56 CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); 57 CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
57 58
58 if (specialization.isSpecialized() || specialization.isUninitialized()) { 59 if (specialization.isSpecialized() || specialization.isUninitialized()) {
59 clazz.add(createGetMetadata0(false)); 60 clazz.add(createGetMetadata0(false));
60 clazz.add(createMetadataLiteral()); 61 clazz.add(createMetadataLiteral());
61 } 62 }
70 } else if (specialization.isSpecialized()) { 71 } else if (specialization.isSpecialized()) {
71 cost = NodeCost.MONOMORPHIC; 72 cost = NodeCost.MONOMORPHIC;
72 } else { 73 } else {
73 throw new AssertionError(); 74 throw new AssertionError();
74 } 75 }
75 clazz.getAnnotationMirrors().add(createNodeInfo(node, cost)); 76 clazz.getAnnotationMirrors().add(createNodeInfo(cost));
76 77
77 if (specialization.isUninitialized() && node.getGenericSpecialization().isReachable()) { 78 if (specialization.isUninitialized() && node.getGenericSpecialization().isReachable()) {
78 clazz.add(createUninitializedGetCostOverride()); 79 clazz.add(createUninitializedGetCostOverride());
80 }
81
82 createConstructors(clazz);
83
84 createExecuteMethods(clazz);
85 createCachedExecuteMethods(clazz);
86
87 if (specialization.isUninitialized()) {
88 if (specialization.getNode().isFallbackReachable()) {
89 CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK);
90 var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal()));
91 clazz.add(var);
92 }
93 clazz.add(createExecuteUninitialized());
94 }
95
96 if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) {
97 clazz.add(createCopyConstructorFactoryMethod(clazz, nodeGen.asType()));
98 } else {
99 for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
100 if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) {
101 // skip copy constructor - not used
102 continue;
103 }
104 clazz.add(createConstructorFactoryMethod(clazz, constructor));
105 }
79 } 106 }
80 107
81 return clazz; 108 return clazz;
82 } 109 }
83 110
95 private CodeVariableElement createMetadataLiteral() { 122 private CodeVariableElement createMetadataLiteral() {
96 CodeVariableElement includes = new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), context.getTruffleTypes().getDslMetadata(), METADATA_FIELD_NAME); 123 CodeVariableElement includes = new CodeVariableElement(modifiers(PRIVATE, STATIC, FINAL), context.getTruffleTypes().getDslMetadata(), METADATA_FIELD_NAME);
97 124
98 CodeTreeBuilder builder = includes.createInitBuilder(); 125 CodeTreeBuilder builder = includes.createInitBuilder();
99 126
100 SpecializationData specialization = getModel();
101 NodeData node = specialization.getNode();
102
103 Set<SpecializationData> contains = specialization.getContains(); 127 Set<SpecializationData> contains = specialization.getContains();
104 if (specialization.isUninitialized()) { 128 if (specialization.isUninitialized()) {
105 contains = new HashSet<>(); 129 contains = new HashSet<>();
106 130
107 SpecializationData polymorphic = node.getPolymorphicSpecialization(); 131 SpecializationData polymorphic = node.getPolymorphicSpecialization();
113 contains.addAll(generic.getContains()); 137 contains.addAll(generic.getContains());
114 } 138 }
115 } 139 }
116 140
117 builder.startNew(context.getTruffleTypes().getDslMetadata()); 141 builder.startNew(context.getTruffleTypes().getDslMetadata());
118 builder.startGroup().string(nodeSpecializationClassName(getModel()), ".class").end(); 142 builder.startGroup().string(nodeSpecializationClassName(getSpecialization()), ".class").end();
119 builder.tree(createSpecializationListLiteral(builder, contains)); 143 builder.tree(createSpecializationListLiteral(builder, contains));
120 builder.tree(createSpecializationListLiteral(builder, getModel().getExcludedBy())); 144 builder.tree(createSpecializationListLiteral(builder, getSpecialization().getExcludedBy()));
121 builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getModel()))); 145 builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getSpecialization())));
122 builder.string("0").string("0"); 146 builder.string("0").string("0");
123 builder.end(); 147 builder.end();
124 return includes; 148 return includes;
125 } 149 }
126 150
147 171
148 if (list.isEmpty()) { 172 if (list.isEmpty()) {
149 builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); 173 builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY);
150 } else { 174 } else {
151 builder.startNewArray(classArray, null); 175 builder.startNewArray(classArray, null);
152 for (SpecializationData specialization : list) { 176 for (SpecializationData current : list) {
153 SpecializationData s = specialization; 177 SpecializationData s = current;
154 if (s.isGeneric() || s.isPolymorphic()) { 178 if (s.isGeneric() || s.isPolymorphic()) {
155 s = getModel().getNode().getUninitializedSpecialization(); 179 s = getSpecialization().getNode().getUninitializedSpecialization();
156 } 180 }
157 builder.startGroup().string(nodeSpecializationClassName(s)).string(".class").end(); 181 builder.startGroup().string(nodeSpecializationClassName(s)).string(".class").end();
158 } 182 }
159 builder.end(); 183 builder.end();
160 } 184 }
161 185
162 return builder.getRoot(); 186 return builder.getRoot();
163 } 187 }
164 188
165 protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) { 189 protected CodeAnnotationMirror createNodeInfo(NodeCost cost) {
166 String shortName = node.getShortName(); 190 String shortName = node.getShortName();
167 CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation()); 191 CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(context.getTruffleTypes().getNodeInfoAnnotation());
168 if (shortName != null) { 192 if (shortName != null) {
169 nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName)); 193 nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName));
170 } 194 }
171 195
172 DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost(); 196 DeclaredType nodeinfoCost = context.getTruffleTypes().getNodeCost();
173 VariableElement varKind = ElementUtils.findVariableElement(nodeinfoCost, cost.name()); 197 VariableElement varKind = ElementUtils.findVariableElement(nodeinfoCost, cost.name());
174 198
175 nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind)); 199 nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind));
176 return nodeInfoMirror; 200 return nodeInfoMirror;
177 } 201 }
178 202
179 @Override
180 protected void createChildren(SpecializationData specialization) {
181 CodeTypeElement clazz = getElement();
182 createConstructors(clazz);
183
184 createExecuteMethods(specialization);
185 createCachedExecuteMethods(specialization);
186
187 if (specialization.isUninitialized()) {
188 if (specialization.getNode().isFallbackReachable()) {
189 CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK);
190 var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal()));
191 clazz.add(var);
192 }
193 clazz.add(createExecuteUninitialized());
194 }
195
196 if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) {
197 clazz.add(createCopyConstructorFactoryMethod(nodeGen.asType(), specialization));
198 } else {
199 for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
200 if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) {
201 // skip copy constructor - not used
202 continue;
203 }
204 clazz.add(createConstructorFactoryMethod(specialization, constructor));
205 }
206 }
207 }
208
209 protected void createConstructors(CodeTypeElement clazz) { 203 protected void createConstructors(CodeTypeElement clazz) {
210 TypeElement superTypeElement = ElementUtils.fromTypeMirror(clazz.getSuperclass()); 204 TypeElement superTypeElement = ElementUtils.fromTypeMirror(clazz.getSuperclass());
211 SpecializationData specialization = getModel();
212 NodeData node = specialization.getNode();
213 for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) { 205 for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) {
214 if (specialization.isUninitialized()) { 206 if (specialization.isUninitialized()) {
215 // ignore copy constructors for uninitialized if not polymorphic 207 // ignore copy constructors for uninitialized if not polymorphic
216 if (isCopyConstructor(constructor) && !node.isPolymorphic(context)) { 208 if (isCopyConstructor(constructor) && !node.isPolymorphic(context)) {
217 continue; 209 continue;
221 if (!isCopyConstructor(constructor)) { 213 if (!isCopyConstructor(constructor)) {
222 continue; 214 continue;
223 } 215 }
224 } 216 }
225 217
226 CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor); 218 CodeExecutableElement superConstructor = GeneratorUtils.createSuperConstructor(context, clazz, constructor);
227 if (superConstructor == null) { 219 if (superConstructor == null) {
228 continue; 220 continue;
229 } 221 }
230 CodeTree body = superConstructor.getBodyTree(); 222 CodeTree body = superConstructor.getBodyTree();
231 CodeTreeBuilder builder = superConstructor.createBuilder(); 223 CodeTreeBuilder builder = superConstructor.createBuilder();
232 builder.tree(body); 224 builder.tree(body);
233 225
234 if (superConstructor != null) { 226 if (superConstructor != null) {
235 for (Parameter param : getImplicitTypeParameters(getModel())) { 227 for (Parameter param : getImplicitTypeParameters(getSpecialization())) {
236 clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param))); 228 clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), context.getType(Class.class), implicitTypeName(param)));
237 superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); 229 superConstructor.getParameters().add(new CodeVariableElement(context.getType(Class.class), implicitTypeName(param)));
238 230
239 builder.startStatement(); 231 builder.startStatement();
240 builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param)); 232 builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param));
241 builder.end(); 233 builder.end();
242 } 234 }
244 clazz.add(superConstructor); 236 clazz.add(superConstructor);
245 } 237 }
246 } 238 }
247 } 239 }
248 240
249 protected void createExecuteMethods(SpecializationData specialization) { 241 protected void createExecuteMethods(CodeTypeElement clazz) {
250 NodeData node = specialization.getNode();
251 CodeTypeElement clazz = getElement();
252 242
253 List<ExecutableTypeData> primaryExecutes = null; 243 List<ExecutableTypeData> primaryExecutes = null;
254 int lastEvaluatedCount = -1; 244 int lastEvaluatedCount = -1;
255 245
256 for (ExecutableTypeData execType : node.getExecutableTypes()) { 246 for (ExecutableTypeData execType : node.getExecutableTypes()) {
257 if (execType.isFinal()) { 247 if (execType.isFinal()) {
258 continue; 248 continue;
259 } 249 }
260 if (execType.getEvaluatedCount() != lastEvaluatedCount) { 250 if (execType.getEvaluatedCount() != lastEvaluatedCount) {
261 lastEvaluatedCount = execType.getEvaluatedCount(); 251 lastEvaluatedCount = execType.getEvaluatedCount();
262 primaryExecutes = findFunctionalExecutableType(specialization, lastEvaluatedCount); 252 primaryExecutes = findFunctionalExecutableType(lastEvaluatedCount);
263 } 253 }
264 254
265 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true); 255 CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true);
266 clazz.add(executeMethod); 256 clazz.add(executeMethod);
267 CodeTreeBuilder builder = executeMethod.getBuilder(); 257 CodeTreeBuilder builder = executeMethod.getBuilder();
268 CodeTree result = createExecuteBody(builder, specialization, execType, primaryExecutes); 258 CodeTree result = createExecuteBody(builder, execType, primaryExecutes);
269 if (result != null) { 259 if (result != null) {
270 builder.tree(result); 260 builder.tree(result);
271 } else { 261 } else {
272 clazz.remove(executeMethod); 262 clazz.remove(executeMethod);
273 } 263 }
274 } 264 }
275 } 265 }
276 266
277 protected void createCachedExecuteMethods(SpecializationData specialization) { 267 protected void createCachedExecuteMethods(CodeTypeElement clazz) {
278 NodeData node = specialization.getNode();
279 if (!node.isPolymorphic(context)) { 268 if (!node.isPolymorphic(context)) {
280 return; 269 return;
281 } 270 }
282 271
283 CodeTypeElement clazz = getElement();
284
285 final SpecializationData polymorphic = node.getPolymorphicSpecialization(); 272 final SpecializationData polymorphic = node.getPolymorphicSpecialization();
286 ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_CHAINED); 273 ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_CHAINED);
287 CodeExecutableElement executeMethod = CodeExecutableElement.clone(getContext().getEnvironment(), executeCached); 274 CodeExecutableElement executeMethod = CodeExecutableElement.clone(context.getEnvironment(), executeCached);
288 executeMethod.getModifiers().remove(Modifier.ABSTRACT); 275 executeMethod.getModifiers().remove(Modifier.ABSTRACT);
289 CodeTreeBuilder builder = executeMethod.createBuilder(); 276 CodeTreeBuilder builder = executeMethod.createBuilder();
290 277
291 if (specialization.isPolymorphic()) { 278 if (specialization.isPolymorphic()) {
292 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); 279 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED);
323 builder.tree(createDeoptimize(builder)); 310 builder.tree(createDeoptimize(builder));
324 } 311 }
325 return builder.getRoot(); 312 return builder.getRoot();
326 } 313 }
327 314
328 private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType, List<ExecutableTypeData> primaryExecutes) { 315 private CodeTree createExecuteBody(CodeTreeBuilder parent, ExecutableTypeData execType, List<ExecutableTypeData> primaryExecutes) {
329 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 316 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
330 317
331 if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) { 318 if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) {
332 builder.tree(createFunctionalExecute(builder, specialization, execType)); 319 builder.tree(createFunctionalExecute(builder, execType));
333 } else if (needsCastingExecuteMethod(execType)) { 320 } else if (needsCastingExecuteMethod(execType)) {
334 assert !primaryExecutes.isEmpty(); 321 assert !primaryExecutes.isEmpty();
335 builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0))); 322 builder.tree(createCastingExecute(builder, execType, primaryExecutes.get(0)));
336 } else { 323 } else {
337 return null; 324 return null;
338 } 325 }
339 326
340 return builder.getRoot(); 327 return builder.getRoot();
341 } 328 }
342 329
343 private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) { 330 private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) {
344 CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); 331 CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), execType.getMethod());
345 332
346 method.getAnnotationMirrors().clear(); 333 method.getAnnotationMirrors().clear();
347 for (VariableElement variable : method.getParameters()) { 334 for (VariableElement variable : method.getParameters()) {
348 variable.getAnnotationMirrors().clear(); 335 variable.getAnnotationMirrors().clear();
349 } 336 }
364 name = valueNameEvaluated(actualParameter); 351 name = valueNameEvaluated(actualParameter);
365 } else { 352 } else {
366 name = valueName(actualParameter); 353 name = valueName(actualParameter);
367 } 354 }
368 355
369 int varArgCount = getModel().getSignatureSize() - signatureIndex; 356 int varArgCount = getSpecialization().getSignatureSize() - signatureIndex;
370 if (evaluated && actualParameter.isTypeVarArgs()) { 357 if (evaluated && actualParameter.isTypeVarArgs()) {
371 Parameter baseVarArgs = actualParameter; 358 Parameter baseVarArgs = actualParameter;
372 name = valueName(baseVarArgs) + "Args"; 359 name = valueName(baseVarArgs) + "Args";
373 360
374 builder.startAssert().string(name).string(" != null").end(); 361 builder.startAssert().string(name).string(" != null").end();
409 return true; 396 return true;
410 } 397 }
411 return false; 398 return false;
412 } 399 }
413 400
414 private List<ExecutableTypeData> findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) { 401 private List<ExecutableTypeData> findFunctionalExecutableType(int evaluatedCount) {
415 TypeData primaryType = specialization.getReturnType().getTypeSystemType(); 402 TypeData primaryType = specialization.getReturnType().getTypeSystemType();
416 List<ExecutableTypeData> otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount); 403 List<ExecutableTypeData> otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount);
417 404
418 List<ExecutableTypeData> filteredTypes = new ArrayList<>(); 405 List<ExecutableTypeData> filteredTypes = new ArrayList<>();
419 for (ExecutableTypeData compareType : otherTypes) { 406 for (ExecutableTypeData compareType : otherTypes) {
423 } 410 }
424 411
425 // no direct matches found use generic where the type is Object 412 // no direct matches found use generic where the type is Object
426 if (filteredTypes.isEmpty()) { 413 if (filteredTypes.isEmpty()) {
427 for (ExecutableTypeData compareType : otherTypes) { 414 for (ExecutableTypeData compareType : otherTypes) {
428 if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) { 415 if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(context)) {
429 filteredTypes.add(compareType); 416 filteredTypes.add(compareType);
430 } 417 }
431 } 418 }
432 } 419 }
433 420
440 } 427 }
441 428
442 return filteredTypes; 429 return filteredTypes;
443 } 430 }
444 431
445 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) { 432 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final ExecutableTypeData executable) {
446 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 433 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
447 434
448 if (specialization.isUninitialized()) { 435 if (specialization.isUninitialized()) {
449 builder.tree(createDeoptimizeUninitialized(specialization.getNode(), builder)); 436 builder.tree(createDeoptimizeUninitialized(specialization.getNode(), builder));
450 } 437 }
454 CodeTree returnSpecialized = null; 441 CodeTree returnSpecialized = null;
455 442
456 if (specialization.findNextSpecialization() != null) { 443 if (specialization.findNextSpecialization() != null) {
457 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); 444 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
458 returnBuilder.tree(createDeoptimize(builder)); 445 returnBuilder.tree(createDeoptimize(builder));
459 returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "One of guards " + specialization.getGuards() + 446 returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), null, "One of guards " + specialization.getGuards() + " failed"));
460 " failed"));
461 returnSpecialized = returnBuilder.getRoot(); 447 returnSpecialized = returnBuilder.getRoot();
462 } 448 }
463 449
464 builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() { 450 builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() {
465 451
466 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 452 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
467 return createExecute(b, executable, specialization); 453 return createExecute(b, executable);
468 } 454 }
469 }, returnSpecialized, false, false, false, false)); 455 }, returnSpecialized, false, false, false, false));
470 456
471 return builder.getRoot(); 457 return builder.getRoot();
472 } 458 }
473 459
474 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { 460 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable) {
475 NodeData node = specialization.getNode();
476 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 461 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
477 if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) { 462 if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) {
478 builder.startTryBlock(); 463 builder.startTryBlock();
479 } 464 }
480 465
492 } else if (specialization.isUninitialized()) { 477 } else if (specialization.isUninitialized()) {
493 returnBuilder.startCall(EXECUTE_UNINITIALIZED); 478 returnBuilder.startCall(EXECUTE_UNINITIALIZED);
494 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); 479 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null);
495 returnBuilder.end(); 480 returnBuilder.end();
496 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { 481 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) {
497 emitEncounteredSynthetic(builder, getModel().getNode(), specialization); 482 emitEncounteredSynthetic(builder, getSpecialization().getNode(), specialization);
498 } else { 483 } else {
499 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); 484 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null));
500 } 485 }
501 486
502 if (!returnBuilder.isEmpty()) { 487 if (!returnBuilder.isEmpty()) {
520 505
521 if (!specialization.getExceptions().isEmpty()) { 506 if (!specialization.getExceptions().isEmpty()) {
522 for (SpecializationThrowsData exception : specialization.getExceptions()) { 507 for (SpecializationThrowsData exception : specialization.getExceptions()) {
523 builder.end().startCatchBlock(exception.getJavaClass(), "ex"); 508 builder.end().startCatchBlock(exception.getJavaClass(), "ex");
524 builder.tree(createDeoptimize(builder)); 509 builder.tree(createDeoptimize(builder));
525 builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, 510 builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass())));
526 "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass())));
527 } 511 }
528 builder.end(); 512 builder.end();
529 } 513 }
530 if (!specialization.getAssumptions().isEmpty()) { 514 if (!specialization.getAssumptions().isEmpty()) {
531 builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex"); 515 builder.end().startCatchBlock(context.getTruffleTypes().getInvalidAssumption(), "ex");
532 builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "Assumption failed")); 516 builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Assumption failed"));
533 builder.end(); 517 builder.end();
534 } 518 }
535 519
536 return builder.getRoot(); 520 return builder.getRoot();
537 } 521 }
538 522
539 private CodeExecutableElement createCopyConstructorFactoryMethod(TypeMirror baseType, SpecializationData specialization) { 523 private CodeExecutableElement createCopyConstructorFactoryMethod(CodeTypeElement clazz, TypeMirror baseType) {
540 List<Parameter> implicitTypeParams = getImplicitTypeParameters(specialization); 524 List<Parameter> implicitTypeParams = getImplicitTypeParameters(specialization);
541 String baseName = "current"; 525 String baseName = "current";
542 CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME); 526 CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME);
543 method.addParameter(new CodeVariableElement(specialization.getNode().getNodeType(), baseName)); 527 method.addParameter(new CodeVariableElement(specialization.getNode().getNodeType(), baseName));
544 for (Parameter implicitTypeParam : implicitTypeParams) { 528 for (Parameter implicitTypeParam : implicitTypeParams) {
545 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(implicitTypeParam))); 529 method.addParameter(new CodeVariableElement(context.getType(Class.class), implicitTypeName(implicitTypeParam)));
546 } 530 }
547 CodeTreeBuilder builder = method.createBuilder(); 531 CodeTreeBuilder builder = method.createBuilder();
548 builder.startReturn(); 532 builder.startReturn();
549 builder.startNew(getElement().asType()); 533 builder.startNew(clazz.asType());
550 builder.startGroup().cast(baseType, CodeTreeBuilder.singleString(baseName)).end(); 534 builder.startGroup().cast(baseType, CodeTreeBuilder.singleString(baseName)).end();
551 for (Parameter param : implicitTypeParams) { 535 for (Parameter param : implicitTypeParams) {
552 builder.string(implicitTypeName(param)); 536 builder.string(implicitTypeName(param));
553 } 537 }
554 builder.end().end(); 538 builder.end().end();
555 return method; 539 return method;
556 } 540 }
557 541
558 private CodeExecutableElement createConstructorFactoryMethod(SpecializationData specialization, ExecutableElement constructor) { 542 private CodeExecutableElement createConstructorFactoryMethod(CodeTypeElement clazz, ExecutableElement constructor) {
559 List<? extends VariableElement> parameters = constructor.getParameters(); 543 List<? extends VariableElement> parameters = constructor.getParameters();
560 CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME, 544 CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME,
561 parameters.toArray(new CodeVariableElement[parameters.size()])); 545 parameters.toArray(new CodeVariableElement[parameters.size()]));
562 CodeTreeBuilder builder = method.createBuilder(); 546 CodeTreeBuilder builder = method.createBuilder();
563 builder.startReturn(); 547 builder.startReturn();
564 builder.startNew(getElement().asType()); 548 builder.startNew(clazz.asType());
565 for (VariableElement param : parameters) { 549 for (VariableElement param : parameters) {
566 builder.string(((CodeVariableElement) param).getName()); 550 builder.string(((CodeVariableElement) param).getName());
567 } 551 }
568 builder.end().end(); 552 builder.end().end();
569 return method; 553 return method;