aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/x86
diff options
context:
space:
mode:
authorasaha <none@none>2016-01-25 14:39:01 -0800
committerasaha <none@none>2016-01-25 14:39:01 -0800
commita0ffbdd4c777818eb4635e46b89bbeba44662fe7 (patch)
tree8df81060473340382dacbe485318daf0cd9b5435 /src/cpu/x86
parentaf290d0fb302ee6a355fc55bc11602fddbac08bb (diff)
parent0db60e5fe609af81b45d46118f9187b4970d7749 (diff)
downloadjdk8u_hotspot-a0ffbdd4c777818eb4635e46b89bbeba44662fe7.tar.gz
Merge
Diffstat (limited to 'src/cpu/x86')
-rw-r--r--src/cpu/x86/vm/c1_LIRGenerator_x86.cpp7
-rw-r--r--src/cpu/x86/vm/cppInterpreter_x86.cpp9
-rw-r--r--src/cpu/x86/vm/interp_masm_x86.cpp50
-rw-r--r--src/cpu/x86/vm/interp_masm_x86.hpp5
-rw-r--r--src/cpu/x86/vm/interp_masm_x86_32.cpp5
-rw-r--r--src/cpu/x86/vm/interp_masm_x86_64.cpp5
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_32.cpp10
-rw-r--r--src/cpu/x86/vm/templateInterpreter_x86_64.cpp11
-rw-r--r--src/cpu/x86/vm/templateTable_x86_32.cpp70
-rw-r--r--src/cpu/x86/vm/templateTable_x86_64.cpp59
10 files changed, 208 insertions, 23 deletions
diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
index 1ee690ea4..290c0b1f2 100644
--- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -283,7 +283,7 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
length.load_item();
}
- if (needs_store_check) {
+ if (needs_store_check || x->check_boolean()) {
value.load_item();
} else {
value.load_for_store(x->elt_type());
@@ -331,7 +331,8 @@ void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
// Seems to be a precise
post_barrier(LIR_OprFact::address(array_addr), value.result());
} else {
- __ move(value.result(), array_addr, null_check_info);
+ LIR_Opr result = maybe_mask_boolean(x, array.result(), value.result(), null_check_info);
+ __ move(result, array_addr, null_check_info);
}
}
diff --git a/src/cpu/x86/vm/cppInterpreter_x86.cpp b/src/cpu/x86/vm/cppInterpreter_x86.cpp
index 81db13d7f..fbba6c6e2 100644
--- a/src/cpu/x86/vm/cppInterpreter_x86.cpp
+++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -870,7 +870,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
- Label notByte, notShort, notChar;
+ Label notByte, notBool, notShort, notChar;
const Address field_address (rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
@@ -889,6 +889,11 @@ address InterpreterGenerator::generate_accessor_entry(void) {
__ bind(notObj);
#endif // _LP64
+ __ cmpl(rdx, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+ __ load_signed_byte(rax, field_address);
+ __ jmp(xreturn_path);
+
__ cmpl(rdx, btos);
__ jcc(Assembler::notEqual, notByte);
__ load_signed_byte(rax, field_address);
diff --git a/src/cpu/x86/vm/interp_masm_x86.cpp b/src/cpu/x86/vm/interp_masm_x86.cpp
index 42a826d77..3edcc887b 100644
--- a/src/cpu/x86/vm/interp_masm_x86.cpp
+++ b/src/cpu/x86/vm/interp_masm_x86.cpp
@@ -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
@@ -27,6 +27,54 @@
#include "interpreter/interpreter.hpp"
#include "oops/methodData.hpp"
+
+// 8u does not have InterpreterMacroAssembler::load_earlyret_value here
+
+void InterpreterMacroAssembler::narrow(Register result) {
+
+ // Get method->_constMethod->_result_type
+ movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
+ movptr(rcx, Address(rcx, Method::const_offset()));
+ load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
+
+ Label done, notBool, notByte, notChar;
+
+ // common case first
+ cmpl(rcx, T_INT);
+ jcc(Assembler::equal, done);
+
+ // mask integer result to narrower return type.
+ cmpl(rcx, T_BOOLEAN);
+ jcc(Assembler::notEqual, notBool);
+ andl(result, 0x1);
+ jmp(done);
+
+ bind(notBool);
+ cmpl(rcx, T_BYTE);
+ jcc(Assembler::notEqual, notByte);
+ LP64_ONLY(movsbl(result, result);)
+ NOT_LP64(shll(result, 24);) // truncate upper 24 bits
+ NOT_LP64(sarl(result, 24);) // and sign-extend byte
+ jmp(done);
+
+ bind(notByte);
+ cmpl(rcx, T_CHAR);
+ jcc(Assembler::notEqual, notChar);
+ LP64_ONLY(movzwl(result, result);)
+ NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits
+ jmp(done);
+
+ bind(notChar);
+ // cmpl(rcx, T_SHORT); // all that's left
+ // jcc(Assembler::notEqual, done);
+ LP64_ONLY(movswl(result, result);)
+ NOT_LP64(shll(result, 16);) // truncate upper 16 bits
+ NOT_LP64(sarl(result, 16);) // and sign-extend short
+
+ // Nothing to do for T_INT
+ bind(done);
+}
+
#ifndef CC_INTERP
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
Label update, next, none;
diff --git a/src/cpu/x86/vm/interp_masm_x86.hpp b/src/cpu/x86/vm/interp_masm_x86.hpp
index 2ac4d0266..c07ff4b06 100644
--- a/src/cpu/x86/vm/interp_masm_x86.hpp
+++ b/src/cpu/x86/vm/interp_masm_x86.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -48,6 +48,9 @@ class InterpreterMacroAssembler: public MacroAssembler {
Register _bcp_register; // register that contains the bcp
public:
+ // narrow int return value
+ void narrow(Register result);
+
#ifndef CC_INTERP
void profile_obj_type(Register obj, const Address& mdo_addr);
void profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual);
diff --git a/src/cpu/x86/vm/interp_masm_x86_32.cpp b/src/cpu/x86/vm/interp_masm_x86_32.cpp
index b6f2438db..8a132c12f 100644
--- a/src/cpu/x86/vm/interp_masm_x86_32.cpp
+++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp
@@ -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
@@ -151,6 +151,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
case ltos:
movl(rdx, val_addr1); // fall through
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: movl(rax, val_addr); break;
@@ -362,6 +363,7 @@ void InterpreterMacroAssembler::pop(TosState state) {
switch (state) {
case atos: pop_ptr(rax); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: pop_i(rax); break;
@@ -405,6 +407,7 @@ void InterpreterMacroAssembler::push(TosState state) {
switch (state) {
case atos: push_ptr(rax); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: push_i(rax); break;
diff --git a/src/cpu/x86/vm/interp_masm_x86_64.cpp b/src/cpu/x86/vm/interp_masm_x86_64.cpp
index 520c872a6..693ac7958 100644
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -149,6 +149,7 @@ void InterpreterMacroAssembler::load_earlyret_value(TosState state) {
verify_oop(rax, state); break;
case ltos: movptr(rax, val_addr); break;
case btos: // fall through
+ case ztos: // fall through
case ctos: // fall through
case stos: // fall through
case itos: movl(rax, val_addr); break;
@@ -387,6 +388,7 @@ void InterpreterMacroAssembler::pop(TosState state) {
switch (state) {
case atos: pop_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: pop_i(); break;
@@ -404,6 +406,7 @@ void InterpreterMacroAssembler::push(TosState state) {
switch (state) {
case atos: push_ptr(); break;
case btos:
+ case ztos:
case ctos:
case stos:
case itos: push_i(); break;
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index d7f85cf3a..dfe431a7b 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -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
@@ -713,7 +713,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
rdx,
Address::times_ptr, ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
- Label notByte, notShort, notChar;
+ Label notByte, notBool, notShort, notChar;
const Address field_address (rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
@@ -728,6 +728,12 @@ address InterpreterGenerator::generate_accessor_entry(void) {
__ jmp(xreturn_path);
__ bind(notByte);
+ __ cmpl(rdx, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+ __ load_signed_byte(rax, field_address);
+ __ jmp(xreturn_path);
+
+ __ bind(notBool);
__ cmpl(rdx, stos);
__ jcc(Assembler::notEqual, notShort);
__ load_signed_short(rax, field_address);
diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 652c7060e..156cbe95d 100644
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -680,7 +680,7 @@ address InterpreterGenerator::generate_accessor_entry(void) {
ConstantPoolCache::base_offset() +
ConstantPoolCacheEntry::flags_offset()));
- Label notObj, notInt, notByte, notShort;
+ Label notObj, notInt, notByte, notBool, notShort;
const Address field_address(rax, rcx, Address::times_1);
// Need to differentiate between igetfield, agetfield, bgetfield etc.
@@ -711,6 +711,13 @@ address InterpreterGenerator::generate_accessor_entry(void) {
__ jmp(xreturn_path);
__ bind(notByte);
+ __ cmpl(rdx, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+ // ztos
+ __ load_signed_byte(rax, field_address);
+ __ jmp(xreturn_path);
+
+ __ bind(notBool);
__ cmpl(rdx, stos);
__ jcc(Assembler::notEqual, notShort);
// stos
diff --git a/src/cpu/x86/vm/templateTable_x86_32.cpp b/src/cpu/x86/vm/templateTable_x86_32.cpp
index 3c2ec9f42..9d18e8c83 100644
--- a/src/cpu/x86/vm/templateTable_x86_32.cpp
+++ b/src/cpu/x86/vm/templateTable_x86_32.cpp
@@ -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 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
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::aastore() {
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 @@ void TemplateTable::_return(TosState state) {
__ 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 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
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 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ 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 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
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 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
}
__ 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 @@ void TemplateTable::jvmti_post_fast_field_mod() {
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 @@ void TemplateTable::jvmti_post_fast_field_mod() {
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 @@ void TemplateTable::fast_storefield(TosState state) {
// 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 @@ void TemplateTable::fast_storefield(TosState state) {
// 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;
diff --git a/src/cpu/x86/vm/templateTable_x86_64.cpp b/src/cpu/x86/vm/templateTable_x86_64.cpp
index 544019c71..9a8c34c2e 100644
--- a/src/cpu/x86/vm/templateTable_x86_64.cpp
+++ b/src/cpu/x86/vm/templateTable_x86_64.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -219,6 +219,7 @@ void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
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:
@@ -1018,6 +1019,16 @@ void TemplateTable::bastore() {
// ebx: index
// rdx: array
index_check(rdx, rbx); // prefer index in ebx
+ // 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)),
@@ -2071,7 +2082,14 @@ void TemplateTable::_return(TosState state) {
__ 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, r13);
+
__ jmp(r13);
}
@@ -2289,7 +2307,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
const Address field(obj, off, Address::times_1);
- Label Done, notByte, notInt, notShort, notChar,
+ Label Done, notByte, notBool, notInt, notShort, notChar,
notLong, notFloat, notObj, notDouble;
__ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
@@ -2308,6 +2326,20 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
__ jmp(Done);
__ bind(notByte);
+ __ cmpl(flags, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+
+ // ztos (same code as btos)
+ __ load_signed_byte(rax, field);
+ __ 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, bc, rbx);
+ }
+ __ jmp(Done);
+
+ __ bind(notBool);
__ cmpl(flags, atos);
__ jcc(Assembler::notEqual, notObj);
// atos
@@ -2497,7 +2529,7 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
// field address
const Address field(obj, off, Address::times_1);
- Label notByte, notInt, notShort, notChar,
+ Label notByte, notBool, notInt, notShort, notChar,
notLong, notFloat, notObj, notDouble;
__ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
@@ -2518,6 +2550,22 @@ void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
}
__ bind(notByte);
+ __ cmpl(flags, ztos);
+ __ jcc(Assembler::notEqual, notBool);
+
+ // ztos
+ {
+ __ pop(ztos);
+ if (!is_static) pop_and_check_object(obj);
+ __ andl(rax, 0x1);
+ __ movb(field, rax);
+ if (!is_static) {
+ patch_bytecode(Bytecodes::_fast_zputfield, bc, rbx, true, byte_no);
+ }
+ __ jmp(Done);
+ }
+
+ __ bind(notBool);
__ cmpl(flags, atos);
__ jcc(Assembler::notEqual, notObj);
@@ -2666,6 +2714,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
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;
@@ -2691,6 +2740,7 @@ void TemplateTable::jvmti_post_fast_field_mod() {
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;
@@ -2746,6 +2796,9 @@ void TemplateTable::fast_storefield(TosState state) {
case Bytecodes::_fast_iputfield:
__ movl(field, rax);
break;
+ case Bytecodes::_fast_zputfield:
+ __ andl(rax, 0x1); // boolean is true if LSB is 1
+ // fall through to bputfield
case Bytecodes::_fast_bputfield:
__ movb(field, rax);
break;