예제 #1
0
  @Override
  public void lower(LoweringTool tool) {
    StructuredGraph replacementGraph = getLoweredSnippetGraph(tool);

    InvokeNode invoke = replaceWithInvoke();
    assert invoke.verify();

    if (replacementGraph != null) {
      // Pull out the receiver null check so that a replaced
      // receiver can be lowered if necessary
      if (!targetMethod.isStatic()) {
        ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
        if (nonNullReceiver instanceof Lowerable) {
          ((Lowerable) nonNullReceiver).lower(tool);
        }
      }
      InliningUtil.inline(invoke, replacementGraph, false, null);
      Debug.dump(Debug.INFO_LOG_LEVEL, graph(), "After inlining replacement %s", replacementGraph);
    } else {
      if (isPlaceholderBci(invoke.bci())) {
        throw new GraalError("%s: cannot lower to invoke with placeholder BCI: %s", graph(), this);
      }

      if (invoke.stateAfter() == null) {
        ResolvedJavaMethod method = graph().method();
        if (method.getAnnotation(MethodSubstitution.class) != null
            || method.getAnnotation(Snippet.class) != null) {
          // One cause for this is that a MacroNode is created for a method that
          // no longer needs a MacroNode. For example, Class.getComponentType()
          // only needs a MacroNode prior to JDK9 as it was given a non-native
          // implementation in JDK9.
          throw new GraalError(
              "%s macro created for call to %s in %s must be lowerable to a snippet or intrinsic graph. "
                  + "Maybe a macro node is not needed for this method in the current JDK?",
              getClass().getSimpleName(), targetMethod.format("%h.%n(%p)"), graph());
        }
        throw new GraalError("%s: cannot lower to invoke without state: %s", graph(), this);
      }
      invoke.lower(tool);
    }
  }
예제 #2
0
 /**
  * Checks that lowering of a given node did not introduce any new {@link Lowerable} nodes that
  * could be lowered in the current {@link LoweringPhase}. Such nodes must be recursively lowered
  * as part of lowering {@code node}.
  *
  * @param node a node that was just lowered
  * @param preLoweringMark the graph mark before {@code node} was lowered
  * @param unscheduledUsages set of {@code node}'s usages that were unscheduled before it was
  *     lowered
  * @throws AssertionError if the check fails
  */
 private static boolean checkPostNodeLowering(
     Node node,
     LoweringToolImpl loweringTool,
     Mark preLoweringMark,
     Collection<Node> unscheduledUsages) {
   StructuredGraph graph = (StructuredGraph) node.graph();
   Mark postLoweringMark = graph.getMark();
   NodeIterable<Node> newNodesAfterLowering = graph.getNewNodes(preLoweringMark);
   if (node instanceof FloatingNode) {
     if (!unscheduledUsages.isEmpty()) {
       for (Node n : newNodesAfterLowering) {
         assert !(n instanceof FixedNode)
             : node.graph()
                 + ": cannot lower floatable node "
                 + node
                 + " as it introduces fixed node(s) but has the following unscheduled usages: "
                 + unscheduledUsages;
       }
     }
   }
   for (Node n : newNodesAfterLowering) {
     if (n instanceof Lowerable) {
       ((Lowerable) n).lower(loweringTool);
       Mark mark = graph.getMark();
       assert postLoweringMark.equals(mark)
           : graph
               + ": lowering of "
               + node
               + " produced lowerable "
               + n
               + " that should have been recursively lowered as it introduces these new nodes: "
               + graph.getNewNodes(postLoweringMark).snapshot();
     }
   }
   return true;
 }
예제 #3
0
    @SuppressWarnings("try")
    private AnchoringNode process(
        final Block b, final NodeBitMap activeGuards, final AnchoringNode startAnchor) {

      final LoweringToolImpl loweringTool =
          new LoweringToolImpl(context, startAnchor, activeGuards, b.getBeginNode());

      // Lower the instructions of this block.
      List<Node> nodes = schedule.nodesFor(b);
      for (Node node : nodes) {

        if (node.isDeleted()) {
          // This case can happen when previous lowerings deleted nodes.
          continue;
        }

        // Cache the next node to be able to reconstruct the previous of the next node
        // after lowering.
        FixedNode nextNode = null;
        if (node instanceof FixedWithNextNode) {
          nextNode = ((FixedWithNextNode) node).next();
        } else {
          nextNode = loweringTool.lastFixedNode().next();
        }

        if (node instanceof Lowerable) {
          Collection<Node> unscheduledUsages = null;
          assert (unscheduledUsages = getUnscheduledUsages(node)) != null;
          Mark preLoweringMark = node.graph().getMark();
          try (DebugCloseable s = node.graph().withNodeContext(node)) {
            ((Lowerable) node).lower(loweringTool);
          }
          if (loweringTool.guardAnchor.asNode().isDeleted()) {
            // TODO nextNode could be deleted but this is not currently supported
            assert nextNode.isAlive();
            loweringTool.guardAnchor = AbstractBeginNode.prevBegin(nextNode);
          }
          assert checkPostNodeLowering(node, loweringTool, preLoweringMark, unscheduledUsages);
        }

        if (!nextNode.isAlive()) {
          // can happen when the rest of the block is killed by lowering
          // (e.g. by an unconditional deopt)
          break;
        } else {
          Node nextLastFixed = nextNode.predecessor();
          if (!(nextLastFixed instanceof FixedWithNextNode)) {
            // insert begin node, to have a valid last fixed for next lowerable node.
            // This is about lowering a FixedWithNextNode to a control split while this
            // FixedWithNextNode is followed by some kind of BeginNode.
            // For example the when a FixedGuard followed by a loop exit is lowered to a
            // control-split + deopt.
            AbstractBeginNode begin = node.graph().add(new BeginNode());
            nextLastFixed.replaceFirstSuccessor(nextNode, begin);
            begin.setNext(nextNode);
            nextLastFixed = begin;
          }
          loweringTool.setLastFixedNode((FixedWithNextNode) nextLastFixed);
        }
      }
      return loweringTool.getCurrentGuardAnchor();
    }