mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
6795465: Crash in assembler_sparc.cpp with client compiler on solaris-sparc
Reviewed-by: twisti, cfang
This commit is contained in:
parent
05c34e93bd
commit
cc01c0f4f6
5 changed files with 66 additions and 20 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -38,7 +38,7 @@ enum {
|
||||||
// registers
|
// registers
|
||||||
enum {
|
enum {
|
||||||
pd_nof_cpu_regs_frame_map = 32, // number of registers used during code emission
|
pd_nof_cpu_regs_frame_map = 32, // number of registers used during code emission
|
||||||
pd_nof_caller_save_cpu_regs_frame_map = 6, // number of cpu registers killed by calls
|
pd_nof_caller_save_cpu_regs_frame_map = 10, // number of cpu registers killed by calls
|
||||||
pd_nof_cpu_regs_reg_alloc = 20, // number of registers that are visible to register allocator
|
pd_nof_cpu_regs_reg_alloc = 20, // number of registers that are visible to register allocator
|
||||||
pd_nof_cpu_regs_linearscan = 32,// number of registers visible linear scan
|
pd_nof_cpu_regs_linearscan = 32,// number of registers visible linear scan
|
||||||
pd_first_cpu_reg = 0,
|
pd_first_cpu_reg = 0,
|
||||||
|
|
|
@ -320,6 +320,10 @@ void FrameMap::init () {
|
||||||
_caller_save_cpu_regs[3] = FrameMap::O3_opr;
|
_caller_save_cpu_regs[3] = FrameMap::O3_opr;
|
||||||
_caller_save_cpu_regs[4] = FrameMap::O4_opr;
|
_caller_save_cpu_regs[4] = FrameMap::O4_opr;
|
||||||
_caller_save_cpu_regs[5] = FrameMap::O5_opr;
|
_caller_save_cpu_regs[5] = FrameMap::O5_opr;
|
||||||
|
_caller_save_cpu_regs[6] = FrameMap::G1_opr;
|
||||||
|
_caller_save_cpu_regs[7] = FrameMap::G3_opr;
|
||||||
|
_caller_save_cpu_regs[8] = FrameMap::G4_opr;
|
||||||
|
_caller_save_cpu_regs[9] = FrameMap::G5_opr;
|
||||||
for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
|
for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
|
||||||
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
|
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -749,6 +749,10 @@ void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
|
||||||
|
|
||||||
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
||||||
assert(x->number_of_arguments() == 5, "wrong type");
|
assert(x->number_of_arguments() == 5, "wrong type");
|
||||||
|
|
||||||
|
// Make all state_for calls early since they can emit code
|
||||||
|
CodeEmitInfo* info = state_for(x, x->state());
|
||||||
|
|
||||||
// Note: spill caller save before setting the item
|
// Note: spill caller save before setting the item
|
||||||
LIRItem src (x->argument_at(0), this);
|
LIRItem src (x->argument_at(0), this);
|
||||||
LIRItem src_pos (x->argument_at(1), this);
|
LIRItem src_pos (x->argument_at(1), this);
|
||||||
|
@ -767,7 +771,6 @@ void LIRGenerator::do_ArrayCopy(Intrinsic* x) {
|
||||||
ciArrayKlass* expected_type;
|
ciArrayKlass* expected_type;
|
||||||
arraycopy_helper(x, &flags, &expected_type);
|
arraycopy_helper(x, &flags, &expected_type);
|
||||||
|
|
||||||
CodeEmitInfo* info = state_for(x, x->state());
|
|
||||||
__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
|
__ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(),
|
||||||
length.result(), rlock_callee_saved(T_INT),
|
length.result(), rlock_callee_saved(T_INT),
|
||||||
expected_type, flags, info);
|
expected_type, flags, info);
|
||||||
|
@ -878,6 +881,9 @@ void LIRGenerator::do_NewInstance(NewInstance* x) {
|
||||||
|
|
||||||
|
|
||||||
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||||
|
// Evaluate state_for early since it may emit code
|
||||||
|
CodeEmitInfo* info = state_for(x, x->state());
|
||||||
|
|
||||||
LIRItem length(x->length(), this);
|
LIRItem length(x->length(), this);
|
||||||
length.load_item();
|
length.load_item();
|
||||||
|
|
||||||
|
@ -892,7 +898,6 @@ void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||||
|
|
||||||
__ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
|
__ oop2reg(ciTypeArrayKlass::make(elem_type)->encoding(), klass_reg);
|
||||||
|
|
||||||
CodeEmitInfo* info = state_for(x, x->state());
|
|
||||||
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
|
CodeStub* slow_path = new NewTypeArrayStub(klass_reg, len, reg, info);
|
||||||
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
|
__ allocate_array(reg, len, tmp1, tmp2, tmp3, tmp4, elem_type, klass_reg, slow_path);
|
||||||
|
|
||||||
|
@ -902,7 +907,8 @@ void LIRGenerator::do_NewTypeArray(NewTypeArray* x) {
|
||||||
|
|
||||||
|
|
||||||
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||||
LIRItem length(x->length(), this);
|
// Evaluate state_for early since it may emit code.
|
||||||
|
CodeEmitInfo* info = state_for(x, x->state());
|
||||||
// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
|
// in case of patching (i.e., object class is not yet loaded), we need to reexecute the instruction
|
||||||
// and therefore provide the state before the parameters have been consumed
|
// and therefore provide the state before the parameters have been consumed
|
||||||
CodeEmitInfo* patching_info = NULL;
|
CodeEmitInfo* patching_info = NULL;
|
||||||
|
@ -910,6 +916,7 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||||
patching_info = state_for(x, x->state_before());
|
patching_info = state_for(x, x->state_before());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIRItem length(x->length(), this);
|
||||||
length.load_item();
|
length.load_item();
|
||||||
|
|
||||||
const LIR_Opr reg = result_register_for(x->type());
|
const LIR_Opr reg = result_register_for(x->type());
|
||||||
|
@ -919,7 +926,6 @@ void LIRGenerator::do_NewObjectArray(NewObjectArray* x) {
|
||||||
LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
LIR_Opr tmp4 = FrameMap::O1_oop_opr;
|
||||||
LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
LIR_Opr klass_reg = FrameMap::G5_oop_opr;
|
||||||
LIR_Opr len = length.result();
|
LIR_Opr len = length.result();
|
||||||
CodeEmitInfo* info = state_for(x, x->state());
|
|
||||||
|
|
||||||
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
|
CodeStub* slow_path = new NewObjectArrayStub(klass_reg, len, reg, info);
|
||||||
ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
|
ciObject* obj = (ciObject*) ciObjArrayKlass::make(x->klass());
|
||||||
|
@ -943,25 +949,20 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
||||||
items->at_put(i, size);
|
items->at_put(i, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to get the info before, as the items may become invalid through item_free
|
// Evaluate state_for early since it may emit code.
|
||||||
|
CodeEmitInfo* info = state_for(x, x->state());
|
||||||
CodeEmitInfo* patching_info = NULL;
|
CodeEmitInfo* patching_info = NULL;
|
||||||
if (!x->klass()->is_loaded() || PatchALot) {
|
if (!x->klass()->is_loaded() || PatchALot) {
|
||||||
patching_info = state_for(x, x->state_before());
|
patching_info = state_for(x, x->state_before());
|
||||||
|
|
||||||
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
|
// cannot re-use same xhandlers for multiple CodeEmitInfos, so
|
||||||
// clone all handlers
|
// clone all handlers.
|
||||||
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
|
x->set_exception_handlers(new XHandlers(x->exception_handlers()));
|
||||||
}
|
}
|
||||||
|
|
||||||
i = dims->length();
|
i = dims->length();
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
LIRItem* size = items->at(i);
|
LIRItem* size = items->at(i);
|
||||||
// if a patching_info was generated above then debug information for the state before
|
|
||||||
// the call is going to be emitted. The LIRGenerator calls above may have left some values
|
|
||||||
// in registers and that's been recorded in the CodeEmitInfo. In that case the items
|
|
||||||
// for those values can't simply be freed if they are registers because the values
|
|
||||||
// might be destroyed by store_stack_parameter. So in the case of patching, delay the
|
|
||||||
// freeing of the items that already were in registers
|
|
||||||
size->load_item();
|
size->load_item();
|
||||||
store_stack_parameter (size->result(),
|
store_stack_parameter (size->result(),
|
||||||
in_ByteSize(STACK_BIAS +
|
in_ByteSize(STACK_BIAS +
|
||||||
|
@ -972,8 +973,6 @@ void LIRGenerator::do_NewMultiArray(NewMultiArray* x) {
|
||||||
// This instruction can be deoptimized in the slow path : use
|
// This instruction can be deoptimized in the slow path : use
|
||||||
// O0 as result register.
|
// O0 as result register.
|
||||||
const LIR_Opr reg = result_register_for(x->type());
|
const LIR_Opr reg = result_register_for(x->type());
|
||||||
CodeEmitInfo* info = state_for(x, x->state());
|
|
||||||
|
|
||||||
jobject2reg_with_patching(reg, x->klass(), patching_info);
|
jobject2reg_with_patching(reg, x->klass(), patching_info);
|
||||||
LIR_Opr rank = FrameMap::O1_opr;
|
LIR_Opr rank = FrameMap::O1_opr;
|
||||||
__ move(LIR_OprFact::intConst(x->rank()), rank);
|
__ move(LIR_OprFact::intConst(x->rank()), rank);
|
||||||
|
|
|
@ -409,8 +409,6 @@ codeBlob.cpp c1_Runtime1.hpp
|
||||||
|
|
||||||
compileBroker.cpp c1_Compiler.hpp
|
compileBroker.cpp c1_Compiler.hpp
|
||||||
|
|
||||||
frame.hpp c1_Defs.hpp
|
|
||||||
|
|
||||||
frame_<arch>.cpp c1_Runtime1.hpp
|
frame_<arch>.cpp c1_Runtime1.hpp
|
||||||
|
|
||||||
globals.cpp c1_globals.hpp
|
globals.cpp c1_globals.hpp
|
||||||
|
@ -433,8 +431,6 @@ os_<os_family>.cpp c1_Runtime1.hpp
|
||||||
|
|
||||||
os_<os_arch>.cpp c1_Runtime1.hpp
|
os_<os_arch>.cpp c1_Runtime1.hpp
|
||||||
|
|
||||||
registerMap.hpp c1_Defs.hpp
|
|
||||||
|
|
||||||
safepoint.cpp c1_globals.hpp
|
safepoint.cpp c1_globals.hpp
|
||||||
|
|
||||||
sharedRuntime.cpp c1_Runtime1.hpp
|
sharedRuntime.cpp c1_Runtime1.hpp
|
||||||
|
|
47
hotspot/test/compiler/6795465/Test6795465.java
Normal file
47
hotspot/test/compiler/6795465/Test6795465.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 6795465
|
||||||
|
* @summary Crash in assembler_sparc.cpp with client compiler on solaris-sparc
|
||||||
|
*
|
||||||
|
* @run main Test6795465
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Test6795465 {
|
||||||
|
static long var_1 = -1;
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
long var_2 = var_1 * 1;
|
||||||
|
var_2 = var_2 + (new byte[1])[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Test6795465 t = new Test6795465();
|
||||||
|
for (int i = 0; i < 200000; i++) {
|
||||||
|
t.test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue