--- old/src/cpu/x86/vm/macroAssembler_x86.cpp 2016-02-29 14:28:33.914723376 +0300 +++ new/src/cpu/x86/vm/macroAssembler_x86.cpp 2016-02-29 14:28:33.862723623 +0300 @@ -7198,21 +7198,45 @@ } -void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp) { +void MacroAssembler::clear_mem(Register base, Register cnt, Register tmp, bool is_large) { // cnt - number of qwords (8-byte words). // base - start address, qword aligned. + // is_large - if optimizers know cnt is larger than InitArrayShortSize assert(base==rdi, "base register must be edi for rep stos"); assert(tmp==rax, "tmp register must be eax for rep stos"); assert(cnt==rcx, "cnt register must be ecx for rep stos"); + assert(InitArrayShortSize % BytesPerLong == 0, + "InitArrayShortSize should be the multiple of BytesPerLong"); + Label SHORT, LONG, DONE; + + if (!is_large) { + cmpptr(cnt, InitArrayShortSize/BytesPerLong); + jcc(Assembler::greater, LONG); + + NOT_LP64(shlptr(cnt, 1);) // convert to number of 32-bit words for 32-bit VM + + // Use individual pointer-sized stores for small counts: + bind(SHORT); + testptr(cnt, cnt); + jcc(Assembler::equal, DONE); + decrement(cnt); + movptr(Address(base, cnt, Address::times_ptr), 0); + jmp(SHORT); + } + + // Use longer rep-prefixed ops for non-small counts: + bind(LONG); xorptr(tmp, tmp); if (UseFastStosb) { - shlptr(cnt,3); // convert to number of bytes + shlptr(cnt, 3); // convert to number of bytes rep_stosb(); } else { - NOT_LP64(shlptr(cnt,1);) // convert to number of dwords for 32-bit VM + NOT_LP64(shlptr(cnt, 1);) // convert to number of 32-bit words for 32-bit VM rep_stos(); } + + bind(DONE); } #ifdef COMPILER2