Path: blob/master/src/java.base/share/classes/java/nio/BufferMismatch.java
41152 views
/*1* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package java.nio;2526import jdk.internal.misc.ScopedMemoryAccess;27import jdk.internal.util.ArraysSupport;2829/**30* Mismatch methods for buffers31*/32final class BufferMismatch {3334static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();3536static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {37int i = 0;38if (length > 7) {39if (a.get(aOff) != b.get(bOff))40return 0;41i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),42a.base(), a.address + aOff,43b.base(), b.address + bOff,44length,45ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE);46if (i >= 0) return i;47i = length - ~i;48}49for (; i < length; i++) {50if (a.get(aOff + i) != b.get(bOff + i))51return i;52}53return -1;54}5556static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) {57int i = 0;58// Ensure only heap or off-heap buffer instances use the59// vectorized mismatch. If either buffer is a StringCharBuffer60// (order is null) then the slow path is taken61if (length > 3 && a.charRegionOrder() == b.charRegionOrder()62&& a.charRegionOrder() != null && b.charRegionOrder() != null) {63if (a.get(aOff) != b.get(bOff))64return 0;65i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),66a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),67b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),68length,69ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE);70if (i >= 0) return i;71i = length - ~i;72}73for (; i < length; i++) {74if (a.get(aOff + i) != b.get(bOff + i))75return i;76}77return -1;78}7980static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {81int i = 0;82if (length > 3 && a.order() == b.order()) {83if (a.get(aOff) != b.get(bOff))84return 0;85i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),86a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),87b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),88length,89ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE);90if (i >= 0) return i;91i = length - ~i;92}93for (; i < length; i++) {94if (a.get(aOff + i) != b.get(bOff + i))95return i;96}97return -1;98}99100static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {101int i = 0;102if (length > 1 && a.order() == b.order()) {103if (a.get(aOff) != b.get(bOff))104return 0;105i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),106a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),107b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),108length,109ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE);110if (i >= 0) return i;111i = length - ~i;112}113for (; i < length; i++) {114if (a.get(aOff + i) != b.get(bOff + i))115return i;116}117return -1;118}119120static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {121int i = 0;122if (length > 1 && a.order() == b.order()) {123if (Float.floatToRawIntBits(a.get(aOff)) == Float.floatToRawIntBits(b.get(bOff))) {124i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),125a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),126b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),127length,128ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);129}130// Mismatched131if (i >= 0) {132// Check if mismatch is not associated with two NaN values; and133// is not associated with +0 and -0134float av = a.get(aOff + i);135float bv = b.get(bOff + i);136if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))137return i;138139// Fall back to slow mechanism140// ISSUE: Consider looping over vectorizedMismatch adjusting ranges141// However, requires that returned value be relative to input ranges142i++;143}144// Matched145else {146i = length - ~i;147}148}149for (; i < length; i++) {150float av = a.get(aOff + i);151float bv = b.get(bOff + i);152if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))153return i;154}155return -1;156}157158static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {159int i = 0;160if (length > 0 && a.order() == b.order()) {161if (a.get(aOff) != b.get(bOff))162return 0;163i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),164a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),165b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),166length,167ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE);168return i >= 0 ? i : -1;169}170for (; i < length; i++) {171if (a.get(aOff + i) != b.get(bOff + i))172return i;173}174return -1;175}176177static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {178int i = 0;179if (length > 0 && a.order() == b.order()) {180if (Double.doubleToRawLongBits(a.get(aOff)) == Double.doubleToRawLongBits(b.get(bOff))) {181i = SCOPED_MEMORY_ACCESS.vectorizedMismatch(a.scope(), b.scope(),182a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),183b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),184length,185ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);186}187// Mismatched188if (i >= 0) {189// Check if mismatch is not associated with two NaN values; and190// is not associated with +0 and -0191double av = a.get(aOff + i);192double bv = b.get(bOff + i);193if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))194return i;195196// Fall back to slow mechanism197// ISSUE: Consider looping over vectorizedMismatch adjusting ranges198// However, requires that returned value be relative to input ranges199i++;200}201// Matched202else {203return -1;204}205}206for (; i < length; i++) {207double av = a.get(aOff + i);208double bv = b.get(bOff + i);209if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))210return i;211}212return -1;213}214}215216217