Merge
This commit is contained in:
commit
39f140a201
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2022, 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
|
||||
@ -234,7 +234,7 @@ AC_DEFUN_ONCE([TOOLCHAIN_DETERMINE_TOOLCHAIN_TYPE],
|
||||
if test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
||||
if test -n "$XCODEBUILD"; then
|
||||
# On Mac OS X, default toolchain to clang after Xcode 5
|
||||
XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version 2>&1 | $HEAD -n 1`
|
||||
XCODE_VERSION_OUTPUT=`"$XCODEBUILD" -version | $HEAD -n 1`
|
||||
$ECHO "$XCODE_VERSION_OUTPUT" | $GREP "Xcode " > /dev/null
|
||||
if test $? -ne 0; then
|
||||
AC_MSG_NOTICE([xcodebuild output: $XCODE_VERSION_OUTPUT])
|
||||
|
@ -81,8 +81,6 @@ void RangeCheckStub::emit_code(LIR_Assembler* ce) {
|
||||
|
||||
if (_info->deoptimize_on_exception()) {
|
||||
address a = Runtime1::entry_for(Runtime1::predicate_failed_trap_id);
|
||||
// May be used by optimizations like LoopInvariantCodeMotion or RangeCheckEliminator.
|
||||
DEBUG_ONLY( __ untested("RangeCheckStub: predicate_failed_trap_id"); )
|
||||
//__ load_const_optimized(R0, a);
|
||||
__ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(a));
|
||||
__ mtctr(R0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2022 SAP SE. 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
|
||||
@ -294,9 +294,56 @@ void frame::patch_pc(Thread* thread, address pc) {
|
||||
}
|
||||
|
||||
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// Is there anything to do?
|
||||
assert(is_interpreted_frame(), "Not an interpreted frame");
|
||||
return true;
|
||||
// These are reasonable sanity checks
|
||||
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (fp() - (abi_minframe_size + ijava_state_size) < sp()) {
|
||||
return false;
|
||||
}
|
||||
// These are hacks to keep us out of trouble.
|
||||
// The problem with these is that they mask other problems
|
||||
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
|
||||
return false;
|
||||
}
|
||||
|
||||
// do some validation of frame elements
|
||||
|
||||
// first the method
|
||||
|
||||
Method* m = *interpreter_frame_method_addr();
|
||||
|
||||
// validate the method we'd find in this potential sender
|
||||
if (!Method::is_valid_method(m)) return false;
|
||||
|
||||
// stack frames shouldn't be much larger than max_stack elements
|
||||
// this test requires the use of unextended_sp which is the sp as seen by
|
||||
// the current frame, and not sp which is the "raw" pc which could point
|
||||
// further because of local variables of the callee method inserted after
|
||||
// method arguments
|
||||
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate bci/bcx
|
||||
|
||||
address bcp = interpreter_frame_bcp();
|
||||
if (m->validate_bci_from_bcp(bcp) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate constantPoolCache*
|
||||
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
|
||||
if (MetaspaceObj::is_valid(cp) == false) return false;
|
||||
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019 SAP SE. All rights reserved.
|
||||
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2022 SAP SE. 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
|
||||
@ -298,9 +298,56 @@ void frame::patch_pc(Thread* thread, address pc) {
|
||||
}
|
||||
|
||||
bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// Is there anything to do?
|
||||
assert(is_interpreted_frame(), "Not an interpreted frame");
|
||||
return true;
|
||||
// These are reasonable sanity checks
|
||||
if (fp() == 0 || (intptr_t(fp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (sp() == 0 || (intptr_t(sp()) & (wordSize-1)) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (fp() - (z_abi_16_size + z_ijava_state_size) < sp()) {
|
||||
return false;
|
||||
}
|
||||
// These are hacks to keep us out of trouble.
|
||||
// The problem with these is that they mask other problems
|
||||
if (fp() <= sp()) { // this attempts to deal with unsigned comparison above
|
||||
return false;
|
||||
}
|
||||
|
||||
// do some validation of frame elements
|
||||
|
||||
// first the method
|
||||
|
||||
Method* m = *interpreter_frame_method_addr();
|
||||
|
||||
// validate the method we'd find in this potential sender
|
||||
if (!Method::is_valid_method(m)) return false;
|
||||
|
||||
// stack frames shouldn't be much larger than max_stack elements
|
||||
// this test requires the use of unextended_sp which is the sp as seen by
|
||||
// the current frame, and not sp which is the "raw" pc which could point
|
||||
// further because of local variables of the callee method inserted after
|
||||
// method arguments
|
||||
if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate bci/bcx
|
||||
|
||||
address bcp = interpreter_frame_bcp();
|
||||
if (m->validate_bci_from_bcp(bcp) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// validate constantPoolCache*
|
||||
ConstantPoolCache* cp = *interpreter_frame_cache_addr();
|
||||
if (MetaspaceObj::is_valid(cp) == false) return false;
|
||||
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
|
||||
|
@ -266,7 +266,7 @@ public sealed interface MemorySegment extends Addressable permits AbstractMemory
|
||||
* <p>
|
||||
* The returned spliterator splits this segment according to the specified element layout; that is,
|
||||
* if the supplied layout has size N, then calling {@link Spliterator#trySplit()} will result in a spliterator serving
|
||||
* approximately {@code S/N/2} elements (depending on whether N is even or not), where {@code S} is the size of
|
||||
* approximately {@code S/N} elements (depending on whether N is even or not), where {@code S} is the size of
|
||||
* this segment. As such, splitting is possible as long as {@code S/N >= 2}. The spliterator returns segments that
|
||||
* are associated with the same scope as this segment.
|
||||
* <p>
|
||||
|
@ -36,13 +36,17 @@ import java.nio.ByteBuffer;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Implementation for heap memory segments. An heap memory segment is composed by an offset and
|
||||
* Implementation for heap memory segments. A heap memory segment is composed by an offset and
|
||||
* a base object (typically an array). To enhance performances, the access to the base object needs to feature
|
||||
* sharp type information, as well as sharp null-check information. For this reason, many concrete subclasses
|
||||
* of {@link HeapMemorySegmentImpl} are defined (e.g. {@link OfFloat}, so that each subclass can override the
|
||||
* {@link HeapMemorySegmentImpl#base()} method so that it returns an array of the correct (sharp) type.
|
||||
* {@link HeapMemorySegmentImpl#base()} method so that it returns an array of the correct (sharp) type. Note that
|
||||
* the field type storing the 'base' coordinate is just Object; similarly, all the constructor in the subclasses
|
||||
* accept an Object 'base' parameter instead of a sharper type (e.g. {@code byte[]}). This is deliberate, as
|
||||
* using sharper types would require use of type-conversions, which in turn would inhibit some C2 optimizations,
|
||||
* such as the elimination of store barriers in methods like {@link HeapMemorySegmentImpl#dup(long, long, int, ResourceScopeImpl)}.
|
||||
*/
|
||||
public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl {
|
||||
public abstract class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl {
|
||||
|
||||
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
|
||||
private static final int BYTE_ARR_BASE = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
@ -53,17 +57,17 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
private static final long MAX_ALIGN_8 = 8;
|
||||
|
||||
final long offset;
|
||||
final H base;
|
||||
final Object base;
|
||||
|
||||
@ForceInline
|
||||
HeapMemorySegmentImpl(long offset, H base, long length, int mask) {
|
||||
HeapMemorySegmentImpl(long offset, Object base, long length, int mask) {
|
||||
super(length, mask, ResourceScopeImpl.GLOBAL);
|
||||
this.offset = offset;
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
@Override
|
||||
abstract H base();
|
||||
abstract Object base();
|
||||
|
||||
@Override
|
||||
long min() {
|
||||
@ -71,7 +75,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
|
||||
@Override
|
||||
abstract HeapMemorySegmentImpl<H> dup(long offset, long size, int mask, ResourceScopeImpl scope);
|
||||
abstract HeapMemorySegmentImpl dup(long offset, long size, int mask, ResourceScopeImpl scope);
|
||||
|
||||
@Override
|
||||
ByteBuffer makeByteBuffer() {
|
||||
@ -84,9 +88,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
// factories
|
||||
|
||||
public static class OfByte extends HeapMemorySegmentImpl<byte[]> {
|
||||
public static class OfByte extends HeapMemorySegmentImpl {
|
||||
|
||||
OfByte(long offset, byte[] base, long length, int mask) {
|
||||
OfByte(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -97,7 +101,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
byte[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (byte[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(byte[] arr) {
|
||||
@ -112,9 +116,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfChar extends HeapMemorySegmentImpl<char[]> {
|
||||
public static class OfChar extends HeapMemorySegmentImpl {
|
||||
|
||||
OfChar(long offset, char[] base, long length, int mask) {
|
||||
OfChar(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -125,7 +129,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
char[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (char[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(char[] arr) {
|
||||
@ -140,9 +144,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfShort extends HeapMemorySegmentImpl<short[]> {
|
||||
public static class OfShort extends HeapMemorySegmentImpl {
|
||||
|
||||
OfShort(long offset, short[] base, long length, int mask) {
|
||||
OfShort(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -153,7 +157,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
short[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (short[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(short[] arr) {
|
||||
@ -168,9 +172,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfInt extends HeapMemorySegmentImpl<int[]> {
|
||||
public static class OfInt extends HeapMemorySegmentImpl {
|
||||
|
||||
OfInt(long offset, int[] base, long length, int mask) {
|
||||
OfInt(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -181,7 +185,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
int[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (int[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(int[] arr) {
|
||||
@ -196,9 +200,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfLong extends HeapMemorySegmentImpl<long[]> {
|
||||
public static class OfLong extends HeapMemorySegmentImpl {
|
||||
|
||||
OfLong(long offset, long[] base, long length, int mask) {
|
||||
OfLong(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -209,7 +213,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
long[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (long[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(long[] arr) {
|
||||
@ -224,9 +228,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfFloat extends HeapMemorySegmentImpl<float[]> {
|
||||
public static class OfFloat extends HeapMemorySegmentImpl {
|
||||
|
||||
OfFloat(long offset, float[] base, long length, int mask) {
|
||||
OfFloat(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -237,7 +241,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
float[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (float[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(float[] arr) {
|
||||
@ -252,9 +256,9 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
}
|
||||
}
|
||||
|
||||
public static class OfDouble extends HeapMemorySegmentImpl<double[]> {
|
||||
public static class OfDouble extends HeapMemorySegmentImpl {
|
||||
|
||||
OfDouble(long offset, double[] base, long length, int mask) {
|
||||
OfDouble(long offset, Object base, long length, int mask) {
|
||||
super(offset, base, length, mask);
|
||||
}
|
||||
|
||||
@ -265,7 +269,7 @@ public abstract class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl
|
||||
|
||||
@Override
|
||||
double[] base() {
|
||||
return Objects.requireNonNull(base);
|
||||
return (double[])Objects.requireNonNull(base);
|
||||
}
|
||||
|
||||
public static MemorySegment fromArray(double[] arr) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2017, 2022, 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
|
||||
@ -37,6 +37,7 @@
|
||||
* -XX:+SegmentedCodeCache
|
||||
* -XX:ReservedCodeCacheSize=16M
|
||||
* -XX:CodeCacheMinBlockLength=1
|
||||
* -XX:CICompilerCount=2
|
||||
* compiler.codecache.stress.ReturnBlobToWrongHeapTest
|
||||
*/
|
||||
|
||||
|
@ -826,6 +826,7 @@ jdk/jfr/event/os/TestThreadContextSwitches.java 8247776 windows-
|
||||
jdk/jfr/startupargs/TestStartName.java 8214685 windows-x64
|
||||
jdk/jfr/startupargs/TestStartDuration.java 8214685 windows-x64
|
||||
jdk/jfr/event/oldobject/TestLargeRootSet.java 8276333 macosx-x64,windows-x64
|
||||
jdk/jfr/api/consumer/recordingstream/TestOnEvent.java 8255404 linux-x64
|
||||
|
||||
############################################################################
|
||||
|
||||
|
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2022, 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.
|
||||
*
|
||||
* 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 org.openjdk.bench.jdk.incubator.foreign;
|
||||
|
||||
import jdk.incubator.foreign.MemorySegment;
|
||||
import jdk.incubator.foreign.ResourceScope;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Fork;
|
||||
import org.openjdk.jmh.annotations.Measurement;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
import org.openjdk.jmh.annotations.TearDown;
|
||||
import org.openjdk.jmh.annotations.Warmup;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static jdk.incubator.foreign.MemoryLayout.PathElement.sequenceElement;
|
||||
import static jdk.incubator.foreign.ValueLayout.JAVA_INT;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@State(org.openjdk.jmh.annotations.Scope.Thread)
|
||||
@OutputTimeUnit(TimeUnit.MILLISECONDS)
|
||||
@Fork(value = 3, jvmArgsAppend = { "--add-modules=jdk.incubator.foreign", "--enable-native-access=ALL-UNNAMED" })
|
||||
|
||||
public class LoopOverSlice {
|
||||
|
||||
static final int ELEM_SIZE = 1_000_000;
|
||||
static final int CARRIER_SIZE = (int)JAVA_INT.byteSize();
|
||||
static final int ALLOC_SIZE = ELEM_SIZE * CARRIER_SIZE;
|
||||
|
||||
MemorySegment nativeSegment, heapSegment;
|
||||
IntBuffer nativeBuffer, heapBuffer;
|
||||
ResourceScope scope;
|
||||
|
||||
@Setup
|
||||
public void setup() {
|
||||
scope = ResourceScope.newConfinedScope();
|
||||
nativeSegment = MemorySegment.allocateNative(ALLOC_SIZE, scope);
|
||||
heapSegment = MemorySegment.ofArray(new int[ELEM_SIZE]);
|
||||
nativeBuffer = ByteBuffer.allocateDirect(ALLOC_SIZE).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
|
||||
heapBuffer = IntBuffer.wrap(new int[ELEM_SIZE]);
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void tearDown() {
|
||||
scope.close();
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void native_segment_slice_loop() {
|
||||
new NativeSegmentWrapper(nativeSegment).forEach(NativeSegmentWrapper.Element::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void native_buffer_slice_loop() {
|
||||
new NativeBufferWrapper(nativeBuffer).forEach(NativeBufferWrapper.Element::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void heap_segment_slice_loop() {
|
||||
new HeapSegmentWrapper(heapSegment).forEach(HeapSegmentWrapper.Element::get);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void heap_buffer_slice_loop() {
|
||||
new HeapBufferWrapper(heapBuffer).forEach(HeapBufferWrapper.Element::get);
|
||||
}
|
||||
|
||||
class HeapSegmentWrapper implements Iterable<HeapSegmentWrapper.Element> {
|
||||
final MemorySegment segment;
|
||||
|
||||
public HeapSegmentWrapper(MemorySegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Element> iterator() {
|
||||
return new Iterator<Element>() {
|
||||
|
||||
MemorySegment current = segment;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current.byteSize() > 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element next() {
|
||||
Element element = new Element(current);
|
||||
current = current.asSlice(4);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class Element {
|
||||
final MemorySegment segment;
|
||||
|
||||
public Element(MemorySegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
int get() {
|
||||
return segment.getAtIndex(JAVA_INT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NativeSegmentWrapper implements Iterable<NativeSegmentWrapper.Element> {
|
||||
final MemorySegment segment;
|
||||
|
||||
public NativeSegmentWrapper(MemorySegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Element> iterator() {
|
||||
return new Iterator<Element>() {
|
||||
|
||||
MemorySegment current = segment;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current.byteSize() > 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element next() {
|
||||
Element element = new Element(current);
|
||||
current = current.asSlice(4);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class Element {
|
||||
final MemorySegment segment;
|
||||
|
||||
public Element(MemorySegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
int get() {
|
||||
return segment.getAtIndex(JAVA_INT, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NativeBufferWrapper implements Iterable<NativeBufferWrapper.Element> {
|
||||
final IntBuffer buffer;
|
||||
|
||||
public NativeBufferWrapper(IntBuffer buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Element> iterator() {
|
||||
return new Iterator<Element>() {
|
||||
|
||||
IntBuffer current = buffer;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current.position() < current.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element next() {
|
||||
Element element = new Element(current);
|
||||
int lim = current.limit();
|
||||
current = current.slice(1, lim - 1);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class Element {
|
||||
final IntBuffer buffer;
|
||||
|
||||
public Element(IntBuffer segment) {
|
||||
this.buffer = segment;
|
||||
}
|
||||
|
||||
int get() {
|
||||
return buffer.get( 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HeapBufferWrapper implements Iterable<HeapBufferWrapper.Element> {
|
||||
final IntBuffer buffer;
|
||||
|
||||
public HeapBufferWrapper(IntBuffer buffer) {
|
||||
this.buffer = buffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Element> iterator() {
|
||||
return new Iterator<Element>() {
|
||||
|
||||
IntBuffer current = buffer;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current.position() < current.limit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element next() {
|
||||
Element element = new Element(current);
|
||||
int lim = current.limit();
|
||||
current = current.slice(1, lim - 1);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class Element {
|
||||
final IntBuffer buffer;
|
||||
|
||||
public Element(IntBuffer segment) {
|
||||
this.buffer = segment;
|
||||
}
|
||||
|
||||
int get() {
|
||||
return buffer.get( 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user