--- old/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp 2019-05-21 13:17:34.356823856 -0700 +++ new/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp 2019-05-21 13:17:34.060813288 -0700 @@ -1383,6 +1383,7 @@ } else if (type == T_ADDRESS && addr->disp() == oopDesc::klass_offset_in_bytes()) { #ifdef _LP64 if (UseCompressedClassPointers) { + __ andl(dest->as_register(), oopDesc::compressed_klass_mask()); __ decode_klass_not_null(dest->as_register()); } #endif @@ -1931,8 +1932,8 @@ } void LIR_Assembler::emit_opFlattenedArrayCheck(LIR_OpFlattenedArrayCheck* op) { - // We are loading/storing an array that *may* be a flattened array (e.g., the declared type - // is Object[]). If this array is flattened, take slow path. + // We are loading/storing an array that *may* be a flattened array (the declared type + // Object[], interface[], or VT?[]). If this array is flattened, take slow path. __ load_storage_props(op->tmp()->as_register(), op->array()->as_register()); __ testb(op->tmp()->as_register(), ArrayStorageProperties::flattened_value); @@ -1953,7 +1954,7 @@ void LIR_Assembler::emit_opNullFreeArrayCheck(LIR_OpNullFreeArrayCheck* op) { // This is called when we use aastore into a an array declared as "[LVT;", // where we know VT is not flattenable (due to ValueArrayElemMaxFlatOops, etc). - // However, we need to do a NULL check if the actual array is a "QLVT;". + // However, we need to do a NULL check if the actual array is a "[QVT;". __ load_storage_props(op->tmp()->as_register(), op->array()->as_register()); __ testb(op->tmp()->as_register(), ArrayStorageProperties::null_free_value); @@ -3078,18 +3079,16 @@ } -void LIR_Assembler::arraycopy_flat_check(Register obj, Register tmp, CodeStub* slow_path) { - Address klass_addr = Address(obj, oopDesc::klass_offset_in_bytes()); - if (UseCompressedClassPointers) { - __ movl(tmp, klass_addr); - LP64_ONLY(__ decode_klass_not_null(tmp)); +void LIR_Assembler::arraycopy_valuetype_check(Register obj, Register tmp, CodeStub* slow_path, bool is_dest) { + __ load_storage_props(tmp, obj); + if (is_dest) { + // We also take slow path if it's a null_free destination array, just in case the source array + // contains NULLs. + __ testb(tmp, ArrayStorageProperties::flattened_value | ArrayStorageProperties::null_free_value); } else { - __ movptr(tmp, klass_addr); + __ testb(tmp, ArrayStorageProperties::flattened_value); } - __ movl(tmp, Address(tmp, Klass::layout_helper_offset())); - __ sarl(tmp, Klass::_lh_array_tag_shift); - __ cmpl(tmp, Klass::_lh_array_tag_vt_value); - __ jcc(Assembler::equal, *slow_path->entry()); + __ jcc(Assembler::notEqual, *slow_path->entry()); } @@ -3119,12 +3118,12 @@ return; } - if (flags & LIR_OpArrayCopy::src_flat_check) { - arraycopy_flat_check(src, tmp, stub); + if (flags & LIR_OpArrayCopy::src_valuetype_check) { + arraycopy_valuetype_check(src, tmp, stub, false); } - if (flags & LIR_OpArrayCopy::dst_flat_check) { - arraycopy_flat_check(dst, tmp, stub); + if (flags & LIR_OpArrayCopy::dst_valuetype_check) { + arraycopy_valuetype_check(dst, tmp, stub, true); } // if we don't know anything, just go through the generic arraycopy