All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.memory.UnsafeUtil Maven / Gradle / Ivy

/*
 * Copyright 2015-16, Yahoo! Inc.
 * Licensed under the terms of the Apache License 2.0. See LICENSE file at the project root for terms.
 */

package com.yahoo.memory;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import sun.misc.Unsafe;

/**
 * Provides access to the sun.misc.Unsafe class and its key static fields.
 *
 * 

NOTE: Native/Direct memory acquired using Unsafe may have garbage in it. * It is the responsibility of the using class to clear this memory, if required, * and to call freeMemory() when done. * * @author Lee Rhodes */ //@SuppressWarnings("restriction") public final class UnsafeUtil { public static final Unsafe unsafe; public static final int ADDRESS_SIZE; //not an indicator of whether compressed references are used. //varies depending on compressed ref, 16 or 24 for 64-bit systems public static final int ARRAY_BOOLEAN_BASE_OFFSET; public static final int ARRAY_BYTE_BASE_OFFSET; public static final int ARRAY_SHORT_BASE_OFFSET; public static final int ARRAY_CHAR_BASE_OFFSET; public static final int ARRAY_INT_BASE_OFFSET; public static final int ARRAY_LONG_BASE_OFFSET; public static final int ARRAY_FLOAT_BASE_OFFSET; public static final int ARRAY_DOUBLE_BASE_OFFSET; public static final int ARRAY_OBJECT_BASE_OFFSET; //@formatter:off public static final int ARRAY_BOOLEAN_INDEX_SCALE; // 1 public static final int ARRAY_BYTE_INDEX_SCALE; // 1 public static final int ARRAY_SHORT_INDEX_SCALE; // 2 public static final int ARRAY_CHAR_INDEX_SCALE; // 2 public static final int ARRAY_INT_INDEX_SCALE; // 4 public static final int ARRAY_LONG_INDEX_SCALE; // 8 public static final int ARRAY_FLOAT_INDEX_SCALE; // 4 public static final int ARRAY_DOUBLE_INDEX_SCALE; // 8 public static final int ARRAY_OBJECT_INDEX_SCALE; // varies, 4 or 8 depending on compressed ref //Used to convert "type" to bytes: bytes = longs << LONG_SHIFT public static final int BOOLEAN_SHIFT = 0; public static final int BYTE_SHIFT = 0; public static final int SHORT_SHIFT = 1; public static final int CHAR_SHIFT = 1; public static final int INT_SHIFT = 2; public static final int LONG_SHIFT = 3; public static final int FLOAT_SHIFT = 2; public static final int DOUBLE_SHIFT = 3; public static final String LS = System.getProperty("line.separator"); //@formatter:on /** * This number limits the number of bytes to copy per call to Unsafe's copyMemory method. * A limit is imposed to allow for safepoint polling during a large copy. */ public static final long UNSAFE_COPY_THRESHOLD = 1L << 20; //2^20 static { try { //should work across JVMs, e.g., with Android: final Constructor unsafeConstructor = Unsafe.class.getDeclaredConstructor(); unsafeConstructor.setAccessible(true); unsafe = unsafeConstructor.newInstance(); // Alternative, but may not work across different JVMs. // Field field = Unsafe.class.getDeclaredField("theUnsafe"); // field.setAccessible(true); // unsafe = (Unsafe) field.get(null); } catch (final InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) { e.printStackTrace(); throw new RuntimeException("Unable to acquire Unsafe. ", e); } //4 on 32-bits systems and 64-bit systems < 32GB, otherwise 8. //This alone is not an indicator of compressed ref (Oop) ADDRESS_SIZE = unsafe.addressSize(); ARRAY_BOOLEAN_BASE_OFFSET = unsafe.arrayBaseOffset(boolean[].class); ARRAY_BYTE_BASE_OFFSET = unsafe.arrayBaseOffset(byte[].class); ARRAY_SHORT_BASE_OFFSET = unsafe.arrayBaseOffset(short[].class); ARRAY_CHAR_BASE_OFFSET = unsafe.arrayBaseOffset(char[].class); ARRAY_INT_BASE_OFFSET = unsafe.arrayBaseOffset(int[].class); ARRAY_LONG_BASE_OFFSET = unsafe.arrayBaseOffset(long[].class); ARRAY_FLOAT_BASE_OFFSET = unsafe.arrayBaseOffset(float[].class); ARRAY_DOUBLE_BASE_OFFSET = unsafe.arrayBaseOffset(double[].class); ARRAY_OBJECT_BASE_OFFSET = unsafe.arrayBaseOffset(Object[].class); ARRAY_BOOLEAN_INDEX_SCALE = unsafe.arrayIndexScale(boolean[].class); ARRAY_BYTE_INDEX_SCALE = unsafe.arrayIndexScale(byte[].class); ARRAY_SHORT_INDEX_SCALE = unsafe.arrayIndexScale(short[].class); ARRAY_CHAR_INDEX_SCALE = unsafe.arrayIndexScale(char[].class); ARRAY_INT_INDEX_SCALE = unsafe.arrayIndexScale(int[].class); ARRAY_LONG_INDEX_SCALE = unsafe.arrayIndexScale(long[].class); ARRAY_FLOAT_INDEX_SCALE = unsafe.arrayIndexScale(float[].class); ARRAY_DOUBLE_INDEX_SCALE = unsafe.arrayIndexScale(double[].class); ARRAY_OBJECT_INDEX_SCALE = unsafe.arrayIndexScale(Object[].class); } private UnsafeUtil() {} /** * Perform bounds checking using java assert (if enabled) checking the requested offset and length * against the allocated size. * If reqOff + reqLen > allocSize or any of the parameters are negative an exception will * be thrown. * @param reqOff the requested offset * @param reqLen the requested length * @param allocSize the allocated size. */ public static void assertBounds(final long reqOff, final long reqLen, final long allocSize) { assert ((reqOff | reqLen | (reqOff + reqLen) | (allocSize - (reqOff + reqLen))) >= 0) : "reqOffset: " + reqOff + ", reqLength: " + reqLen + ", (reqOff + reqLen): " + (reqOff + reqLen) + ", allocSize: " + allocSize; } /** * Check the requested offset and length against the allocated size. * If reqOff + reqLen > allocSize or any of the parameters are negative an exception will * be thrown. * @param reqOff the requested offset * @param reqLen the requested length * @param allocSize the allocated size. */ public static void checkBounds(final long reqOff, final long reqLen, final long allocSize) { if ((reqOff | reqLen | (reqOff + reqLen) | (allocSize - (reqOff + reqLen))) < 0) { throw new IllegalArgumentException( "reqOffset: " + reqOff + ", reqLength: " + ", (reqOff + reqLen): " + (reqOff + reqLen) + ", allocSize: " + allocSize); } } /** * Return true if the given offsets and length do not overlap. * @param srcOff the start of the source region * @param dstOff the start of the destination region * @param length the length of both regions * @return true if the given offsets and length do not overlap. */ public static boolean checkOverlap(final long srcOff, final long dstOff, final long length) { final long min = Math.min(srcOff, dstOff); final long max = Math.max(srcOff, dstOff); return (min + length) <= max; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy