1 /* 2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "asm/macroAssembler.hpp" 27 #include "interpreter/interp_masm.hpp" 28 #include "interpreter/interpreter.hpp" 29 #include "interpreter/templateInterpreterGenerator.hpp" 30 #include "runtime/arguments.hpp" 31 32 #define __ _masm-> 33 34 /** 35 * Method entry for static native methods: 36 * int java.util.zip.CRC32.update(int crc, int b) 37 */ 38 address TemplateInterpreterGenerator::generate_CRC32_update_entry() { 39 if (UseCRC32Intrinsics) { 40 address entry = __ pc(); 41 42 // rbx,: Method* 43 // r13: senderSP must preserved for slow path, set SP to it on fast path 44 // c_rarg0: scratch (rdi on non-Win64, rcx on Win64) 45 // c_rarg1: scratch (rsi on non-Win64, rdx on Win64) 46 47 Label slow_path; 48 // If we need a safepoint check, generate full interpreter entry. 49 ExternalAddress state(SafepointSynchronize::address_of_state()); 50 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 51 SafepointSynchronize::_not_synchronized); 52 __ jcc(Assembler::notEqual, slow_path); 53 54 // We don't generate local frame and don't align stack because 55 // we call stub code and there is no safepoint on this path. 56 57 // Load parameters 58 const Register crc = rax; // crc 59 const Register val = c_rarg0; // source java byte value 60 const Register tbl = c_rarg1; // scratch 61 62 // Arguments are reversed on java expression stack 63 __ movl(val, Address(rsp, wordSize)); // byte value 64 __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC 65 66 __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); 67 __ notl(crc); // ~crc 68 __ update_byte_crc32(crc, val, tbl); 69 __ notl(crc); // ~crc 70 // result in rax 71 72 // _areturn 73 __ pop(rdi); // get return address 74 __ mov(rsp, r13); // set sp to sender sp 75 __ jmp(rdi); 76 77 // generate a vanilla native entry as the slow path 78 __ bind(slow_path); 79 __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native)); 80 return entry; 81 } 82 return NULL; 83 } 84 85 /** 86 * Method entry for static native methods: 87 * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) 88 * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) 89 */ 90 address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { 91 if (UseCRC32Intrinsics) { 92 address entry = __ pc(); 93 94 // rbx,: Method* 95 // r13: senderSP must preserved for slow path, set SP to it on fast path 96 97 Label slow_path; 98 // If we need a safepoint check, generate full interpreter entry. 99 ExternalAddress state(SafepointSynchronize::address_of_state()); 100 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 101 SafepointSynchronize::_not_synchronized); 102 __ jcc(Assembler::notEqual, slow_path); 103 104 // We don't generate local frame and don't align stack because 105 // we call stub code and there is no safepoint on this path. 106 107 // Load parameters 108 const Register crc = c_rarg0; // crc 109 const Register buf = c_rarg1; // source java byte array address 110 const Register len = c_rarg2; // length 111 const Register off = len; // offset (never overlaps with 'len') 112 113 // Arguments are reversed on java expression stack 114 // Calculate address of start element 115 if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { 116 __ movptr(buf, Address(rsp, 3*wordSize)); // long buf 117 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset 118 __ addq(buf, off); // + offset 119 __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC 120 } else { 121 __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array 122 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 123 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset 124 __ addq(buf, off); // + offset 125 __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC 126 } 127 // Can now load 'len' since we're finished with 'off' 128 __ movl(len, Address(rsp, wordSize)); // Length 129 130 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); 131 // result in rax 132 133 // _areturn 134 __ pop(rdi); // get return address 135 __ mov(rsp, r13); // set sp to sender sp 136 __ jmp(rdi); 137 138 // generate a vanilla native entry as the slow path 139 __ bind(slow_path); 140 __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native)); 141 return entry; 142 } 143 return NULL; 144 } 145 146 /** 147 * Method entry for static native methods: 148 * int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end) 149 * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end) 150 */ 151 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { 152 if (UseCRC32CIntrinsics) { 153 address entry = __ pc(); 154 // Load parameters 155 const Register crc = c_rarg0; // crc 156 const Register buf = c_rarg1; // source java byte array address 157 const Register len = c_rarg2; 158 const Register off = c_rarg3; // offset 159 const Register end = len; 160 161 // Arguments are reversed on java expression stack 162 // Calculate address of start element 163 if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { 164 __ movptr(buf, Address(rsp, 3 * wordSize)); // long buf 165 __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset 166 __ addq(buf, off); // + offset 167 __ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC 168 // Note on 5 * wordSize vs. 4 * wordSize: 169 // * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end) 170 // 4 2,3 1 0 171 // end starts at SP + 8 172 // The Java(R) Virtual Machine Specification Java SE 7 Edition 173 // 4.10.2.3. Values of Types long and double 174 // "When calculating operand stack length, values of type long and double have length two." 175 } else { 176 __ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array 177 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 178 __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset 179 __ addq(buf, off); // + offset 180 __ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC 181 } 182 __ movl(end, Address(rsp, wordSize)); // end 183 __ subl(end, off); // end - off 184 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len); 185 // result in rax 186 // _areturn 187 __ pop(rdi); // get return address 188 __ mov(rsp, r13); // set sp to sender sp 189 __ jmp(rdi); 190 191 return entry; 192 } 193 194 return NULL; 195 }