private static MethodHandle unmapJava9(MethodHandles.Lookup lookup) throws ReflectiveOperationException { Class<?> unsafeClass = Class.forName("sun.misc.Unsafe"); MethodHandle unmapper = lookup.findVirtual(unsafeClass, "invokeCleaner", methodType(void.class, ByteBuffer.class)); Field f = unsafeClass.getDeclaredField("theUnsafe"); f.setAccessible(true); Object theUnsafe = f.get(null); return unmapper.bindTo(theUnsafe); }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { return lookup.findStatic(getClass(), "eldest", methodType(Object.class, LinkedHashMap.class)); } }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { return lookup.findStatic(System.class, "arraycopy", methodType(void.class, Object.class, int.class, Object.class, int.class, int.class)); } }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { return lookup.findStatic(getClass(), "logE", methodType(void.class, Object[].class)); } }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { return lookup.findStatic(getClass(), "adjustLanguageCode", methodType(String.class, String.class)); } }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { switch (methodName) { case "nanoTime": return lookup.findStatic(ShadowSystemClock.class, "nanoTime", methodType(long.class)); case "currentTimeMillis": return lookup.findStatic(ShadowSystemClock.class, "currentTimeMillis", methodType(long.class)); } throw new UnsupportedOperationException(); } }
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { switch (methodName) { case "create": return lookup.findStatic(getClass(), "create", methodType(Object.class, Object.class, Runnable.class)); case "clean": return lookup.findStatic(getClass(), "clean", methodType(void.class, Object.class)); default: throw new IllegalStateException(); } } }
private static Object globalCleaner() { MethodHandles.Lookup lookup = MethodHandles.lookup(); try { Class<?> newCleaner = Class.forName( "java.lang.ref.Cleaner" ); MethodHandle createInstance = lookup.findStatic( newCleaner, "create", MethodType.methodType( newCleaner ) ); return createInstance.invoke(); } catch ( Throwable throwable ) { return null; } }
@Override MethodHandle lookup(Method method) throws ReflectiveOperationException { MethodType methodType = MethodType.methodType(method.getReturnType(), method.getParameterTypes()); return getLookup(method.getDeclaringClass()).findSpecial(method.getDeclaringClass(), method.getName(), methodType, method.getDeclaringClass()); }
private UnaryOperator<Key> checkForCloneMethod(final Class<?> declType, final Class<?> returnType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findVirtual(declType, "clone", MethodType.methodType(returnType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
private UnaryOperator<Key> checkForCopyCtor(final Class<?> declType, final Class<?> paramType) { final MethodHandles.Lookup lookup = MethodHandles.lookup(); final MethodHandle handle = doPrivileged((PrivilegedAction<MethodHandle>) () -> { try { return lookup.findConstructor(declType, MethodType.methodType(void.class, paramType)); } catch (NoSuchMethodException | IllegalAccessException e) { return null; } }); return handle == null ? null : produceOp(handle); }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { List<Type> types = this.typeParameters.stream().map(boundVariables::getTypeVariable).collect(toImmutableList()); List<ArgumentProperty> argumentProperties = nCopies(types.size(), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); List<Class<?>> javaArgumentTypes = nCopies(types.size(), Block.class); MethodHandle methodHandle = METHOD_HANDLE.bindTo(types).asVarargsCollector(Block[].class).asType(methodType(Block.class, javaArgumentTypes)); return new ScalarFunctionImplementation(false, argumentProperties, methodHandle, isDeterministic()); }
private static MethodHandle lookupNewJarFile() { try { return MethodHandles.lookup().findConstructor(java.util.jar.JarFile.class, MethodType.methodType(void.class, java.io.File.class, java.lang.Boolean.TYPE, Integer.TYPE, runtimeVersionClass())); } catch (Throwable t) { return null; } } private static Class<?> runtimeVersionClass() throws ClassNotFoundException {
private static MethodHandle lookupRuntimeVersion() { try { return MethodHandles.lookup().findStatic(java.lang.Runtime.class, "version", MethodType.methodType(runtimeVersionClass())); } catch (Throwable t) { return null; } } private static MethodHandle lookupRuntimeVersionMajor() {
private static MethodHandle unmapJava7Or8(MethodHandles.Lookup lookup) throws ReflectiveOperationException { /* "Compile" a MethodHandle that is roughly equivalent to the following lambda: * * (ByteBuffer buffer) -> { * sun.misc.Cleaner cleaner = ((java.nio.DirectByteBuffer) byteBuffer).cleaner(); * if (nonNull(cleaner)) * cleaner.clean(); * else * noop(cleaner); // the noop is needed because MethodHandles#guardWithTest always needs both if and else * } */ Class<?> directBufferClass = Class.forName("java.nio.DirectByteBuffer"); Method m = directBufferClass.getMethod("cleaner"); m.setAccessible(true); MethodHandle directBufferCleanerMethod = lookup.unreflect(m); Class<?> cleanerClass = directBufferCleanerMethod.type().returnType(); MethodHandle cleanMethod = lookup.findVirtual(cleanerClass, "clean", methodType(void.class)); MethodHandle nonNullTest = lookup.findStatic(MappedByteBuffers.class, "nonNull", methodType(boolean.class, Object.class)).asType(methodType(boolean.class, cleanerClass)); MethodHandle noop = dropArguments(constant(Void.class, null).asType(methodType(void.class)), 0, cleanerClass); MethodHandle unmapper = filterReturnValue(directBufferCleanerMethod, guardWithTest(nonNullTest, cleanMethod, noop)) .asType(methodType(void.class, ByteBuffer.class)); return unmapper; }
private ObjectStrategy(FunctionRegistry registry, Type type) { hashCodeHandle = registry.getScalarFunctionImplementation(registry.resolveOperator(HASH_CODE, ImmutableList.of(type))) .getMethodHandle() .asType(MethodType.methodType(long.class, Object.class)); equalsHandle = registry.getScalarFunctionImplementation(registry.resolveOperator(EQUAL, ImmutableList.of(type, type))) .getMethodHandle() .asType(MethodType.methodType(Boolean.class, Object.class, Object.class)); }
private static MethodHandle lookupRuntimeVersionParse() { try { return MethodHandles.lookup().findStatic(runtimeVersionClass(), "parse", MethodType.methodType(runtimeVersionClass(), String.class)); } catch (Throwable t) { return null; } } private static MethodHandle lookupRuntimeVersion() {
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle nothing = constant(Void.class, null).asType(methodType(void.class)); if (type.parameterCount() != 0) { return dropArguments(nothing, 0, type.parameterArray()); } else { return nothing; } } }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type fromType = boundVariables.getTypeVariable("F"); Type toType = boundVariables.getTypeVariable("T"); Class<?> returnType = Primitives.wrap(toType.getJavaType()); List<ArgumentProperty> argumentProperties; MethodHandle tryCastHandle; // the resulting method needs to return a boxed type Signature signature = functionRegistry.getCoercion(fromType, toType); ScalarFunctionImplementation implementation = functionRegistry.getScalarFunctionImplementation(signature); argumentProperties = ImmutableList.of(implementation.getArgumentProperty(0)); MethodHandle coercion = implementation.getMethodHandle(); coercion = coercion.asType(methodType(returnType, coercion.type())); MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class); tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler); return new ScalarFunctionImplementation(true, argumentProperties, tryCastHandle, isDeterministic()); } }
private static BlockBuilder createMapBuilder(int expectedEntries) { MethodHandle varcharNativeEquals = MethodHandleUtil.methodHandle(Slice.class, "equals", Object.class).asType(MethodType.methodType(boolean.class, Slice.class, Slice.class)); MethodHandle varcharBlockNativeEquals = compose(varcharNativeEquals, nativeValueGetter(VARCHAR)); MethodHandle varcharBlockEquals = compose(varcharNativeEquals, nativeValueGetter(VARCHAR), nativeValueGetter(VARCHAR)); return new MapBlockBuilder( VARCHAR, VARCHAR, varcharBlockNativeEquals, varcharBlockEquals, MethodHandleUtil.methodHandle(Slice.class, "hashCode").asType(MethodType.methodType(long.class, Slice.class)), MethodHandleUtil.methodHandle(TestColumnarMap.class, "blockVarcharHashCode", Block.class, int.class), null, expectedEntries); }