diff src/cpu/x86/vm/templateTable_x86_32.cpp @ 23614:32b682649973 jdk8u75-b04

8132051: Better byte behavior Reviewed-by: coleenp, roland
author kevinw
date Fri, 15 Jan 2016 22:33:15 +0000
parents 42790b7e4d48
children ca5c97226d1c
line wrap: on
line diff
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp	Mon Jan 11 13:41:45 2016 -0800
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp	Fri Jan 15 22:33:15 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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
@@ -212,6 +212,7 @@
   switch (bc) {
   case Bytecodes::_fast_aputfield:
   case Bytecodes::_fast_bputfield:
+  case Bytecodes::_fast_zputfield:
   case Bytecodes::_fast_cputfield:
   case Bytecodes::_fast_dputfield:
   case Bytecodes::_fast_fputfield:
@@ -988,11 +989,21 @@
 void TemplateTable::bastore() {
   transition(itos, vtos);
   __ pop_i(rbx);
-  // rax,: value
+  // rax: value
+  // rbx: index
   // rdx: array
-  index_check(rdx, rbx);  // prefer index in rbx,
-  // rbx,: index
-  __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax);
+  index_check(rdx, rbx);  // prefer index in rbx
+  // Need to check whether array is boolean or byte
+  // since both types share the bastore bytecode.
+  __ load_klass(rcx, rdx);
+  __ movl(rcx, Address(rcx, Klass::layout_helper_offset()));
+  int diffbit = Klass::layout_helper_boolean_diffbit();
+  __ testl(rcx, diffbit);
+  Label L_skip;
+  __ jccb(Assembler::zero, L_skip);
+  __ andl(rax, 1);  // if it is a T_BOOLEAN array, mask the stored value to 0/1
+  __ bind(L_skip);
+ __ movb(Address(rdx, rbx, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)), rax);
 }
 
 
@@ -2037,7 +2048,14 @@
     __ bind(skip_register_finalizer);
   }
 
+  // Narrow result if state is itos but result type is smaller.
+  // Need to narrow in the return bytecode rather than in generate_return_entry
+  // since compiled code callers expect the result to already be narrowed.
+  if (state == itos) {
+    __ narrow(rax);
+  }
   __ remove_activation(state, rsi);
+
   __ jmp(rsi);
 }
 
@@ -2234,7 +2252,7 @@
   const Address lo(obj, off, Address::times_1, 0*wordSize);
   const Address hi(obj, off, Address::times_1, 1*wordSize);
 
-  Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
+  Label Done, notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
 
   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   assert(btos == 0, "change code, btos != 0");
@@ -2251,6 +2269,22 @@
   __ jmp(Done);
 
   __ bind(notByte);
+
+  __ cmpl(flags, ztos);
+  __ jcc(Assembler::notEqual, notBool);
+
+  // ztos (same code as btos)
+  __ load_signed_byte(rax, lo);
+  __ push(ztos);
+  // Rewrite bytecode to be faster
+  if (!is_static) {
+    // use btos rewriting, no truncating to t/f bit is needed for getfield.
+    patch_bytecode(Bytecodes::_fast_bgetfield, rcx, rbx);
+  }
+  __ jmp(Done);
+
+  __ bind(notBool);
+
   // itos
   __ cmpl(flags, itos );
   __ jcc(Assembler::notEqual, notInt);
@@ -2450,7 +2484,7 @@
   const Address lo(obj, off, Address::times_1, 0*wordSize);
   const Address hi(obj, off, Address::times_1, 1*wordSize);
 
-  Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
+  Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
 
   __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   assert(btos == 0, "change code, btos != 0");
@@ -2469,6 +2503,22 @@
   }
 
   __ bind(notByte);
+  __ cmpl(flags, ztos);
+  __ jcc(Assembler::notEqual, notBool);
+
+  // ztos
+  {
+    __ pop(ztos);
+    if (!is_static) pop_and_check_object(obj);
+    __ andl(rax, 0x1);
+    __ movb(lo, rax);
+    if (!is_static) {
+      patch_bytecode(Bytecodes::_fast_zputfield, rcx, rbx, true, byte_no);
+    }
+    __ jmp(Done);
+  }
+
+  __ bind(notBool);
   __ cmpl(flags, itos);
   __ jcc(Assembler::notEqual, notInt);
 
@@ -2640,6 +2690,7 @@
      switch (bytecode()) {          // load values into the jvalue object
      case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
      case Bytecodes::_fast_bputfield: // fall through
+     case Bytecodes::_fast_zputfield: // fall through
      case Bytecodes::_fast_sputfield: // fall through
      case Bytecodes::_fast_cputfield: // fall through
      case Bytecodes::_fast_iputfield: __ push_i(rax); break;
@@ -2662,6 +2713,7 @@
      switch (bytecode()) {             // restore tos values
      case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
      case Bytecodes::_fast_bputfield: // fall through
+     case Bytecodes::_fast_zputfield: // fall through
      case Bytecodes::_fast_sputfield: // fall through
      case Bytecodes::_fast_cputfield: // fall through
      case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
@@ -2712,6 +2764,8 @@
 
   // access field
   switch (bytecode()) {
+    case Bytecodes::_fast_zputfield: __ andl(rax, 0x1);  // boolean is true if LSB is 1
+    // fall through to bputfield
     case Bytecodes::_fast_bputfield: __ movb(lo, rax); break;
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;
@@ -2746,6 +2800,8 @@
 
   // access field
   switch (bytecode()) {
+    case Bytecodes::_fast_zputfield: __ andl(rax, 0x1);  // boolean is true if LSB is 1
+    // fall through to bputfield
     case Bytecodes::_fast_bputfield: __ movb(lo, rax); break;
     case Bytecodes::_fast_sputfield: // fall through
     case Bytecodes::_fast_cputfield: __ movw(lo, rax); break;