Класс 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 |
Преобразовать существующую переменную-обработчик в новую переменную-обработчик, тип носителя которой - MemorySegment. |
static VarHandle |
asUnsigned |
Преобразует целевую переменную-обработчик, сужая входные значения и расширяя выходные значения до и от указанного типа соответственно. |
static VarHandle |
collectCoordinates |
Преобразует целевую переменную-обработчик, предварительно обрабатывая подпоследовательность её координат фильтром (методом-обработчиком). |
static VarHandle |
dropCoordinates |
Возвращает переменную-обработчик, которая отбросит некоторые фиктивные координаты перед делегированием целевой переменной-обработчику. |
static VarHandle |
filterCoordinates |
Преобразует целевую переменную-обработчик, предварительно обрабатывая входные координаты с использованием функций одноместного фильтра. |
static VarHandle |
filterValue |
Преобразует целевую переменную-обработчик, предварительно обрабатывая входные и выходные значения с помощью пары функций фильтра. |
static VarHandle |
insertCoordinates |
Предоставляет целевой переменной-обработчик одну или несколько связанных координат заранее перед вызовом переменной-обработчика. |
static VarHandle |
permuteCoordinates |
Предоставляет переменную-обработчик, которая адаптирует значения координат целевой переменной-обработчика, переупорядочив их так, чтобы новые координаты соответствовали предоставленным. |
static VarHandle |
varHandle |
Создаёт переменную-обработчик доступа к памяти с указанным типом носителя, ограничением выравнивания и порядком байтов. |
static VarHandle |
varHandle |
Создаёт переменную-обработчик доступа к памяти с указанным типом носителя и порядком байтов. |
Подробности методов
varHandle
public static VarHandle varHandle(Class<?> carrier, ByteOrder byteOrder)
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)
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)
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 может удобно использоваться для представления беззнаковых примитивных типов данных как более широких знаковых примитивных типов. Например, часто удобно моделировать беззнаковый 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.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