comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 11443:b33783cbd8ce

Truffle-DSL: refactored redundant guard generation code.
author Christian Humer <christian.humer@gmail.com>
date Wed, 28 Aug 2013 11:41:10 +0200
parents 2868b55001d4
children 5fbd1ba4a5f3
comparison
equal deleted inserted replaced
11442:2868b55001d4 11443:b33783cbd8ce
322 body.startGroup(); 322 body.startGroup();
323 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString()); 323 body.staticReference(singleton.getEnclosingElement().asType(), singleton.getSimpleName().toString());
324 body.string(".").startCall(methodName); 324 body.string(".").startCall(methodName);
325 } 325 }
326 326
327 private CodeTree createGuardAndCast(CodeTreeBuilder parent, String conditionPrefix, SpecializationData sourceSpecialization, SpecializationData targetSpecialization, boolean castValues,
328 CodeTree guardedStatements, CodeTree elseStatements, boolean emitAssumptions, boolean forceElse) {
329
330 NodeData node = targetSpecialization.getNode();
331 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
332 CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, sourceSpecialization, targetSpecialization, emitAssumptions);
333 CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, sourceSpecialization, targetSpecialization);
334
335 Set<String> valuesNeedsCast;
336 if (castValues) {
337 // cast all
338 valuesNeedsCast = null;
339 } else {
340 // find out which values needs a cast
341 valuesNeedsCast = new HashSet<>();
342 for (GuardData guard : targetSpecialization.getGuards()) {
343 for (ActualParameter targetParameter : guard.getParameters()) {
344 NodeChildData field = node.findChild(targetParameter.getSpecification().getName());
345 if (field == null) {
346 continue;
347 }
348 TypeData targetType = targetParameter.getTypeSystemType();
349 ActualParameter sourceParameter = sourceSpecialization.findParameter(targetParameter.getLocalName());
350 if (sourceParameter == null) {
351 sourceParameter = targetParameter;
352 }
353 TypeData sourceType = sourceParameter.getTypeSystemType();
354
355 if (sourceType.needsCastTo(getContext(), targetType)) {
356 valuesNeedsCast.add(targetParameter.getLocalName());
357 }
358 }
359 }
360 }
361
362 int ifCount = 0;
363
364 if (implicitGuards != null) {
365 builder.startIf();
366 builder.tree(implicitGuards);
367 builder.end();
368 builder.startBlock();
369 ifCount++;
370 }
371
372 builder.tree(createCasts(parent, valuesNeedsCast, sourceSpecialization, targetSpecialization));
373
374 if (explicitGuards != null) {
375 builder.startIf();
376 builder.tree(explicitGuards);
377 builder.end();
378 builder.startBlock();
379 ifCount++;
380 }
381
382 if (implicitGuards == null && explicitGuards == null && conditionPrefix != null && !conditionPrefix.isEmpty()) {
383 builder.startIf();
384 builder.string(conditionPrefix);
385 builder.end().startBlock();
386 ifCount++;
387 }
388
389 builder.tree(guardedStatements);
390
391 builder.end(ifCount);
392 if (elseStatements != null && (forceElse || ifCount > 0)) {
393 builder.tree(elseStatements);
394 }
395 return builder.getRoot();
396 }
397
398 private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
399 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
400 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
401 if (guardedSpecialization.getGuards().size() > 0) {
402 // Explicitly specified guards
403 for (GuardData guard : guardedSpecialization.getGuards()) {
404 builder.string(andOperator);
405 if (guard.isNegated()) {
406 builder.string("!");
407 }
408 builder.tree(createTemplateMethodCall(parent, null, valueSpecialization, guard, null));
409 andOperator = " && ";
410 }
411 }
412
413 return builder.isEmpty() ? null : builder.getRoot();
414 }
415
416 private CodeTree createCasts(CodeTreeBuilder parent, Set<String> castWhiteList, TemplateMethod valueSpecialization, SpecializationData guardedSpecialization) {
417 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
418 // Implict guards based on method signature
419 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
420 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
421 if (field == null) {
422 continue;
423 }
424 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
425
426 if (valueParam == null) {
427 /*
428 * If used inside a function execute method. The value param may not exist. In that
429 * case it assumes that the value is already converted.
430 */
431 valueParam = guardedParam;
432 }
433
434 if (castWhiteList != null && !castWhiteList.contains(guardedParam.getLocalName())) {
435 continue;
436 }
437
438 CodeTree cast = createCast(parent, field, valueParam, guardedParam.getTypeSystemType());
439 if (cast == null) {
440 continue;
441 }
442 builder.tree(cast);
443 }
444
445 return builder.getRoot();
446 }
447
448 private CodeTree createImplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean emitAssumptions) {
449 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
450 // Implict guards based on method signature
451 String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
452
453 if (emitAssumptions) {
454 for (String assumption : guardedSpecialization.getAssumptions()) {
455 builder.string(andOperator);
456 builder.string("this");
457 builder.string(".").string(assumption).string(".isValid()");
458 andOperator = " && ";
459 }
460 }
461
462 for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
463 NodeChildData field = guardedSpecialization.getNode().findChild(guardedParam.getSpecification().getName());
464 if (field == null) {
465 continue;
466 }
467 ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
468
469 if (valueParam == null) {
470 /*
471 * If used inside a function execute method. The value param may not exist. In that
472 * case it assumes that the value is already converted.
473 */
474 valueParam = guardedParam;
475 }
476
477 CodeTree implicitGuard = createTypeGuard(builder, field, valueParam, guardedParam.getTypeSystemType());
478 if (implicitGuard == null) {
479 continue;
480 }
481
482 builder.string(andOperator);
483 builder.tree(implicitGuard);
484 andOperator = " && ";
485 }
486
487 return builder.isEmpty() ? null : builder.getRoot();
488 }
489
490 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
491 NodeData node = field.getNodeData();
492
493 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
494
495 TypeData sourceType = source.getTypeSystemType();
496
497 if (!sourceType.needsCastTo(getContext(), targetType)) {
498 return null;
499 }
500
501 builder.startGroup();
502
503 if (field.isShortCircuit()) {
504 ActualParameter shortCircuit = source.getPreviousParameter();
505 assert shortCircuit != null;
506 builder.string("(");
507 builder.string("!").string(valueName(shortCircuit));
508 builder.string(" || ");
509 }
510
511 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType));
512 builder.string(valueName(source));
513 builder.end().end(); // call
514
515 if (field.isShortCircuit()) {
516 builder.string(")");
517 }
518
519 builder.end(); // group
520
521 return builder.getRoot();
522 }
523
524 private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
525 NodeData node = field.getNodeData();
526 TypeData sourceType = source.getTypeSystemType();
527
528 if (!sourceType.needsCastTo(getContext(), targetType)) {
529 return null;
530 }
531
532 CodeTree condition = null;
533 if (field.isShortCircuit()) {
534 ActualParameter shortCircuit = source.getPreviousParameter();
535 assert shortCircuit != null;
536 condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
537 }
538
539 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source)));
540
541 return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value);
542 }
543
544 /** 327 /**
545 * <pre> 328 * <pre>
546 * variant1 $condition != null 329 * variant1 $condition != null
547 * 330 *
548 * $type $name = defaultValue($type); 331 * $type $name = defaultValue($type);
1442 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), rootGroup, true, new CodeBlock<SpecializationData>() { 1225 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), rootGroup, true, new CodeBlock<SpecializationData>() {
1443 1226
1444 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 1227 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
1445 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar); 1228 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar);
1446 } 1229 }
1447 })); 1230 }, null, false, true));
1448 1231
1449 boolean firstUnreachable = true; 1232 boolean firstUnreachable = true;
1450 for (SpecializationData current : node.getSpecializations()) { 1233 for (SpecializationData current : node.getSpecializations()) {
1451 if (current.isUninitialized() || current.isReachable()) { 1234 if (current.isUninitialized() || current.isReachable()) {
1452 continue; 1235 continue;
1486 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, false, new CodeBlock<SpecializationData>() { 1269 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, false, new CodeBlock<SpecializationData>() {
1487 1270
1488 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 1271 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
1489 return createGenericInvoke(builder, current.getNode().getGenericSpecialization(), current); 1272 return createGenericInvoke(builder, current.getNode().getGenericSpecialization(), current);
1490 } 1273 }
1491 })); 1274 }, null, false, true));
1492 1275
1493 emitUnreachableSpecializations(builder, node); 1276 emitUnreachableSpecializations(builder, node);
1494 1277
1495 return method; 1278 return method;
1496 } 1279 }
1502 } 1285 }
1503 builder.string("// unreachable ").string(current.getId()).newLine(); 1286 builder.string("// unreachable ").string(current.getId()).newLine();
1504 } 1287 }
1505 } 1288 }
1506 1289
1507 private CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState, 1290 protected CodeTree createExecuteTree(CodeTreeBuilder outerParent, final SpecializationData source, final SpecializationGroup group, final boolean checkMinimumState,
1508 final CodeBlock<SpecializationData> guardedblock) { 1291 final CodeBlock<SpecializationData> guardedblock, final CodeTree elseBlock, boolean forceElse, final boolean emitAssumptions) {
1509 return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Void>() { 1292 return guard(outerParent, source, group, checkMinimumState, new CodeBlock<Integer>() {
1510 1293
1511 public CodeTree create(CodeTreeBuilder parent, Void value) { 1294 public CodeTree create(CodeTreeBuilder parent, Integer ifCount) {
1512 CodeTreeBuilder builder = parent.create(); 1295 CodeTreeBuilder builder = parent.create();
1513 1296
1514 if (group.getSpecialization() != null) { 1297 if (group.getSpecialization() != null) {
1515 builder.tree(guardedblock.create(builder, group.getSpecialization())); 1298 builder.tree(guardedblock.create(builder, group.getSpecialization()));
1516 1299
1517 assert group.getChildren().isEmpty() : "missed a specialization"; 1300 assert group.getChildren().isEmpty() : "missed a specialization";
1301
1518 } else { 1302 } else {
1519 for (SpecializationGroup childGroup : group.getChildren()) { 1303 for (SpecializationGroup childGroup : group.getChildren()) {
1520 builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock)); 1304 builder.tree(createExecuteTree(builder, source, childGroup, checkMinimumState, guardedblock, null, false, emitAssumptions));
1521 } 1305 }
1522 } 1306 }
1523 1307
1524 return builder.getRoot(); 1308 return builder.getRoot();
1525 } 1309 }
1526 }); 1310 }, elseBlock, forceElse, emitAssumptions);
1527 } 1311 }
1528 1312
1529 private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Void> bodyBlock) { 1313 private CodeTree guard(CodeTreeBuilder parent, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, CodeBlock<Integer> bodyBlock, CodeTree elseBlock,
1314 boolean forceElse, boolean emitAssumptions) {
1530 CodeTreeBuilder builder = parent.create(); 1315 CodeTreeBuilder builder = parent.create();
1531 1316
1532 int ifCount = emitGuards(builder, source, group, checkMinimumState); 1317 int ifCount = emitGuards(builder, source, group, checkMinimumState, emitAssumptions);
1533 1318
1534 if (isReachableGroup(group, ifCount, checkMinimumState)) { 1319 if (isReachableGroup(group, ifCount, checkMinimumState)) {
1535 builder.tree(bodyBlock.create(builder, null)); 1320 builder.tree(bodyBlock.create(builder, ifCount));
1536 } 1321 }
1537 1322
1538 builder.end(ifCount); 1323 builder.end(ifCount);
1324
1325 if (elseBlock != null) {
1326 if (ifCount > 0 || forceElse) {
1327 builder.tree(elseBlock);
1328 }
1329 }
1539 1330
1540 return builder.getRoot(); 1331 return builder.getRoot();
1541 } 1332 }
1542 1333
1543 private boolean isReachableGroup(SpecializationGroup group, int ifCount, boolean checkMinimumState) { 1334 private boolean isReachableGroup(SpecializationGroup group, int ifCount, boolean checkMinimumState) {
1559 } 1350 }
1560 1351
1561 return true; 1352 return true;
1562 } 1353 }
1563 1354
1564 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState) { 1355 private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean checkMinimumState, boolean emitAssumptions) {
1565 NodeData node = source.getNode(); 1356 NodeData node = source.getNode();
1566 1357
1567 CodeTreeBuilder guardsBuilder = builder.create(); 1358 CodeTreeBuilder guardsBuilder = builder.create();
1568 CodeTreeBuilder castBuilder = builder.create(); 1359 CodeTreeBuilder castBuilder = builder.create();
1569 CodeTreeBuilder guardsCastBuilder = builder.create(); 1360 CodeTreeBuilder guardsCastBuilder = builder.create();
1599 guardsBuilder.string("minimumState < " + groupMaxIndex); 1390 guardsBuilder.string("minimumState < " + groupMaxIndex);
1600 guardsAnd = " && "; 1391 guardsAnd = " && ";
1601 } 1392 }
1602 } 1393 }
1603 1394
1604 for (String assumption : group.getAssumptions()) { 1395 if (emitAssumptions) {
1605 guardsBuilder.string(guardsAnd); 1396 for (String assumption : group.getAssumptions()) {
1606 guardsBuilder.string("this"); 1397 guardsBuilder.string(guardsAnd);
1607 guardsBuilder.string(".").string(assumption).string(".isValid()"); 1398 guardsBuilder.string("this");
1608 guardsAnd = " && "; 1399 guardsBuilder.string(".").string(assumption).string(".isValid()");
1400 guardsAnd = " && ";
1401 }
1609 } 1402 }
1610 1403
1611 for (TypeGuard typeGuard : group.getTypeGuards()) { 1404 for (TypeGuard typeGuard : group.getTypeGuards()) {
1612 ActualParameter valueParam = source.getSignatureParameter(typeGuard.getSignatureIndex()); 1405 ActualParameter valueParam = source.getSignatureParameter(typeGuard.getSignatureIndex());
1613 1406
1695 ActualParameter sourceParameter = source.findParameter(parameter.getLocalName()); 1488 ActualParameter sourceParameter = source.findParameter(parameter.getLocalName());
1696 if (sourceParameter == null) { 1489 if (sourceParameter == null) {
1697 sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName()); 1490 sourceParameter = source.getNode().getGenericSpecialization().findParameter(parameter.getLocalName());
1698 } 1491 }
1699 1492
1700 if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), requiredType)) { 1493 if (Utils.needsCastTo(getContext(), sourceParameter.getType(), requiredType.getPrimitiveType())) {
1701 return true; 1494 return true;
1702 } 1495 }
1703 } 1496 }
1704 1497
1705 signatureIndex++; 1498 signatureIndex++;
1706 } 1499 }
1707 return false; 1500 return false;
1501 }
1502
1503 private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
1504 NodeData node = field.getNodeData();
1505
1506 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
1507
1508 TypeData sourceType = source.getTypeSystemType();
1509
1510 if (!sourceType.needsCastTo(getContext(), targetType)) {
1511 return null;
1512 }
1513
1514 builder.startGroup();
1515
1516 if (field.isShortCircuit()) {
1517 ActualParameter shortCircuit = source.getPreviousParameter();
1518 assert shortCircuit != null;
1519 builder.string("(");
1520 builder.string("!").string(valueName(shortCircuit));
1521 builder.string(" || ");
1522 }
1523
1524 startCallTypeSystemMethod(getContext(), builder, node, TypeSystemCodeGenerator.isTypeMethodName(targetType));
1525 builder.string(valueName(source));
1526 builder.end().end(); // call
1527
1528 if (field.isShortCircuit()) {
1529 builder.string(")");
1530 }
1531
1532 builder.end(); // group
1533
1534 return builder.getRoot();
1535 }
1536
1537 private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType) {
1538 NodeData node = field.getNodeData();
1539 TypeData sourceType = source.getTypeSystemType();
1540
1541 if (!sourceType.needsCastTo(getContext(), targetType)) {
1542 return null;
1543 }
1544
1545 CodeTree condition = null;
1546 if (field.isShortCircuit()) {
1547 ActualParameter shortCircuit = source.getPreviousParameter();
1548 assert shortCircuit != null;
1549 condition = CodeTreeBuilder.singleString(valueName(shortCircuit));
1550 }
1551
1552 CodeTree value = createCallTypeSystemMethod(context, parent, node, TypeSystemCodeGenerator.asTypeMethodName(targetType), CodeTreeBuilder.singleString(valueName(source)));
1553
1554 return createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, value);
1708 } 1555 }
1709 1556
1710 private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) { 1557 private CodeTree createMethodGuard(CodeTreeBuilder parent, String prefix, SpecializationData source, GuardData guard) {
1711 CodeTreeBuilder builder = parent.create(); 1558 CodeTreeBuilder builder = parent.create();
1712 builder.string(prefix); 1559 builder.string(prefix);
2457 } 2304 }
2458 2305
2459 protected void createCachedExecuteMethods(SpecializationData specialization) { 2306 protected void createCachedExecuteMethods(SpecializationData specialization) {
2460 NodeData node = specialization.getNode(); 2307 NodeData node = specialization.getNode();
2461 CodeTypeElement clazz = getElement(); 2308 CodeTypeElement clazz = getElement();
2462 for (SpecializationData polymorphic : node.getPolymorphicSpecializations()) { 2309 for (final SpecializationData polymorphic : node.getPolymorphicSpecializations()) {
2463 if (!specialization.getSignature().isCompatibleTo(polymorphic.getSignature())) { 2310 if (!specialization.getSignature().isCompatibleTo(polymorphic.getSignature())) {
2464 continue; 2311 continue;
2465 } 2312 }
2466 ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic)); 2313 ExecutableElement executeCached = nodeGen.getMethod(executeCachedName(polymorphic));
2467 ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType()); 2314 ExecutableTypeData execType = new ExecutableTypeData(polymorphic, executeCached, node.getTypeSystem(), polymorphic.getReturnType().getTypeSystemType());
2478 } else { 2325 } else {
2479 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); 2326 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder);
2480 elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic)); 2327 elseBuilder.startReturn().startCall("this.next0", executeCachedName(polymorphic));
2481 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true); 2328 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, true);
2482 elseBuilder.end().end(); 2329 elseBuilder.end().end();
2483 CodeTreeBuilder execute = new CodeTreeBuilder(builder); 2330
2484 execute.tree(createGenericInvoke(builder, polymorphic, specialization)); 2331 boolean forceElse = specialization.getExceptions().size() > 0;
2485 boolean forceElse = !specialization.getExceptions().isEmpty(); 2332 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() {
2486 builder.tree(createGuardAndCast(builder, null, polymorphic, specialization, true, execute.getRoot(), elseBuilder.getRoot(), true, forceElse)); 2333
2334 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
2335 return createGenericInvoke(b, polymorphic, current);
2336 }
2337 }, elseBuilder.getRoot(), forceElse, true));
2487 } 2338 }
2488 clazz.add(executeMethod); 2339 clazz.add(executeMethod);
2489 } 2340 }
2490 } 2341 }
2491 2342
2620 } 2471 }
2621 2472
2622 return filteredTypes; 2473 return filteredTypes;
2623 } 2474 }
2624 2475
2625 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable) { 2476 private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) {
2626 CodeTreeBuilder builder = new CodeTreeBuilder(parent); 2477 CodeTreeBuilder builder = new CodeTreeBuilder(parent);
2627 if (specialization.isUninitialized()) { 2478 if (specialization.isUninitialized()) {
2628 builder.tree(createDeoptimize(builder)); 2479 builder.tree(createDeoptimize(builder));
2629 } 2480 }
2630 2481
2631 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false)); 2482 builder.tree(createExecuteChildren(builder, executable, specialization, specialization.getParameters(), null, false));
2632
2633 CodeTree executeNode = createExecute(builder, executable, specialization);
2634 2483
2635 CodeTree returnSpecialized = null; 2484 CodeTree returnSpecialized = null;
2636 2485
2637 if (specialization.findNextSpecialization() != null) { 2486 if (specialization.findNextSpecialization() != null) {
2638 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); 2487 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder);
2639 returnBuilder.tree(createDeoptimize(builder)); 2488 returnBuilder.tree(createDeoptimize(builder));
2640 returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuardDefinitions() + " failed")); 2489 returnBuilder.tree(createReturnExecuteAndSpecialize(builder, executable, specialization, null, "One of guards " + specialization.getGuardDefinitions() + " failed"));
2641 returnSpecialized = returnBuilder.getRoot(); 2490 returnSpecialized = returnBuilder.getRoot();
2642 } 2491 }
2643 2492
2644 builder.tree(createGuardAndCast(builder, null, specialization, specialization, true, executeNode, returnSpecialized, false, false)); 2493 builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), false, new CodeBlock<SpecializationData>() {
2494
2495 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
2496 return createExecute(b, executable, specialization);
2497 }
2498 }, returnSpecialized, false, false));
2645 2499
2646 return builder.getRoot(); 2500 return builder.getRoot();
2647 } 2501 }
2648 2502
2649 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { 2503 private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) {