@Override
  public long getMemorySize(JavaConstant constant) {
    if (constant.getJavaKind() == JavaKind.Object) {
      HotSpotResolvedObjectType lookupJavaType = lookupJavaType(constant);

      if (lookupJavaType == null) {
        return 0;
      } else {
        if (lookupJavaType.isArray()) {
          // TODO(tw): Add compressed pointer support.
          int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
          ResolvedJavaType elementType = lookupJavaType.getComponentType();
          JavaKind elementKind = elementType.getJavaKind();
          final int headerSize = getArrayBaseOffset(elementKind);
          TargetDescription target = runtime.getHostJVMCIBackend().getTarget();
          int sizeOfElement = getArrayIndexScale(elementKind);
          int alignment = target.wordSize;
          int log2ElementSize = CodeUtil.log2(sizeOfElement);
          return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
        }
        return lookupJavaType.instanceSize();
      }
    } else {
      return constant.getJavaKind().getByteCount();
    }
  }
 static ResolvedJavaField findField(
     ResolvedJavaType type, String name, String fieldType, boolean isStatic) {
   ResolvedJavaField[] fields = isStatic ? type.getStaticFields() : type.getInstanceFields(false);
   for (ResolvedJavaField field : fields) {
     if (field.getName().equals(name) && field.getType().getName().equals(fieldType)) {
       return field;
     }
   }
   return null;
 }
 private ParameterNode[] createParameters(GraphKit kit, Class<?>[] args) {
   ParameterNode[] params = new ParameterNode[args.length];
   ResolvedJavaType accessingClass = providers.getMetaAccess().lookupJavaType(getClass());
   for (int i = 0; i < args.length; i++) {
     ResolvedJavaType type =
         providers.getMetaAccess().lookupJavaType(args[i]).resolve(accessingClass);
     Stamp stamp;
     if (type.getJavaKind().getStackKind() == JavaKind.Object) {
       stamp = StampFactory.declared(type);
     } else {
       stamp = StampFactory.forKind(type.getJavaKind());
     }
     ParameterNode param = kit.unique(new ParameterNode(i, stamp));
     params[i] = param;
   }
   return params;
 }
 static ResolvedJavaMethod findMethod(
     ResolvedJavaType type, String name, String descriptor, boolean isStatic) {
   if (isStatic && name.equals("<clinit>")) {
     ResolvedJavaMethod method = type.getClassInitializer();
     if (method != null) {
       return method;
     }
   }
   ResolvedJavaMethod[] methodsToSearch =
       name.equals("<init>") ? type.getDeclaredConstructors() : type.getDeclaredMethods();
   for (ResolvedJavaMethod method : methodsToSearch) {
     if (method.isStatic() == isStatic
         && method.getName().equals(name)
         && method.getSignature().toMethodDescriptor().equals(descriptor)) {
       return method;
     }
   }
   return null;
 }
    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();
    }
    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);
    }
 private static JavaKind getComponentKind(ResolvedJavaType type) {
   if (type != null && type.isArray()) {
     return type.getComponentType().getJavaKind();
   }
   return null;
 }