8246183: Scanner/ScanTest.java fails due to SIGSEGV in StubRoutines::jshort_disjoint_arraycopy

Reviewed-by: mikael, smarks
This commit is contained in:
Brian Burkhalter 2020-05-29 19:08:57 -07:00
parent cd340d5e70
commit c328bca493
4 changed files with 70 additions and 397 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, 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
@ -409,7 +409,44 @@ class Direct$Type$Buffer$RW$$BO$
public $Type$Buffer put($Type$Buffer src) {
#if[rw]
checkSegment();
super.put(src);
if (src instanceof Direct$Type$Buffer$BO$) {
if (src == this)
throw createSameBufferException();
Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src;
int spos = sb.position();
int slim = sb.limit();
assert (spos <= slim);
int srem = (spos <= slim ? slim - spos : 0);
int pos = position();
int lim = limit();
assert (pos <= lim);
int rem = (pos <= lim ? lim - pos : 0);
if (srem > rem)
throw new BufferOverflowException();
try {
UNSAFE.copyMemory(sb.ix(spos), ix(pos), (long)srem << $LG_BYTES_PER_VALUE$);
} finally {
Reference.reachabilityFence(sb);
Reference.reachabilityFence(this);
}
sb.position(spos + srem);
position(pos + srem);
} else if (src.hb != null) {
int spos = src.position();
int slim = src.limit();
assert (spos <= slim);
int srem = (spos <= slim ? slim - spos : 0);
put(src.hb, src.offset + spos, srem);
src.position(spos + srem);
} else {
super.put(src);
}
return this;
#else[rw]
throw new ReadOnlyBufferException();

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, 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
@ -47,7 +47,7 @@ class Heap$Type$Buffer$RW$
// Cached array base offset
private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
// Cached array index scale
// Cached array base offset
private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class);
// For speed these fields are actually declared in X-Buffer;
@ -244,7 +244,29 @@ class Heap$Type$Buffer$RW$
public $Type$Buffer put($Type$Buffer src) {
#if[rw]
checkSegment();
super.put(src);
if (src instanceof Heap$Type$Buffer) {
if (src == this)
throw createSameBufferException();
Heap$Type$Buffer sb = (Heap$Type$Buffer)src;
int pos = position();
int sbpos = sb.position();
int n = sb.limit() - sbpos;
if (n > limit() - pos)
throw new BufferOverflowException();
System.arraycopy(sb.hb, sb.ix(sbpos),
hb, ix(pos), n);
sb.position(sbpos + n);
position(pos + n);
} else if (src.isDirect()) {
int n = src.remaining();
int pos = position();
if (n > limit() - pos)
throw new BufferOverflowException();
src.get(hb, ix(pos), n);
position(pos + n);
} else {
super.put(src);
}
return this;
#else[rw]
throw new ReadOnlyBufferException();

View file

@ -30,7 +30,6 @@ package java.nio;
#if[char]
import java.io.IOException;
#end[char]
import java.lang.ref.Reference;
#if[streamableType]
import java.util.Spliterator;
import java.util.stream.StreamSupport;
@ -117,7 +116,7 @@ import jdk.internal.util.ArraysSupport;
* obvious. It is therefore recommended that direct buffers be allocated
* primarily for large, long-lived buffers that are subject to the underlying
* system's native I/O operations. In general it is best to allocate direct
* buffers only when they yield a measurable gain in program performance.
* buffers only when they yield a measureable gain in program performance.
*
* <p> A direct byte buffer may also be created by {@link
* java.nio.channels.FileChannel#map mapping} a region of a file
@ -923,10 +922,7 @@ public abstract class $Type$Buffer
* dst.put(src.get()); </pre>
*
* except that it first checks that there is sufficient space in this
* buffer and it is potentially much more efficient. If this buffer and
* the source buffer share the same backing array or memory, then the
* result will be as if the source elements were first copied to an
* intermediate location before being written into this buffer.
* buffer and it is potentially much more efficient.
*
* @param src
* The source buffer from which $type$s are to be read;
@ -949,58 +945,11 @@ public abstract class $Type$Buffer
throw createSameBufferException();
if (isReadOnly())
throw new ReadOnlyBufferException();
int srcPos = src.position();
int n = src.limit() - srcPos;
int pos = position();
if (n > limit() - pos)
int n = src.remaining();
if (n > remaining())
throw new BufferOverflowException();
long len = (long)n << $LG_BYTES_PER_VALUE$;
Object base = base();
Object srcBase = src.base();
#if[!byte]
if (this.order() == src.order()) {
#end[!byte]
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
long srcAddr = src.address + ((long)srcPos << $LG_BYTES_PER_VALUE$);
try {
UNSAFE.copyMemory(srcBase,
srcAddr,
base,
addr,
len);
} finally {
Reference.reachabilityFence(src);
Reference.reachabilityFence(this);
}
position(pos + n);
src.position(srcPos + n);
#if[!byte]
} else {
long addr = address + ((long)pos << $LG_BYTES_PER_VALUE$);
long srcAddr = src.address + ((long)srcPos << $LG_BYTES_PER_VALUE$);
try {
UNSAFE.copySwapMemory(srcBase,
srcAddr,
base,
addr,
len,
(long)1 << $LG_BYTES_PER_VALUE$);
} finally {
Reference.reachabilityFence(src);
Reference.reachabilityFence(this);
}
position(pos + n);
src.position(srcPos + n);
}
#end[!byte]
for (int i = 0; i < n; i++)
put(src.get());
return this;
}