< prev index next >

src/cpu/x86/vm/macroAssembler_x86.cpp

Print this page

        

@@ -7196,25 +7196,49 @@
   }
 #endif
 
 }
 
-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
 
 // IndexOf for constant substrings with size >= 8 chars
< prev index next >