static {
    try {
      MethodHandles.Lookup lookup = MethodHandles.lookup();

      BIND_CALL_SITE =
          lookup.findStatic(
              InvokeDynamicSupport.class,
              "bindCallSite",
              methodType(MethodHandle.class, MethodCallSite.class));
      BIND_INIT_CALL_SITE =
          lookup.findStatic(
              InvokeDynamicSupport.class,
              "bindInitCallSite",
              methodType(MethodHandle.class, RoboCallSite.class));
      MethodHandle cleanStackTrace =
          lookup.findStatic(
              RobolectricInternals.class,
              "cleanStackTrace",
              methodType(Throwable.class, Throwable.class));
      EXCEPTION_HANDLER =
          filterArguments(throwException(void.class, Throwable.class), 0, cleanStackTrace);
      GET_SHADOW =
          lookup.findVirtual(ShadowedObject.class, "$$robo$getData", methodType(Object.class));
    } catch (NoSuchMethodException | IllegalAccessException e) {
      throw new AssertionError(e);
    }
  }
 public static int add5(int a) throws Throwable {
   MethodHandles.Lookup lookup = MethodHandles.lookup();
   MethodType type = MethodType.methodType(int.class, int.class, int.class);
   MethodHandle mhAdd = lookup.findStatic(FunctionProgramming.class, "add", type);
   MethodHandle mh = curry(mhAdd, 5);
   return (int) mh.invoke(a);
 }
Exemple #3
0
    public static Object call(InterfaceCallSite ics, Object o, Object[] args) throws Throwable {
      final Class<?> receiverClass = o.getClass();

      // drop the 'this' (locals[0]) parameter from the signature
      // since that is implicit in a virtual method
      MethodHandle handle =
          lookup.findVirtual(
              receiverClass, ics.methodName, ics.methodType.dropParameterTypes(0, 1));

      // cache receiver type as long as the CallSite
      // is not megamorphic
      if (ics.cacheDepth != -1) {
        // figure out what kind of an upgrade we're doing

        if (ics.cacheDepth < MAX_CACHE_DEPTH) {
          // upgrade, from either uninitialized or mono/polymorphic,
          // add class to polymorphic tree
          MethodHandle test =
              lookup
                  .findVirtual(
                      Class.class, "isInstance", MethodType.methodType(boolean.class, Object.class))
                  .bindTo(receiverClass);

          ics.cacheDepth++;

          // the new receiver type becomes the root
          // of the cache tree
          ics.setTarget(
              MethodHandles.guardWithTest(
                  test, handle.asType(ics.getTarget().type()), ics.getTarget()));
        } else {
          // call site has become megamorphic.
          // don't use a cache tree anymore, set cacheDepth
          // to indicate megamorphic call site
          ics.setTarget(ics.rootHandle);
          ics.cacheDepth = -1;

          // TODO: since rootHandle points to this method,
          //       every megmorphic invocation pays for
          //       the branch above with ics.cacheDepth != -1
          //       really another static method needs to be
          //       created that just does the invocation
          //       without the upgrade logic
        }
      }

      // cache is now setup for next invocation, but we still need
      // to handle this invocation, so spread arguments array
      // over resolved receiver method and invoke

      handle =
          MethodHandles.insertArguments(handle, 0, o)
              .asSpreader(Object[].class, ics.methodType.parameterCount() - 1);

      return handle.invoke(args);
    }
Exemple #4
0
  static {
    final MethodHandles.Lookup lookup = MethodHandles.lookup();

    MethodHandle methodHandle = null;
    try {
      methodHandle = lookup.findStatic(Thread.class, "onSpinWait", methodType(void.class));
    } catch (final Exception ignore) {
    }

    ON_SPIN_WAIT_METHOD_HANDLE = methodHandle;
  }
  public static void main(String[] args) throws Throwable {
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodHandle handle = lookup.findStatic(FunctionProgramming.class, "print", typeCallback);
    forEach(new Object[] {1, 2, 4}, handle);

    MethodHandle handle2 = lookup.findStatic(FunctionProgramming.class, "add", typeCallback2);
    Object[] result = map(new Object[] {1, 2, 4}, handle2);
    forEach(result, handle);

    MethodHandle handle3 = lookup.findStatic(FunctionProgramming.class, "reduce", typeCallback3);
    System.out.println(reduce(new Object[] {1, 2, 4}, 0, handle3));

    System.out.println(FunctionProgramming.add5(8));
  }
  public static void main(String[] args) throws Throwable {
    Object x, y;
    String s;
    int i;
    MethodType mt;
    MethodHandle mh;
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    // mt is (char,char)String
    mt = MethodType.methodType(String.class, char.class, char.class);
    mh = lookup.findVirtual(String.class, "replace", mt);
    s = (String) mh.invokeExact("daddy", 'd', 'n');
    System.out.println("Result: " + s);
    // invokeExact(Ljava/lang/String;CC)Ljava/lang/String;

    // weakly typed invocation (using MHs.invoke)
    s = (String) mh.invokeWithArguments("sappy", 'p', 'v');
    System.out.println("Result: " + s);
    // mt is (Object[])List

    mt = MethodType.methodType(java.util.List.class, Object[].class);
    mh = lookup.findStatic(java.util.Arrays.class, "asList", mt);
    assert (mh.isVarargsCollector());
    x = mh.invoke("one", "two");
    // ArrayList
    System.out.println("x: " + x + " type: " + x.getClass().getCanonicalName());

    // invoke(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
    // assertEquals(x, java.util.Arrays.asList("one","two"));

    // mt is (Object,Object,Object)Object
    mt = MethodType.genericMethodType(3);
    mh = mh.asType(mt);
    x = mh.invokeExact((Object) 1, (Object) 2, (Object) 3);
    // invokeExact(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
    // 1,2,3
    System.out.println("x: " + x + " type: " + x.getClass().getCanonicalName());

    // assertEquals(x, java.util.Arrays.asList(1,2,3));
    // mt is ()int
    mt = MethodType.methodType(int.class);
    mh = lookup.findVirtual(java.util.List.class, "size", mt);
    i = (int) mh.invokeExact(java.util.Arrays.asList(1, 2, 3));
    // invokeExact(Ljava/util/List;)I
    assert (i == 3);

    mt = MethodType.methodType(void.class, String.class);
    mh = lookup.findVirtual(java.io.PrintStream.class, "println", mt);
    mh.invokeExact(System.out, "Hello, world.");
    // invokeExact(Ljava/io/PrintStream;Ljava/lang/String;)V
  }
 public static MethodHandle getMH(Class<?> c) {
   try {
     return lookup.findStatic(C.class, "m_" + c.getSimpleName(), methodType(c, String.class));
   } catch (NoSuchMethodException | IllegalAccessException e) {
     throw new RuntimeException(e);
   }
 }
Exemple #8
0
 private static MethodHandle lookupSpecial(Method method) {
   final Class<?> declaringClass = method.getDeclaringClass();
   MethodHandles.Lookup lookup = MethodHandles.publicLookup().in(declaringClass);
   return tryReflection(
       () -> {
         final Field f = MethodHandles.Lookup.class.getDeclaredField("allowedModes");
         final int modifiers = f.getModifiers();
         if (Modifier.isFinal(modifiers)) {
           final Field modifiersField = Field.class.getDeclaredField("modifiers");
           modifiersField.setAccessible(true);
           modifiersField.setInt(f, modifiers & ~Modifier.FINAL);
           f.setAccessible(true);
           f.set(lookup, MethodHandles.Lookup.PRIVATE);
         }
         return lookup.unreflectSpecial(method, declaringClass);
       });
 }
  @SuppressWarnings("UnusedDeclaration")
  public static CallSite bootstrapInit(MethodHandles.Lookup caller, String name, MethodType type) {
    RoboCallSite site = new RoboCallSite(type, caller.lookupClass());

    bindInitCallSite(site);

    return site;
  }
  @SuppressWarnings("UnusedDeclaration")
  public static CallSite bootstrapStatic(
      MethodHandles.Lookup caller, String name, MethodType type, MethodHandle original)
      throws IllegalAccessException {
    MethodCallSite site = new MethodCallSite(type, caller.lookupClass(), name, original, STATIC);

    bindCallSite(site);

    return site;
  }
  static {
    try {
      MethodHandles.Lookup lookup = MethodHandles.lookup();
      THROW_OR_RETURN =
          lookup.findStatic(
              TestCase.class,
              "throwOrReturn",
              MethodType.methodType(Object.class, Object.class, Throwable.class));
      CATCHER =
          lookup.findStatic(
              TestCase.class, "catcher", MethodType.methodType(Object.class, Object.class));
      FAKE_IDENTITY =
          lookup.findVirtual(
              TestCase.class, "fakeIdentity", MethodType.methodType(Object.class, Object.class));

    } catch (NoSuchMethodException | IllegalAccessException e) {
      throw new Error(e);
    }
    PartialConstructor[] constructors = {
      create(Object.class, Object.class::cast),
      create(String.class, Objects::toString),
      create(int[].class, x -> new int[] {Objects.hashCode(x)}),
      create(long.class, x -> Objects.hashCode(x) & (-1L >>> 32)),
      create(void.class, TestCase::noop)
    };
    Throwable[] throwables = {
      new ClassCastException("testing"),
      new java.io.IOException("testing"),
      new LinkageError("testing")
    };
    List<Supplier<TestCase>> list =
        new ArrayList<>(constructors.length * throwables.length * ThrowMode.values().length);
    //noinspection unchecked
    for (PartialConstructor f : constructors) {
      for (ThrowMode mode : ThrowMode.values()) {
        for (Throwable t : throwables) {
          list.add(f.apply(mode, t));
        }
      }
    }
    CONSTRUCTORS = Collections.unmodifiableList(list);
  }
Exemple #12
0
 public static MethodHandle resolveCallHandle() {
   try {
     return lookup.findStatic(
         InterfaceCallSite.class,
         "call",
         MethodType.methodType(
             Object.class, // return type
             InterfaceCallSite.class, // interface method being invoked
             Object.class, // receiver
             Object[].class) // args
         );
   } catch (Throwable e) {
     throw new IllegalStateException(e);
   }
 }
Exemple #13
0
  public static CallSite bootstrap(
      MethodHandles.Lookup caller, String name, MethodType type, String targetType)
      throws NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
    // lookup the target type within the ClassLoader of the
    // calling class, otherwise this bootstrap class may not
    // have visibility (if loaded through AnonymousClassLoader, etc)
    Class<?> targetClass = Class.forName(targetType, true, caller.lookupClass().getClassLoader());

    InterfaceCallSite ics = new InterfaceCallSite(targetClass, name, type);

    // set the interface class, method name, and method type
    // as the first arguments of the handle, then have
    // it collect whatever arguments are sent at runtime
    // into a trailing Object[]

    ics.rootHandle =
        MethodHandles.insertArguments(callHandle, 0, ics)
            .asVarargsCollector(Object[].class)
            .asType(type);

    ics.setTarget(ics.rootHandle);

    return ics;
  }
Exemple #14
0
  public static void main(String[] arg) throws Throwable {

    MethodHandles.Lookup lookup = MethodHandles.lookup();
    Class thisClass = lookup.lookupClass(); // (who am I?)

    MethodType methodType;
    MethodHandle methodHandle;

    Employee employee = new Employee();
    String name;

    Field fieldName = null;
    for (Field field : Employee.class.getDeclaredFields()) {
      if (field.getName().equals("name")) {
        fieldName = field;
        fieldName.setAccessible(true);
        break;
      }
    }

    // Lookup invoke dynamic
    methodType = MethodType.methodType(String.class);
    methodHandle = lookup.findVirtual(Employee.class, "getName", methodType);
    name = (String) methodHandle.invokeExact(new Employee());
    System.out.println("invoke dynamic " + name);

    // Lookup reflection
    Method method = Employee.class.getMethod("getName", new Class<?>[] {});
    name = (String) method.invoke(new Employee());
    System.out.println("reflection " + name);

    // Lookup Handle Field Direct
    MethodHandle methodHandleFieldDirect = lookup.unreflectGetter(fieldName);
    name = (String) methodHandleFieldDirect.invokeExact(new Employee());
    System.out.println("method handle for field direct " + name);

    long start = 0;
    long end = 0;
    long times = 10_000;
    long regularTime;
    long invokeDynamicTime;
    long reflectionTime;
    long count = 0;
    long invokeDynamicTimeUsingField;
    long fieldDirect;

    // warm up
    for (int index = 0; index < times; index++) {
      employee.getName();
      name = (String) methodHandle.invokeExact(employee);
      name = (String) method.invoke(employee);
      name = (String) methodHandleFieldDirect.invokeExact(employee);
    }

    // regular method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = employee.getName();
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    regularTime = end - start;
    System.out.printf("regular method call time        			= %d\n", regularTime / times);

    // invoke dynamic method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) methodHandle.invokeExact(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    invokeDynamicTime = end - start;

    System.out.printf("invoke dynamic method call time 			= %d\n", invokeDynamicTime / times);

    // reflection method call time
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) method.invoke(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    reflectionTime = end - start;
    System.out.printf("reflection method call time     			= %d\n", reflectionTime / times);

    //
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) methodHandleFieldDirect.invokeExact(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    invokeDynamicTimeUsingField = end - start;
    System.out.printf(
        "field method invoke dynamic call time     		= %d\n", invokeDynamicTimeUsingField / times);

    //
    start = System.nanoTime();
    for (int index = 0; index < times; index++) {
      name = (String) fieldName.get(employee);
      count += name.hashCode();
    }
    count = 0;
    end = System.nanoTime();
    fieldDirect = end - start;
    System.out.printf("field method reflection call time     			= %d\n", fieldDirect / times);
  }
Exemple #15
0
  static {
    Field charsField =
        AccessController.doPrivileged(
            new PrivilegedAction<Field>() {
              @Override
              public Field run() {
                Field charsField;
                try {
                  charsField = String.class.getDeclaredField("value");
                  charsField.setAccessible(true);
                } catch (NoSuchFieldException ex) {
                  LOG.info("char array stealing from String not supported", ex);
                  charsField = null;
                } catch (SecurityException ex) {
                  throw new RuntimeException(ex);
                }
                return charsField;
              }
            });
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    if (charsField != null) {
      try {
        CHARS_FIELD_GET = lookup.unreflectGetter(charsField);
      } catch (IllegalAccessException ex) {
        throw new ExceptionInInitializerError(ex);
      }
    } else {
      CHARS_FIELD_GET = null;
    }

    // up until u45 String(int offset, int count, char value[]) {
    // u45 reverted to: String(char[] value, boolean share) {
    Constructor<String> prConstr =
        AccessController.doPrivileged(
            new PrivilegedAction<Constructor<String>>() {
              @Override
              public Constructor<String> run() {
                Constructor<String> constr;
                try {
                  constr = String.class.getDeclaredConstructor(char[].class, boolean.class);
                  constr.setAccessible(true);
                } catch (NoSuchMethodException ex) {
                  try {
                    constr =
                        String.class.getDeclaredConstructor(int.class, int.class, char[].class);
                    constr.setAccessible(true);
                  } catch (NoSuchMethodException ex2) {
                    ex2.addSuppressed(ex);
                    LOG.info("building String from char[] fast not supported", ex2);
                    constr = null;
                  } catch (SecurityException ex2) {
                    ex2.addSuppressed(ex);
                    throw new RuntimeException(ex2);
                  }
                } catch (SecurityException ex) {
                  throw new RuntimeException(ex);
                }
                return constr;
              }
            });

    if (prConstr == null) {
      PROTECTED_STR_CONSTR_PARAM_TYPES = null;
      PROTECTED_STR_CONSTR_HANDLE = null;
    } else {
      PROTECTED_STR_CONSTR_PARAM_TYPES = prConstr.getParameterTypes();
      try {
        PROTECTED_STR_CONSTR_HANDLE = lookup.unreflectConstructor(prConstr);
      } catch (IllegalAccessException ex) {
        throw new ExceptionInInitializerError(ex);
      }
    }
  }