@Test
 public void testJoin7() {
   Stamp aExact = StampFactory.exact(getType(A.class));
   Stamp e = StampFactory.declared(getType(E.class));
   Stamp join = join(aExact, e);
   Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
   Assert.assertNull(StampTool.typeOrNull(join));
   Assert.assertFalse(StampTool.isExactType(join));
 }
 @Test
 public void testJoin5() {
   Stamp dExact = StampFactory.exact(getType(D.class));
   Stamp c = StampFactory.declared(getType(C.class));
   Stamp join = join(c, dExact);
   Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
   Assert.assertNull(StampTool.typeOrNull(join));
   Assert.assertFalse(StampTool.isExactType(join));
 }
 @Test
 public void testJoin6() {
   Stamp dExactNonNull = StampFactory.exactNonNull(getType(D.class));
   Stamp alwaysNull = StampFactory.alwaysNull();
   Stamp join = join(alwaysNull, dExactNonNull);
   Assert.assertFalse(join.isLegal());
   Assert.assertFalse(StampTool.isPointerNonNull(join));
   Assert.assertFalse(StampTool.isPointerAlwaysNull(join));
 }
 @Test
 public void testJoin9() {
   Stamp bExact = StampFactory.exact(getType(B.class));
   Stamp dExact = StampFactory.exact(getType(D.class));
   Stamp join = join(bExact, dExact);
   Assert.assertTrue(StampTool.isPointerAlwaysNull(join));
   Assert.assertNull(StampTool.typeOrNull(join));
   Assert.assertNull(StampTool.typeOrNull(join));
 }
    public static JavaKind selectComponentKind(BasicArrayCopyNode arraycopy, boolean exact) {
      ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
      ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());

      if (srcType == null || !srcType.isArray() || destType == null || !destType.isArray()) {
        if (!exact) {
          JavaKind component = getComponentKind(srcType);
          if (component != null) {
            return component;
          }
          return getComponentKind(destType);
        }
        return null;
      }
      if (exact) {
        if (!destType.getComponentType().isAssignableFrom(srcType.getComponentType())) {
          return null;
        }
        if (!arraycopy.isExact()) {
          return null;
        }
      }
      return srcType.getComponentType().getJavaKind();
    }
 /**
  * For one or more `invoke` arguments, flow-sensitive information may suggest their narrowing or
  * simplification. In those cases, a new {@link com.oracle.graal.nodes.java.MethodCallTargetNode
  * MethodCallTargetNode} is prepared just for this callsite, consuming reduced arguments.
  *
  * <p>Specializing the {@link com.oracle.graal.nodes.java.MethodCallTargetNode
  * MethodCallTargetNode} as described above may enable two optimizations:
  *
  * <ul>
  *   <li>devirtualization of an {@link com.oracle.graal.nodes.CallTargetNode.InvokeKind#Interface}
  *       or {@link com.oracle.graal.nodes.CallTargetNode.InvokeKind#Virtual} callsite
  *       (devirtualization made possible after narrowing the type of the receiver)
  *   <li>(future work) actual-argument-aware inlining, ie, to specialize callees on the types of
  *       arguments other than the receiver (examples: multi-methods, the inlining problem, lambdas
  *       as arguments).
  * </ul>
  *
  * <p>Precondition: inputs haven't been deverbosified yet.
  */
 private void visitInvoke(Invoke invoke) {
   if (invoke.asNode().stamp() instanceof IllegalStamp) {
     return; // just to be safe
   }
   boolean isMethodCallTarget = invoke.callTarget() instanceof MethodCallTargetNode;
   if (!isMethodCallTarget) {
     return;
   }
   FlowUtil.replaceInPlace(
       invoke.asNode(),
       invoke.callTarget(),
       deverbosifyInputsCopyOnWrite((MethodCallTargetNode) invoke.callTarget()));
   MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
   if (callTarget.invokeKind() != CallTargetNode.InvokeKind.Interface
       && callTarget.invokeKind() != CallTargetNode.InvokeKind.Virtual) {
     return;
   }
   ValueNode receiver = callTarget.receiver();
   if (receiver == null) {
     return;
   }
   if (!FlowUtil.hasLegalObjectStamp(receiver)) {
     return;
   }
   Witness w = state.typeInfo(receiver);
   ResolvedJavaType type;
   ResolvedJavaType stampType = StampTool.typeOrNull(receiver);
   if (w == null || w.cluelessAboutType()) {
     // can't improve on stamp but wil try to devirtualize anyway
     type = stampType;
   } else {
     type = FlowUtil.tighten(w.type(), stampType);
   }
   if (type == null) {
     return;
   }
   ResolvedJavaMethod method =
       type.resolveMethod(callTarget.targetMethod(), invoke.getContextType());
   if (method == null) {
     return;
   }
   if (method.canBeStaticallyBound() || Modifier.isFinal(type.getModifiers())) {
     metricMethodResolved.increment();
     callTarget.setInvokeKind(CallTargetNode.InvokeKind.Special);
     callTarget.setTargetMethod(method);
   }
 }
 @Test
 public void testJoin3() {
   Stamp d = StampFactory.declared(getType(D.class));
   Stamp c = StampFactory.declared(getType(C.class));
   Assert.assertTrue(StampTool.isPointerAlwaysNull(join(c, d)));
 }
Beispiel #8
0
 public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {
   return add(stamp1, (IntegerStamp) StampTool.negate(stamp2));
 }
    public void lower(ArrayCopyNode arraycopy, LoweringTool tool) {
      JavaKind componentKind = selectComponentKind(arraycopy);
      SnippetInfo snippetInfo = null;
      SnippetInfo slowPathSnippetInfo = null;
      Object slowPathArgument = null;

      if (arraycopy.getLength().isConstant()
          && arraycopy.getLength().asJavaConstant().asLong() == 0) {
        snippetInfo = arraycopyZeroLengthIntrinsicSnippet;
      } else if (arraycopy.isExact()) {
        snippetInfo = arraycopyExactIntrinsicSnippet;
        if (shouldUnroll(arraycopy.getLength())) {
          snippetInfo = arraycopyUnrolledIntrinsicSnippet;
        }
      } else {
        if (componentKind == JavaKind.Object) {
          ResolvedJavaType srcType = StampTool.typeOrNull(arraycopy.getSource().stamp());
          ResolvedJavaType destType = StampTool.typeOrNull(arraycopy.getDestination().stamp());
          ResolvedJavaType srcComponentType = srcType == null ? null : srcType.getComponentType();
          ResolvedJavaType destComponentType =
              destType == null ? null : destType.getComponentType();
          if (srcComponentType != null
              && destComponentType != null
              && !srcComponentType.isPrimitive()
              && !destComponentType.isPrimitive()) {
            snippetInfo = arraycopySlowPathIntrinsicSnippet;
            slowPathSnippetInfo = checkcastArraycopyWorkSnippet;
            slowPathArgument = LocationIdentity.any();
            /*
             * Because this snippet has to use Sysytem.arraycopy as a slow path, we must
             * pretend to kill any() so clear the componentKind.
             */
            componentKind = null;
          }
        }
        if (componentKind == null && snippetInfo == null) {
          JavaKind predictedKind = selectComponentKind(arraycopy, false);
          if (predictedKind != null) {
            /*
             * At least one array is of a known type requiring no store checks, so
             * assume the other is of the same type. Generally this is working around
             * deficiencies in our propagation of type information.
             */
            componentKind = predictedKind;
            if (predictedKind == JavaKind.Object) {
              snippetInfo = arraycopySlowPathIntrinsicSnippet;
              slowPathSnippetInfo = arraycopyPredictedObjectWorkSnippet;
              slowPathArgument = predictedKind;
              componentKind = null;
            } else {
              snippetInfo = arraycopyPredictedExactIntrinsicSnippet;
            }
          }
        }
        if (snippetInfo == null) {
          snippetInfo = arraycopyGenericSnippet;
        }
      }
      Arguments args =
          new Arguments(snippetInfo, arraycopy.graph().getGuardsStage(), tool.getLoweringStage());
      args.add("src", arraycopy.getSource());
      args.add("srcPos", arraycopy.getSourcePosition());
      args.add("dest", arraycopy.getDestination());
      args.add("destPos", arraycopy.getDestinationPosition());
      args.add("length", arraycopy.getLength());
      if (snippetInfo == arraycopyUnrolledIntrinsicSnippet) {
        args.addConst("unrolledLength", arraycopy.getLength().asJavaConstant().asInt());
        args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
      } else if (snippetInfo == arraycopySlowPathIntrinsicSnippet) {
        args.addConst("elementKind", componentKind != null ? componentKind : JavaKind.Illegal);
        args.addConst("slowPath", slowPathSnippetInfo);
        assert slowPathArgument != null;
        args.addConst("slowPathArgument", slowPathArgument);
      } else if (snippetInfo == arraycopyExactIntrinsicSnippet
          || snippetInfo == arraycopyPredictedExactIntrinsicSnippet) {
        assert componentKind != null;
        args.addConst("elementKind", componentKind);
        args.addConst("counter", arraycopyCallCounters.get(componentKind));
        args.addConst("copiedCounter", arraycopyCallCopiedCounters.get(componentKind));
      }
      instantiate(args, arraycopy);
    }