Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8284883: JVM crash: guarantee(sect->end() <= sect->limit()) failed: s…
…anity on AVX512

Reviewed-by: kvn, jbhateja
  • Loading branch information
dean-long committed Apr 29, 2022
1 parent 3d07b3c commit cd8709e
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 9 deletions.
41 changes: 33 additions & 8 deletions src/hotspot/cpu/x86/macroAssembler_x86.cpp
Expand Up @@ -5277,10 +5277,28 @@ void MacroAssembler::clear_mem(Register base, int cnt, Register rtmp, XMMRegiste

int vector64_count = (cnt & (~0x7)) >> 3;
cnt = cnt & 0x7;
const int fill64_per_loop = 4;
const int max_unrolled_fill64 = 8;

// 64 byte initialization loop.
vpxor(xtmp, xtmp, xtmp, use64byteVector ? AVX_512bit : AVX_256bit);
for (int i = 0; i < vector64_count; i++) {
int start64 = 0;
if (vector64_count > max_unrolled_fill64) {
Label LOOP;
Register index = rtmp;

start64 = vector64_count - (vector64_count % fill64_per_loop);

movl(index, 0);
BIND(LOOP);
for (int i = 0; i < fill64_per_loop; i++) {
fill64(Address(base, index, Address::times_1, i * 64), xtmp, use64byteVector);
}
addl(index, fill64_per_loop * 64);
cmpl(index, start64 * 64);
jccb(Assembler::less, LOOP);
}
for (int i = start64; i < vector64_count; i++) {
fill64(base, i * 64, xtmp, use64byteVector);
}

Expand Down Expand Up @@ -8874,22 +8892,29 @@ void MacroAssembler::fill32_masked(uint shift, Register dst, int disp,
}


void MacroAssembler::fill32(Register dst, int disp, XMMRegister xmm) {
void MacroAssembler::fill32(Address dst, XMMRegister xmm) {
assert(MaxVectorSize >= 32, "vector length should be >= 32");
vmovdqu(Address(dst, disp), xmm);
vmovdqu(dst, xmm);
}

void MacroAssembler::fill64(Register dst, int disp, XMMRegister xmm, bool use64byteVector) {
void MacroAssembler::fill32(Register dst, int disp, XMMRegister xmm) {
fill32(Address(dst, disp), xmm);
}

void MacroAssembler::fill64(Address dst, XMMRegister xmm, bool use64byteVector) {
assert(MaxVectorSize >= 32, "vector length should be >= 32");
BasicType type[] = {T_BYTE, T_SHORT, T_INT, T_LONG};
if (!use64byteVector) {
fill32(dst, disp, xmm);
fill32(dst, disp + 32, xmm);
fill32(dst, xmm);
fill32(dst.plus_disp(32), xmm);
} else {
evmovdquq(Address(dst, disp), xmm, Assembler::AVX_512bit);
evmovdquq(dst, xmm, Assembler::AVX_512bit);
}
}

void MacroAssembler::fill64(Register dst, int disp, XMMRegister xmm, bool use64byteVector) {
fill64(Address(dst, disp), xmm, use64byteVector);
}

#ifdef _LP64
void MacroAssembler::generate_fill_avx3(BasicType type, Register to, Register value,
Register count, Register rtmp, XMMRegister xtmp) {
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/cpu/x86/macroAssembler_x86.hpp
Expand Up @@ -1985,8 +1985,12 @@ class MacroAssembler: public Assembler {
XMMRegister xmm, KRegister mask, Register length,
Register temp);

void fill32(Address dst, XMMRegister xmm);

void fill32(Register dst, int disp, XMMRegister xmm);

void fill64(Address dst, XMMRegister xmm, bool use64byteVector = false);

void fill64(Register dst, int dis, XMMRegister xmm, bool use64byteVector = false);

#ifdef _LP64
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/opto/memnode.cpp
Expand Up @@ -3072,7 +3072,7 @@ Node* ClearArrayNode::Identity(PhaseGVN* phase) {
// Clearing a short array is faster with stores
Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Already know this is a large node, do not try to ideal it
if (!IdealizeClearArrayNode || _is_large) return NULL;
if (_is_large) return NULL;

const int unit = BytesPerLong;
const TypeX* t = phase->type(in(2))->isa_intptr_t();
Expand All @@ -3093,6 +3093,7 @@ Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
} else if (size > 2 && Matcher::match_rule_supported_vector(Op_ClearArray, 4, T_LONG)) {
return NULL;
}
if (!IdealizeClearArrayNode) return NULL;
Node *mem = in(1);
if( phase->type(mem)==Type::TOP ) return NULL;
Node *adr = in(3);
Expand Down
51 changes: 51 additions & 0 deletions test/hotspot/jtreg/compiler/c2/ClearArray.java
@@ -0,0 +1,51 @@
/*
* 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.
*
*/

/*
* @test ClearArray.java
* @bug 8284883
* @compile ClearArray.java
* @summary ClearArray instruction overflows scratch buffer
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:-TieredCompilation -Xbatch
* -XX:InitArrayShortSize=32768 -XX:-IdealizeClearArrayNode compiler.c2.ClearArray
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Xbatch
* -XX:InitArrayShortSize=32768 -XX:-IdealizeClearArrayNode -XX:UseAVX=3 compiler.c2.ClearArray
*/

package compiler.c2;

public class ClearArray {

static long[] STATIC;

static void foo() {
STATIC = new long[2048 - 1];
}

public static void main(String[] args) {
for (int i = 0; i < 20_000; ++i) {
foo();
}
}
}

1 comment on commit cd8709e

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.