Skip to content
Permalink
Browse files
Merge pull request #109 from gianm/cache-array-base-offset
Cache arrayBaseOffset.
  • Loading branch information
leerho committed Aug 1, 2019
2 parents 7e97638 + c48c149 commit 68fd246bd1c1ac2792ec46e5070071e29b9f6492
Showing 3 changed files with 59 additions and 3 deletions.
@@ -94,7 +94,7 @@ abstract class BaseState {
capacityBytes_ = capacityBytes;
cumBaseOffset_ = regionOffset + ((unsafeObj == null)
? nativeBaseOffset
: unsafe.arrayBaseOffset(unsafeObj.getClass()));
: UnsafeUtil.getArrayBaseOffset(unsafeObj.getClass()));
}

//Byte Order Related
@@ -233,7 +233,7 @@ public final long getRegionOffset() {
final Object unsafeObj = getUnsafeObject();
return (unsafeObj == null)
? cumBaseOffset_ - getNativeBaseOffset()
: cumBaseOffset_ - unsafe.arrayBaseOffset(unsafeObj.getClass());
: cumBaseOffset_ - UnsafeUtil.getArrayBaseOffset(unsafeObj.getClass());
}

/**
@@ -518,7 +518,7 @@ static final String toHex(final BaseState state, final String preamble, final lo
uObjHeader = 0;
} else {
uObjStr = uObj.getClass().getSimpleName() + ", " + (uObj.hashCode() & 0XFFFFFFFFL);
uObjHeader = unsafe.arrayBaseOffset(uObj.getClass());
uObjHeader = UnsafeUtil.getArrayBaseOffset(uObj.getClass());
}
final ByteBuffer bb = state.getByteBuffer();
final String bbStr = (bb == null) ? "null"
@@ -157,6 +157,35 @@ static long getFieldOffset(final Class<?> c, final String fieldName) {
}
}

/**
* Like {@link Unsafe#arrayBaseOffset(Class)}, but caches return values for common array types. Useful because
* calling {@link Unsafe#arrayBaseOffset(Class)} directly incurs more overhead.
*/
static long getArrayBaseOffset(final Class<?> c) {
// Ordering here is roughly in order of what we expect to be most popular.
if (c == byte[].class) {
return ARRAY_BYTE_BASE_OFFSET;
} else if (c == int[].class) {
return ARRAY_INT_BASE_OFFSET;
} else if (c == long[].class) {
return ARRAY_LONG_BASE_OFFSET;
} else if (c == float[].class) {
return ARRAY_FLOAT_BASE_OFFSET;
} else if (c == double[].class) {
return ARRAY_DOUBLE_BASE_OFFSET;
} else if (c == boolean[].class) {
return ARRAY_BOOLEAN_BASE_OFFSET;
} else if (c == short[].class) {
return ARRAY_SHORT_BASE_OFFSET;
} else if (c == char[].class) {
return ARRAY_CHAR_BASE_OFFSET;
} else if (c == Object[].class) {
return ARRAY_OBJECT_BASE_OFFSET;
} else {
return unsafe.arrayBaseOffset(c);
}
}

/**
* Assert the requested offset and length against the allocated size.
* The invariants equation is: {@code 0 <= reqOff <= reqLen <= reqOff + reqLen <= allocSize}.
@@ -23,6 +23,9 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

import java.util.ArrayList;
import java.util.List;

import org.testng.annotations.Test;


@@ -122,6 +125,30 @@ public void checkInts() {
Ints.checkedCast(1L << 32);
}

@Test
public void checkArrayBaseOffset()
{
final List<Class<?>> classes = new ArrayList<>();
classes.add(byte[].class);
classes.add(int[].class);
classes.add(long[].class);
classes.add(float[].class);
classes.add(double[].class);
classes.add(boolean[].class);
classes.add(short[].class);
classes.add(char[].class);
classes.add(Object[].class);
classes.add(byte[][].class); // An array type that is not cached

for (Class<?> clazz : classes) {
assertEquals(
UnsafeUtil.getArrayBaseOffset(clazz),
UnsafeUtil.unsafe.arrayBaseOffset(clazz),
clazz.getTypeName()
);
}
}

@Test
public void printlnTest() {
println("PRINTING: "+this.getClass().getName());

0 comments on commit 68fd246

Please sign in to comment.