Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unsigned adapter handles #173

Closed
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -261,66 +261,6 @@ endef

################################################################################

################################################################################
# Setup a rule for generating a memory access unsigned var handle adapter classes
# Param 1 - Variable declaration prefix
# Param 2 - Pair of [adapter dot carrier] types, with first letter capitalized
define GenerateVarHandleUnsignedMemoryAccessAdapter

$1_AdapterType := $(word 1,$(subst ., ,$2))
$1_CarrierType := $(word 2,$(subst ., ,$2))

$1_FILENAME := $(VARHANDLES_GENSRC_DIR)/MemoryHandle$$($1_AdapterType)ToUnsigned$$($1_CarrierType).java

ifeq ($$($1_AdapterType), Long)
$1_adapterType := long
$1_AdapterType := Long
$1_BoxAdapterType := Long
ifeq ($$($1_CarrierType), Byte)
$1_carrierType := byte
$1_CarrierType := Byte
$1_BoxCarrierType := Byte
else ifeq ($$($1_CarrierType), Short)
$1_carrierType := short
$1_CarrierType := Short
$1_BoxCarrierType := Short
else ifeq ($$($1_CarrierType), Int)
$1_carrierType := int
$1_CarrierType := Int
$1_BoxCarrierType := Integer
endif
endif

ifeq ($$($1_AdapterType), Int)
$1_adapterType := int
$1_AdapterType := Int
$1_BoxAdapterType := Integer
ifeq ($$($1_CarrierType), Byte)
$1_carrierType := byte
$1_CarrierType := Byte
$1_BoxCarrierType := Byte
else ifeq ($$($1_CarrierType), Short)
$1_carrierType := short
$1_CarrierType := Short
$1_BoxCarrierType := Short
endif
endif

$$($1_FILENAME): $(VARHANDLES_SRC_DIR)/X-VarHandleMemoryHandleUnsigned.java.template $(BUILD_TOOLS_JDK)
$$(call MakeDir, $$(@D))
$(RM) $$@
$(TOOL_SPP) -nel -K$$($1_type) \
-DadapterType=$$($1_adapterType) \
-DAdapterType=$$($1_AdapterType) \
-DBoxAdapterType=$$($1_BoxAdapterType) \
-DcarrierType=$$($1_carrierType) \
-DCarrierType=$$($1_CarrierType) \
-DBoxCarrierType=$$($1_BoxCarrierType) \
-i$$< -o$$@

GENSRC_VARHANDLES += $$($1_FILENAME)
endef

################################################################################

# List the types to generate source for, with capitalized first letter
@@ -338,9 +278,4 @@ VARHANDLES_MEMORY_ADDRESS_TYPES := Byte Short Char Int Long Float Double
$(foreach t, $(VARHANDLES_MEMORY_ADDRESS_TYPES), \
$(eval $(call GenerateVarHandleMemoryAccess,VAR_HANDLE_MEMORY_ADDRESS_$t,$t)))

# List the type combinations to generate source for, with capitalized first letter
VARHANDLES_UNSIGNED_MEMORY_HANDLE_CARRIER_COMBINATIONS := Int.Byte Int.Short Long.Byte Long.Short Long.Int
$(foreach t, $(VARHANDLES_UNSIGNED_MEMORY_HANDLE_CARRIER_COMBINATIONS), \
$(eval $(call GenerateVarHandleUnsignedMemoryAccessAdapter,VAR_HANDLE_MEMORY_ADDRESS_$t,$t)))

GENSRC_JAVA_BASE += $(GENSRC_VARHANDLES)
@@ -1838,11 +1838,6 @@ public boolean isMemoryAccessVarHandle(VarHandle handle) {
return asMemoryAccessVarHandle(handle) != null;
}

@Override
public VarHandle asUnsigned(VarHandle target, final Class<?> adaptedType) {
return VarHandles.asUnsigned(target, adaptedType);
}

@Override
public VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
@@ -337,48 +337,6 @@ static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, long alignmentMas
}
}

private static void checkWidenable(Class<?> carrier) {
if (!(carrier == byte.class || carrier == short.class || carrier == int.class)) {
throw newIllegalArgumentException("illegal carrier", carrier.getSimpleName());
}
}

private static void checkNarrowable(Class<?> type) {
if (!(type == int.class || type == long.class)) {
throw newIllegalArgumentException("illegal adapter type", type.getSimpleName());
}
}

private static void checkTargetWiderThanCarrier(Class<?> carrier, Class<?> target) {
if (Wrapper.forPrimitiveType(target).bitWidth() <= Wrapper.forPrimitiveType(carrier).bitWidth()) {
throw newIllegalArgumentException(
target.getSimpleName() + " is not wider than " + carrier.getSimpleName());
}
}

public static VarHandle asUnsigned(VarHandle target, final Class<?> adaptedType) {
Objects.requireNonNull(target);
Objects.requireNonNull(adaptedType);
final Class<?> carrier = target.varType();
checkWidenable(carrier);
checkNarrowable(adaptedType);
checkTargetWiderThanCarrier(carrier, adaptedType);

if (adaptedType == int.class && carrier == byte.class) {
return MemoryHandleIntToUnsignedByte.varHandle(target);
} else if (adaptedType == int.class && carrier == short.class) {
return MemoryHandleIntToUnsignedShort.varHandle(target);
} else if (adaptedType == long.class && carrier == byte.class) {
return MemoryHandleLongToUnsignedByte.varHandle(target);
} else if (adaptedType == long.class && carrier == short.class) {
return MemoryHandleLongToUnsignedShort.varHandle(target);
} else if (adaptedType == long.class && carrier == int.class) {
return MemoryHandleLongToUnsignedInt.varHandle(target);
} else {
throw new InternalError("should not reach here");
}
}

private static VarHandle maybeAdapt(VarHandle target) {
if (!VAR_HANDLE_IDENTITY_ADAPT) return target;
target = filterValue(target,

This file was deleted.

@@ -154,12 +154,6 @@ VarHandle memoryAccessVarHandle(Class<?> carrier, long alignmentMask,
*/
long[] memoryAddressStrides(VarHandle handle);

/**
* Var handle carrier adapter.
* Used by {@code jdk.incubator.foreign.MemoryHandles}.
*/
VarHandle asUnsigned(VarHandle target, final Class<?> adaptedType);

/**
* Var handle carrier combinator.
* Used by {@code jdk.incubator.foreign.MemoryHandles}.
@@ -28,6 +28,7 @@
import jdk.internal.access.JavaLangInvokeAccess;
import jdk.internal.access.SharedSecrets;
import jdk.internal.foreign.Utils;
import jdk.internal.foreign.UnsignedAdapters;
import sun.invoke.util.Wrapper;

import java.lang.invoke.MethodHandle;
@@ -360,7 +361,7 @@ public static VarHandle asAddressVarHandle(VarHandle target) {
* @jls 5.1.3 Narrowing Primitive Conversion
*/
public static VarHandle asUnsigned(VarHandle target, final Class<?> adaptedType) {
return JLI.asUnsigned(target, adaptedType);
return UnsignedAdapters.asUnsigned(target, adaptedType);
}

/**
@@ -0,0 +1,159 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.foreign;

import jdk.incubator.foreign.MemoryHandles;
import sun.invoke.util.Wrapper;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.VarHandle;
import java.util.Objects;

public class UnsignedAdapters {

private static final MethodHandle INT_TO_BYTE;
private static final MethodHandle BYTE_TO_UNSIGNED_INT;
private static final MethodHandle INT_TO_SHORT;
private static final MethodHandle SHORT_TO_UNSIGNED_INT;
private static final MethodHandle LONG_TO_BYTE;
private static final MethodHandle BYTE_TO_UNSIGNED_LONG;
private static final MethodHandle LONG_TO_SHORT;
private static final MethodHandle SHORT_TO_UNSIGNED_LONG;
private static final MethodHandle LONG_TO_INT;
private static final MethodHandle INT_TO_UNSIGNED_LONG;

static {
try {
INT_TO_BYTE = MethodHandles.explicitCastArguments(MethodHandles.identity(byte.class),
MethodType.methodType(byte.class, int.class));
BYTE_TO_UNSIGNED_INT = MethodHandles.lookup().findStatic(Byte.class, "toUnsignedInt",
MethodType.methodType(int.class, byte.class));
INT_TO_SHORT = MethodHandles.explicitCastArguments(MethodHandles.identity(short.class),
MethodType.methodType(short.class, int.class));
SHORT_TO_UNSIGNED_INT = MethodHandles.lookup().findStatic(Short.class, "toUnsignedInt",
MethodType.methodType(int.class, short.class));
LONG_TO_BYTE = MethodHandles.explicitCastArguments(MethodHandles.identity(byte.class),
MethodType.methodType(byte.class, long.class));
BYTE_TO_UNSIGNED_LONG = MethodHandles.lookup().findStatic(Byte.class, "toUnsignedLong",
MethodType.methodType(long.class, byte.class));
LONG_TO_SHORT = MethodHandles.explicitCastArguments(MethodHandles.identity(short.class),
MethodType.methodType(short.class, long.class));
SHORT_TO_UNSIGNED_LONG = MethodHandles.lookup().findStatic(Short.class, "toUnsignedLong",
MethodType.methodType(long.class, short.class));
LONG_TO_INT = MethodHandles.explicitCastArguments(MethodHandles.identity(int.class),
MethodType.methodType(int.class, long.class));
INT_TO_UNSIGNED_LONG = MethodHandles.lookup().findStatic(Integer.class, "toUnsignedLong",
MethodType.methodType(long.class, int.class));
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}

public static VarHandle asUnsigned(VarHandle target, final Class<?> adaptedType) {
Objects.requireNonNull(target);
Objects.requireNonNull(adaptedType);
final Class<?> carrier = target.varType();
checkWidenable(carrier);
checkNarrowable(adaptedType);
checkTargetWiderThanCarrier(carrier, adaptedType);

if (adaptedType == int.class && carrier == byte.class) {
return intToUnsignedByte(target);
} else if (adaptedType == int.class && carrier == short.class) {
return intToUnsignedShort(target);
} else if (adaptedType == long.class && carrier == byte.class) {
return longToUnsignedByte(target);
} else if (adaptedType == long.class && carrier == short.class) {
return longToUnsignedShort(target);
} else if (adaptedType == long.class && carrier == int.class) {
return longToUnsignedInt(target);
} else {
throw new InternalError("should not reach here");
}
}

// int to byte
private static VarHandle intToUnsignedByte(VarHandle target) {
if (target.varType() != byte.class)
throw new InternalError("expected byte carrier, but got: " + target.varType());
return MemoryHandles.filterValue(target, INT_TO_BYTE, BYTE_TO_UNSIGNED_INT);
}

// int to short
private static VarHandle intToUnsignedShort(VarHandle target) {
if (target.varType() != short.class)
throw new InternalError("expected byte carrier, but got: " + target.varType());
return MemoryHandles.filterValue(target, INT_TO_SHORT, SHORT_TO_UNSIGNED_INT);
}

// long to byte
private static VarHandle longToUnsignedByte(VarHandle target) {
if (target.varType() != byte.class)
throw new InternalError("expected byte carrier, but got: " + target.varType());
return MemoryHandles.filterValue(target, LONG_TO_BYTE, BYTE_TO_UNSIGNED_LONG);
}

// long to short
private static VarHandle longToUnsignedShort(VarHandle target) {
if (target.varType() != short.class)
throw new InternalError("expected byte carrier, but got: " + target.varType());
return MemoryHandles.filterValue(target, LONG_TO_SHORT, SHORT_TO_UNSIGNED_LONG);
}
Comment on lines +99 to +124

This comment has been minimized.

@mcimadamore

mcimadamore May 18, 2020
Collaborator

I'm not super sure of the added value of these - the check is essentially a no op, since you already have a switch where, based on the var handle carrier, you decide which method to call. So perhaps we can just inline the right MH filter inside the switch above?


//long to int
private static VarHandle longToUnsignedInt(VarHandle target) {
if (target.varType() != int.class)
throw new InternalError("expected byte carrier, but got: " + target.varType());
return MemoryHandles.filterValue(target, LONG_TO_INT, INT_TO_UNSIGNED_LONG);
}

private static void checkWidenable(Class<?> carrier) {
if (!(carrier == byte.class || carrier == short.class || carrier == int.class)) {
throw newIllegalArgumentException("illegal carrier", carrier.getSimpleName());
}
}

private static void checkNarrowable(Class<?> type) {
if (!(type == int.class || type == long.class)) {
throw newIllegalArgumentException("illegal adapter type", type.getSimpleName());
}
}

private static void checkTargetWiderThanCarrier(Class<?> carrier, Class<?> target) {
if (Wrapper.forPrimitiveType(target).bitWidth() <= Wrapper.forPrimitiveType(carrier).bitWidth()) {

This comment has been minimized.

@mcimadamore

mcimadamore May 18, 2020
Collaborator

Note that MemoryHandles has already a routine to retrieve carrier size - maybe there's some reuse possible there

throw newIllegalArgumentException(
target.getSimpleName() + " is not wider than: ", carrier.getSimpleName());
}
}

static RuntimeException newIllegalArgumentException(String message, Object obj) {
return new IllegalArgumentException(message(message, obj));
}
private static String message(String message, Object obj) {
if (obj != null) message = message + ": " + obj;
return message;
}
}
ProTip! Use n and p to navigate between commits in a pull request.