Spec-Zone.ru › OpenJDK 17

Класс MemoryHandles

java.lang.Object
jdk.incubator.foreign.MemoryHandles
public final class MemoryHandles extends Object
В этом классе определены несколько методов-фабрик для построения и комбинирования переменных-обработчиков доступа к памяти. Для получения переменной-обработчика доступа к памяти клиенты должны начать с одного из методов листьев (см. varHandle(Class, ByteOrder), varHandle(Class, long, ByteOrder)). Это определяет тип переменной (поддерживаются все примитивные типы, кроме void и boolean), а также ограничения выравнивания и порядок байтов, связанные с переменной-обработчиком доступа к памяти. Полученную переменную-обработчик доступа к памяти можно затем комбинировать различными способами для эмуляции различных режимов адресации. Переменные-обработчики, созданные этим классом, имеют обязательный тип координат (типа MemorySegment), и один тип координат, представляющий смещение в байтах относительно сегмента, в котором должен произойти обращение.

В качестве примера рассмотрим расположение памяти, выраженное экземпляром GroupLayout, построенным следующим образом:


GroupLayout seq = MemoryLayout.structLayout(
        MemoryLayout.paddingLayout(32),
        MemoryLayout.valueLayout(32, ByteOrder.BIG_ENDIAN).withName("value")
);
 
Для доступа к элементу макета с именем value, мы можем создать переменную-обработчик доступа к памяти следующим образом:

VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN); //(MemorySegment, long) -> int
handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
 

Если не указано иное, передача null аргумента или массива аргументов, содержащего один или несколько null элементов, в метод этого класса приводит к тому, что выбрасывается исключение NullPointerException.

Выравнивание и режимы доступа

Переменная-обработчик доступа к памяти связана с размером доступа S и ограничением выравнивания B (оба выражены в байтах). Мы говорим, что операция доступа к памяти полностью выровнена, если она происходит по адресу памяти A, совместимому с ограничениями выравнивания S и B. Если доступ полностью выровнен, поддерживаются следующие режимы доступа, которые гарантированно поддерживают атомарный доступ:
  • режимы чтения и записи для всех T, за исключением режимов доступа get и set для long и double на 32-битных платформах.
  • атомарные режимы обновления для int, long, float или double. (В будущих основных версиях платформы JDK могут быть добавлены дополнительные типы для некоторых в настоящее время неподдерживаемых режимов доступа.)
  • числовые атомарные режимы обновления для int и long. (В будущих основных версиях платформы JDK могут быть добавлены дополнительные числовые типы для некоторых в настоящее время неподдерживаемых режимов доступа.)
  • битовые атомарные режимы обновления для int и long. (В будущих основных версиях платформы JDK могут быть добавлены дополнительные числовые типы для некоторых в настоящее время неподдерживаемых режимов доступа.)
Если T равно float или double, то атомарные режимы обновления сравнивают значения, используя их битовое представление (см. Float.floatToRawIntBits(float) и Double.doubleToRawLongBits(double) соответственно).

В качестве альтернативы, операция доступа к памяти частично выровнена, если она происходит по адресу памяти A, совместимому только с ограничением выравнивания B; в таких случаях доступ для чего-либо, кроме режимов доступа get и set, приведет к исключению IllegalStateException. Если доступ частично выровнен, атомарный доступ гарантируется только для наибольшей степени двойки, делящей НОД A и S.

Наконец, во всех остальных случаях мы говорим, что операция доступа к памяти не выровнена; в таких случаях выбрасывается исключение IllegalStateException, независимо от используемого режима доступа.

Краткое описание методов

Модификатор и тип Метод Описание
static VarHandle asAddressVarHandle(VarHandle target)
Преобразовать существующую переменную-обработчик в новую переменную-обработчик, тип носителя которой - MemorySegment.
static VarHandle asUnsigned(VarHandle target, Class<?> adaptedType)
Преобразует целевую переменную-обработчик, сужая входные значения и расширяя выходные значения до и от указанного типа соответственно.
static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter)
Преобразует целевую переменную-обработчик, предварительно обрабатывая подпоследовательность её координат фильтром (методом-обработчиком).
static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes)
Возвращает переменную-обработчик, которая отбросит некоторые фиктивные координаты перед делегированием целевой переменной-обработчику.
static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters)
Преобразует целевую переменную-обработчик, предварительно обрабатывая входные координаты с использованием функций одноместного фильтра.
static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)
Преобразует целевую переменную-обработчик, предварительно обрабатывая входные и выходные значения с помощью пары функций фильтра.
static VarHandle insertCoordinates(VarHandle target, int pos, Object... values)
Предоставляет целевой переменной-обработчик одну или несколько связанных координат заранее перед вызовом переменной-обработчика.
static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)
Предоставляет переменную-обработчик, которая адаптирует значения координат целевой переменной-обработчика, переупорядочив их так, чтобы новые координаты соответствовали предоставленным.
static VarHandle varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
Создаёт переменную-обработчик доступа к памяти с указанным типом носителя, ограничением выравнивания и порядком байтов.
static VarHandle varHandle(Class<?> carrier, ByteOrder byteOrder)
Создаёт переменную-обработчик доступа к памяти с указанным типом носителя и порядком байтов.

Методы, объявленные в классе java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Подробности методов

varHandle

public static VarHandle varHandle(Class<?> carrier, ByteOrder byteOrder)
Создаёт обработчик доступа к памяти varHandle с заданным типом носителя и порядком байтов. Тип возвращаемого обработчика varHandle — carrier, а список типов координат — (MemorySegment, long), где тип координаты long соответствует смещению в байтах в заданном сегменте памяти. Возвращаемый обработчик varHandle обращается к байтам по смещению в заданном сегменте памяти, собирая байты для или из значения типа carrier в соответствии с заданным порядком байтов; ограничение выравнивания (в байтах) для результирующего обработчика доступа к памяти varHandle такое же, как размер (в байтах) типа носителя carrier.
Примечание API:
результирующий обработчик varHandle имеет определённые ограничения режима доступа, общие для всех обработчиков доступа к памяти varHandle.
Параметры:
carrier - тип носителя. Допустимые носители — byte, short, char, int, float, long, и double.
byteOrder - требуемый порядок байтов.
Возвращаемое значение:
новый обработчик доступа к памяти.
Исключения:
IllegalArgumentException - при использовании недопустимого типа носителя

varHandle

public static VarHandle varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
Создаёт обработчик доступа к памяти varHandle с заданным типом носителя, ограничением выравнивания и порядком байтов. Тип возвращаемого обработчика varHandle — carrier, а список типов координат — (MemorySegment, long), где тип координаты long соответствует смещению в байтах в заданном сегменте памяти. Возвращаемый обработчик varHandle обращается к байтам по смещению в заданном сегменте памяти, собирая байты для или из значения типа carrier в соответствии с заданным порядком байтов; ограничение выравнивания (в байтах) для результирующего обработчика доступа к памяти varHandle задаётся alignmentBytes.
Примечание API:
результирующий обработчик varHandle имеет определённые ограничения режима доступа, общие для всех обработчиков доступа к памяти varHandle.
Параметры:
carrier - тип носителя. Допустимые носители — byte, short, char, int, float, long, и double.
alignmentBytes - ограничение выравнивания (в байтах). Должно быть степенью двойки.
byteOrder - требуемый порядок байтов.
Возвращаемое значение:
новый обработчик доступа к памяти.
Исключения:
IllegalArgumentException - если используется недопустимый тип носителя или если alignmentBytes не является степенью двойки.

asAddressVarHandle

public static VarHandle asAddressVarHandle(VarHandle target)
Адаптирует существующий обработчик varHandle в новый обработчик varHandle, тип носителя которого — MemorySegment. То есть, при вызове VarHandle.get(Object...) на возвращаемом обработчике varHandle, считанное числовое значение будет преобразовано в адрес памяти (как если бы был вызван MemoryAddress.ofLong(long)); аналогично, при вызове VarHandle.set(Object...) адрес памяти, который должен быть установлен, будет преобразован в числовое значение и затем записан в память. Объём байтов, считанных (соответственно, записанных) из (соответственно, в) памяти, зависит от носителя исходного обработчика varHandle доступа к памяти.
Параметры:
target - адаптируемый обработчик varHandle доступа к памяти
Возвращаемое значение:
адаптированный обработчик varHandle.
Исключения:
IllegalArgumentException - если тип носителя varHandle является boolean, float, или double, или не является примитивным типом.

asUnsigned

public static VarHandle asUnsigned(VarHandle target, Class<?> adaptedType)
Адаптирует обработчик varHandle, сужая входящие значения и расширяя исходящие значения для и от заданного типа, соответственно.

Возвращаемый обработчик varHandle может удобно использоваться для представления беззнаковых примитивных типов данных как более широких знаковых примитивных типов. Например, часто удобно моделировать беззнаковый short как Java int, чтобы избежать работы с отрицательными значениями, которые были бы в случае моделирования как Java short. Это иллюстрируется в следующем примере:


    MemorySegment segment = MemorySegment.allocateNative(2, ResourceScope.newImplicitScope());
    VarHandle SHORT_VH = MemoryLayouts.JAVA_SHORT.varHandle(short.class);
    VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class);
    SHORT_VH.set(segment, (short)-1);
    INT_VH.get(segment); // returns 65535
 

При вызове, например, VarHandle.set(Object...) на результирующем обработчике varHandle, входящее значение (типа adaptedType) преобразуется с помощью сужающего примитивного преобразования и затем передаётся в обработчик varHandle target. Сужающее примитивное преобразование может потерять информацию о полном значении числовой величины. И наоборот, при вызове, например, VarHandle.get(Object...) на результирующем обработчике varHandle, возвращённое значение, полученное от обработчика varHandle target, преобразуется с помощью расширяющего беззнакового преобразования перед возвращением вызывающей стороне. При расширяющем беззнаковом преобразовании старшие биты, большие, чем у типа носителя target, обнуляются, и младшие биты (равные ширине типа носителя target) равны битам значения, полученного от обработчика varHandle target.

Возвращаемый обработчик varHandle будет иметь тип adaptedType, и те же координаты доступа, те же режимы доступа (см. VarHandle.AccessMode), и те же гарантии атомарного доступа, что и у обработчика varHandle target.

Параметры:
target - адаптируемый обработчик varHandle доступа к памяти
adaptedType - адаптируемый тип
Возвращаемое значение:
адаптированный обработчик varHandle.
Исключения:
IllegalArgumentException - если тип носителя target не является одним из byte, short, или int; если adaptedType не является одним из int, или long; если разрядность adaptedType не превышает разрядность типа носителя target.
См. Спецификацию языка Java:
5.1.3 Сужающее примитивное преобразование

filterValue

public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)
Адаптирует целевой обработчик varHandle, предварительно обрабатывая входящие и исходящие значения с помощью пары функций фильтра.

При вызове, например, VarHandle.set(Object...) на результирующем обработчике varHandle, входящее значение (типа T, где T — тип последнего параметра первой функции фильтра) обрабатывается с помощью первой функции фильтра и затем передаётся целевому обработчику varHandle. И наоборот, при вызове, например, VarHandle.get(Object...) на результирующем обработчике varHandle, возвращаемое значение, полученное от целевого обработчика varHandle (типа T, где T — тип последнего параметра второй функции фильтра) обрабатывается с помощью второй функции фильтра и возвращается вызывающей стороне. Более продвинутые типы режимов доступа, такие как VarHandle.AccessMode.COMPARE_AND_EXCHANGE, могут применять оба фильтра одновременно.

Для корректной работы функций фильтра для преобразования в/из упакованных типов, их типы должны быть вида (A... , S) -> T и (A... , T) -> S, соответственно, где T — тип целевого обработчика varHandle. Если это так, результирующий обработчик varHandle будет иметь тип S и будет иметь дополнительные координаты A... (которые будут добавлены к координатам целевого обработчика varHandle).

Результирующий обработчик varHandle будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик varHandle.

Параметры:
target - целевой обработчик varHandle
filterToTarget - фильтр для преобразования типа S в тип target
filterFromTarget - фильтр для преобразования типа target в тип S
Возвращаемое значение:
адаптер varHandle, принимающий новый тип, выполняющий указанные преобразования в/из упакованных типов.
Исключения:
IllegalArgumentException - если filterFromTarget и filterToTarget некорректны, то есть они имеют типы, отличные от (A... , S) -> T и (A... , T) -> S, соответственно, где T — тип целевого обработчика varHandle, или если filterFromTarget или filterToTarget выбрасывают какие-либо проверяемые исключения.

filterCoordinates

public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters)
Адаптирует целевой обработчик переменной, предварительно обрабатывая входящие координатные значения с помощью унарных функций фильтрации.

При вызове, например, VarHandle.get(Object...) на результирующем обработчике переменной, входящие координатные значения, начиная с позиции pos (типа C1, C2 ... Cn, где C1, C2 ... Cn — возвращаемый тип унарных функций фильтрации), преобразуются в новые значения (типа S1, S2 ... Sn, где S1, S2 ... Sn — типы параметров унарных функций фильтрации), а затем передаются (вместе с любой координатой, которая не была изменена адаптацией) целевому обработчику переменной.

Для корректной работы координатных фильтров их типы должны соответствовать форме S1 -> T1, S2 -> T1 ... Sn -> Tn, где T1, T2 ... Tn — типы координат, начиная с позиции pos целевого обработчика переменной.

Результирующий обработчик переменной будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик переменной.

Параметры:
target - целевой обработчик переменной
pos - позиция первой координаты, которая должна быть преобразована
filters - унарные функции, используемые для преобразования координат, начиная с позиции pos
Возвращает:
адаптер обработчика переменной, который принимает новые типы координат, применяя указанное преобразование к новым координатным значениям.
Исключения:
IllegalArgumentException - если обработчики в filters не соответствуют требованиям, то есть имеют типы, отличные от S1 -> T1, S2 -> T2, ... Sn -> Tn, где T1, T2 ... Tn — типы координат, начиная с позиции pos целевого обработчика переменной, если pos не находится в диапазоне от 0 до арности целевого обработчика переменной координат включительно, или если предоставлено больше фильтров, чем фактическое количество типов координат, доступных, начиная с pos, или если какой-либо из фильтров генерирует проверяемые исключения.

insertCoordinates

public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values)
Обеспечивает целевой обработчик переменной одним или несколькими связанными координатами до вызова обработчика переменной. В результате результирующий обработчик переменной будет иметь меньше типов координат, чем целевой обработчик переменной.

При вызове, например, VarHandle.get(Object...) на результирующем обработчике переменной, входящие координатные значения объединяются со связанными координатными значениями и затем передаются целевому обработчику переменной.

Для корректности связанных координат их типы должны соответствовать T1, T2 ... Tn , где T1, T2 ... Tn — типы координат, начиная с позиции pos целевого обработчика переменной.

Результирующий обработчик переменной будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик переменной.

Параметры:
target - обработчик переменной для вызова после вставки связанных координат
pos - позиция первой координаты для вставки
values - последовательность связанных координат для вставки
Возвращает:
адаптер обработчика переменной, который вставляет дополнительные координаты перед вызовом целевого обработчика переменной
Исключения:
IllegalArgumentException - если pos не находится в диапазоне от 0 до арности координат целевого обработчика переменной включительно, или если предоставлено больше значений, чем фактическое количество типов координат, доступных, начиная с pos.
ClassCastException - если связанные координаты в values не соответствуют требованиям, то есть имеют типы, отличные от T1, T2 ... Tn , где T1, T2 ... Tn — типы координат, начиная с позиции pos целевого обработчика переменной.

permuteCoordinates

public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)
Обеспечивает обработчик переменной, который адаптирует координатные значения целевого обработчика переменной, переупорядочивая их так, что новые координаты соответствуют предоставленным.

Данный массив управляет перестановкой. Обозначим количество входящих координат через #I, (значение newCoordinates.size()) и количество исходящих координат (количество координат, связанных с целевым обработчиком переменной) через #O. Тогда длина массива переупорядочения должна быть #O, а каждый элемент должен быть неотрицательным числом, меньшим #I. Для каждого N меньше #O, N-я исходящая координата будет взята из I-й входящей координаты, где I равно reorder[N].

Преобразования значений координат не применяются. Тип каждой входящей координаты, как определено в newCoordinates, должен быть идентичен типу соответствующей исходящей координаты в целевом обработчике переменной.

Массив переупорядочения необязательно должен задавать фактическую перестановку. Входящая координата будет дублироваться, если ее индекс встречается в массиве более одного раза, и входящая координата будет пропущена, если ее индекс не встречается в массиве.

Результирующий обработчик переменной будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик переменной.

Параметры:
target - обработчик переменной для вызова после переупорядочивания координат
newCoordinates - новые типы координат
reorder - массив индексов, управляющий переупорядочиванием
Возвращает:
адаптер обработчика переменной, который переупорядочивает входящие координатные значения перед вызовом целевого обработчика переменной
Исключения:
IllegalArgumentException - если длина массива индексов не равна числу координат целевого обработчика переменной, или если какой-либо элемент массива индексов не является допустимым индексом для координаты newCoordinates, или если два соответствующих типа координат в целевом обработчике переменной и в newCoordinates не идентичны.

collectCoordinates

public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter)
Адаптирует целевой обработчик переменной, предварительно обрабатывая подпоследовательность его координатных значений с помощью фильтра (обработчика метода). Предварительно обработанные координаты заменяются результатом (если таковой имеется) функции фильтрации, а затем целевой обработчик переменной вызывается с измененным (обычно укороченным) списком координат.

Если R — возвращаемый тип фильтра (который не может быть void), целевой обработчик переменной должен принимать значение типа R в качестве координаты на позиции pos, перед и/или после любой координаты, не переданной в фильтр. Координаты не переупорядочиваются, а возвращаемый результат фильтра заменяет (по порядку) всю подпоследовательность координат, изначально переданную адаптеру.

Типы аргументов (если таковые имеются) фильтра заменяют ноль или одну координаты типа целевого обработчика переменной на позиции pos в результирующем адаптаторном обработчике переменной. Возвращаемый тип фильтра должен быть идентичен типу координаты целевого обработчика переменной на позиции pos, и эта координата целевого обработчика переменной предоставляется значением, возвращенным фильтром.

Результирующий обработчик переменной будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик переменной.

Параметры:
target - обработчик переменной для вызова после фильтрации координат
pos - позиция координаты, подлежащей фильтрации
filter - обработчик метода фильтра
Возвращает:
адаптер обработчика переменной, который фильтрует входящие координатные значения перед вызовом целевого обработчика переменной
Исключения:
IllegalArgumentException - если возвращаемый тип filter является void, или он не совпадает с типом pos координаты целевого обработчика переменной, если pos не находится в диапазоне от 0 до арности координат целевого обработчика переменной включительно, если тип результирующего обработчика переменной будет иметь слишком много координат, или если filter выбросит проверяемое исключение.

dropCoordinates

public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes)
Возвращает обработчик переменной, который будет отбрасывать некоторые фиктивные координаты перед делегированием целевому обработчику переменной. В результате результирующий обработчик переменной будет иметь больше типов координат, чем целевой обработчик переменной.

Аргумент pos может принимать значения от нуля до N, где N — арность типов координат целевого обработчика переменной. Если pos равно нулю, фиктивные координаты будут предшествовать реальным аргументам целевого обработчика; если pos равно N, они будут следовать за ними.

Результирующий обработчик переменной будет иметь те же режимы доступа (см. VarHandle.AccessMode) и гарантии атомарного доступа, что и целевой обработчик переменной.

Параметры:
target - обработчик переменной для вызова после отбрасывания фиктивных координат
pos - позиция первой координаты для отбрасывания (ноль для самой левой)
valueTypes - тип(ы) координаты(координат) для отбрасывания
Возвращает:
адаптер обработчика переменной, который отбрасывает некоторые фиктивные координаты перед вызовом целевого обработчика переменной
Исключения:
IllegalArgumentException - если pos не находится в диапазоне от 0 до арности координат целевого обработчика переменной включительно.

© 1993, 2021, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/17/docs/api/jdk.incubator.foreign/jdk/incubator/foreign/MemoryHandles.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API