8144534: Refactor templateInterpreter and templateInterpreterGenerator functions
Merged templateInterpreter_x86_32/64 into templateInterpreterGenerator_x86.cpp (some 32/64 functions remain for the hand coded crc functions). Reviewed-by: goetz, jrose, twisti
This commit is contained in:
parent
679e48d459
commit
5f07c2b8ad
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -39,7 +39,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -259,20 +258,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
1925
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
Normal file
1925
hotspot/src/cpu/aarch64/vm/templateInterpreterGenerator_aarch64.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -61,26 +60,6 @@
|
||||
|
||||
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
|
||||
|
||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
int i = 0;
|
||||
switch (type) {
|
||||
case T_BOOLEAN: i = 0; break;
|
||||
case T_CHAR : i = 1; break;
|
||||
case T_BYTE : i = 2; break;
|
||||
case T_SHORT : i = 3; break;
|
||||
case T_INT : i = 4; break;
|
||||
case T_LONG : i = 5; break;
|
||||
case T_VOID : i = 6; break;
|
||||
case T_FLOAT : i = 7; break;
|
||||
case T_DOUBLE : i = 8; break;
|
||||
case T_OBJECT : i = 9; break;
|
||||
case T_ARRAY : i = 9; break;
|
||||
default : ShouldNotReachHere();
|
||||
}
|
||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
||||
return i;
|
||||
}
|
||||
|
||||
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
||||
// Slow_signature handler that respects the PPC C calling conventions.
|
||||
//
|
||||
@ -579,18 +558,3 @@ address InterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
1802
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
Normal file
1802
hotspot/src/cpu/ppc/vm/templateInterpreterGenerator_ppc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2013, 2015 SAP AG. All rights reserved.
|
||||
* Copyright (c) 2013, 2015 SAP AG. 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
|
||||
@ -33,9 +33,12 @@
|
||||
// if too small.
|
||||
// Run with +PrintInterpreter to get the VM to print out the size.
|
||||
// Max size with JVMTI
|
||||
|
||||
const static int InterpreterCodeSize = 230*K;
|
||||
|
||||
public:
|
||||
// Support abs and sqrt like in compiler.
|
||||
// For others we can use a normal (native) entry.
|
||||
static bool math_entry_available(AbstractInterpreter::MethodKind kind);
|
||||
#endif // CPU_PPC_VM_TEMPLATEINTERPRETER_PPC_HPP
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -62,30 +61,6 @@
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
int i = 0;
|
||||
switch (type) {
|
||||
case T_BOOLEAN: i = 0; break;
|
||||
case T_CHAR : i = 1; break;
|
||||
case T_BYTE : i = 2; break;
|
||||
case T_SHORT : i = 3; break;
|
||||
case T_INT : i = 4; break;
|
||||
case T_LONG : i = 5; break;
|
||||
case T_VOID : i = 6; break;
|
||||
case T_FLOAT : i = 7; break;
|
||||
case T_DOUBLE : i = 8; break;
|
||||
case T_OBJECT : i = 9; break;
|
||||
case T_ARRAY : i = 9; break;
|
||||
default : ShouldNotReachHere();
|
||||
}
|
||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _LP64
|
||||
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
|
||||
address entry = __ pc();
|
||||
@ -254,28 +229,3 @@ address InterpreterGenerator::generate_abstract_entry(void) {
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
// No special entry points that preclude compilation
|
||||
return true;
|
||||
}
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
// Exceptions
|
||||
|
1832
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
Normal file
1832
hotspot/src/cpu/sparc/vm/templateInterpreterGenerator_sparc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -175,6 +175,7 @@ class InterpreterMacroAssembler: public MacroAssembler {
|
||||
movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
|
||||
// NULL last_sp until next java call
|
||||
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD);
|
||||
NOT_LP64(empty_FPU_stack());
|
||||
}
|
||||
|
||||
// Helpers for swap and dup
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -184,20 +183,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
||||
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -298,19 +297,3 @@ address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKin
|
||||
|
||||
return entry_point;
|
||||
}
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
305
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp
Normal file
305
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_32.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterGenerator.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
|
||||
|
||||
#ifndef CC_INTERP
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||
SafepointSynchronize::_not_synchronized);
|
||||
__ jcc(Assembler::notEqual, slow_path);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = rdx; // source java byte value
|
||||
const Register tbl = rdi; // scratch
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// rsi: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// rdx: scratch
|
||||
// rdi: scratch
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||
SafepointSynchronize::_not_synchronized);
|
||||
__ jcc(Assembler::notEqual, slow_path);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rdx; // source java byte array address
|
||||
const Register len = rdi; // length
|
||||
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
// 4 2,3 1 0
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(len, Address(rsp, 4 + 0)); // Length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
|
||||
* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register buf = rcx; // source java byte array address
|
||||
const Register len = rdx; // length
|
||||
const Register end = len;
|
||||
|
||||
// value x86_32
|
||||
// interp. arg ptr ESP + 4
|
||||
// int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
|
||||
// 3 2 1 0
|
||||
// int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(end, Address(rsp, 4 + 0)); // end
|
||||
__ subl(len, Address(rsp, 4 + 1 * wordSize)); // end - offset == length
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
|
||||
__ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
|
||||
}
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native method:
|
||||
* java.lang.Float.intBitsToFloat(int bits)
|
||||
*/
|
||||
address InterpreterGenerator::generate_Float_intBitsToFloat_entry() {
|
||||
if (UseSSE >= 1) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
|
||||
// Skip safepoint check (compiler intrinsic versions of this method
|
||||
// do not perform safepoint checks either).
|
||||
|
||||
// Load 'bits' into xmm0 (interpreter returns results in xmm0)
|
||||
__ movflt(xmm0, Address(rsp, wordSize));
|
||||
|
||||
// Return
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||
__ jmp(rdi);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native method:
|
||||
* java.lang.Float.floatToRawIntBits(float value)
|
||||
*/
|
||||
address InterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
|
||||
if (UseSSE >= 1) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
|
||||
// Skip safepoint check (compiler intrinsic versions of this method
|
||||
// do not perform safepoint checks either).
|
||||
|
||||
// Load the parameter (a floating-point value) into rax.
|
||||
__ movl(rax, Address(rsp, wordSize));
|
||||
|
||||
// Return
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||
__ jmp(rdi);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method entry for static native method:
|
||||
* java.lang.Double.longBitsToDouble(long bits)
|
||||
*/
|
||||
address InterpreterGenerator::generate_Double_longBitsToDouble_entry() {
|
||||
if (UseSSE >= 2) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
|
||||
// Skip safepoint check (compiler intrinsic versions of this method
|
||||
// do not perform safepoint checks either).
|
||||
|
||||
// Load 'bits' into xmm0 (interpreter returns results in xmm0)
|
||||
__ movdbl(xmm0, Address(rsp, wordSize));
|
||||
|
||||
// Return
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||
__ jmp(rdi);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native method:
|
||||
* java.lang.Double.doubleToRawLongBits(double value)
|
||||
*/
|
||||
address InterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
|
||||
if (UseSSE >= 2) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rsi: the sender's SP
|
||||
|
||||
// Skip safepoint check (compiler intrinsic versions of this method
|
||||
// do not perform safepoint checks either).
|
||||
|
||||
// Load the parameter (a floating-point value) into rax.
|
||||
__ movl(rdx, Address(rsp, 2*wordSize));
|
||||
__ movl(rax, Address(rsp, wordSize));
|
||||
|
||||
// Return
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, rsi); // set rsp to the sender's SP
|
||||
__ jmp(rdi);
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif // CC_INTERP
|
197
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp
Normal file
197
hotspot/src/cpu/x86/vm/templateInterpreterGenerator_x86_64.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "asm/macroAssembler.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/interpreterGenerator.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
|
||||
#define __ _masm->
|
||||
|
||||
#ifndef CC_INTERP
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32.update(int crc, int b)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32_update_entry() {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
// c_rarg0: scratch (rdi on non-Win64, rcx on Win64)
|
||||
// c_rarg1: scratch (rsi on non-Win64, rdx on Win64)
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||
SafepointSynchronize::_not_synchronized);
|
||||
__ jcc(Assembler::notEqual, slow_path);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = rax; // crc
|
||||
const Register val = c_rarg0; // source java byte value
|
||||
const Register tbl = c_rarg1; // scratch
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
__ movl(val, Address(rsp, wordSize)); // byte value
|
||||
__ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
|
||||
|
||||
__ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
|
||||
__ notl(crc); // ~crc
|
||||
__ update_byte_crc32(crc, val, tbl);
|
||||
__ notl(crc); // ~crc
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
|
||||
* int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32Intrinsics) {
|
||||
address entry = __ pc();
|
||||
|
||||
// rbx,: Method*
|
||||
// r13: senderSP must preserved for slow path, set SP to it on fast path
|
||||
|
||||
Label slow_path;
|
||||
// If we need a safepoint check, generate full interpreter entry.
|
||||
ExternalAddress state(SafepointSynchronize::address_of_state());
|
||||
__ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
||||
SafepointSynchronize::_not_synchronized);
|
||||
__ jcc(Assembler::notEqual, slow_path);
|
||||
|
||||
// We don't generate local frame and don't align stack because
|
||||
// we call stub code and there is no safepoint on this path.
|
||||
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2; // length
|
||||
const Register off = len; // offset (never overlaps with 'len')
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // long buf
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2*wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC
|
||||
}
|
||||
// Can now load 'len' since we're finished with 'off'
|
||||
__ movl(len, Address(rsp, wordSize)); // Length
|
||||
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
|
||||
// result in rax
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
// generate a vanilla native entry as the slow path
|
||||
__ bind(slow_path);
|
||||
__ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method entry for static native methods:
|
||||
* int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
|
||||
* int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
*/
|
||||
address InterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
|
||||
if (UseCRC32CIntrinsics) {
|
||||
address entry = __ pc();
|
||||
// Load parameters
|
||||
const Register crc = c_rarg0; // crc
|
||||
const Register buf = c_rarg1; // source java byte array address
|
||||
const Register len = c_rarg2;
|
||||
const Register off = c_rarg3; // offset
|
||||
const Register end = len;
|
||||
|
||||
// Arguments are reversed on java expression stack
|
||||
// Calculate address of start element
|
||||
if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // long buf
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC
|
||||
// Note on 5 * wordSize vs. 4 * wordSize:
|
||||
// * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
|
||||
// 4 2,3 1 0
|
||||
// end starts at SP + 8
|
||||
// The Java(R) Virtual Machine Specification Java SE 7 Edition
|
||||
// 4.10.2.3. Values of Types long and double
|
||||
// "When calculating operand stack length, values of type long and double have length two."
|
||||
} else {
|
||||
__ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array
|
||||
__ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
|
||||
__ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset
|
||||
__ addq(buf, off); // + offset
|
||||
__ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC
|
||||
}
|
||||
__ movl(end, Address(rsp, wordSize)); // end
|
||||
__ subl(end, off); // end - off
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
|
||||
// result in rax
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
__ mov(rsp, r13); // set sp to sender sp
|
||||
__ jmp(rdi);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif // ! CC_INTERP
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2015, 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
|
||||
@ -116,4 +116,87 @@ void AbstractInterpreter::layout_activation(Method* method,
|
||||
method->constants()->cache();
|
||||
}
|
||||
|
||||
#ifndef _LP64
|
||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
int i = 0;
|
||||
switch (type) {
|
||||
case T_BOOLEAN: i = 0; break;
|
||||
case T_CHAR : i = 1; break;
|
||||
case T_BYTE : i = 2; break;
|
||||
case T_SHORT : i = 3; break;
|
||||
case T_INT : // fall through
|
||||
case T_LONG : // fall through
|
||||
case T_VOID : i = 4; break;
|
||||
case T_FLOAT : i = 5; break; // have to treat float and double separately for SSE
|
||||
case T_DOUBLE : i = 6; break;
|
||||
case T_OBJECT : // fall through
|
||||
case T_ARRAY : i = 7; break;
|
||||
default : ShouldNotReachHere();
|
||||
}
|
||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
|
||||
return i;
|
||||
}
|
||||
#else
|
||||
int AbstractInterpreter::BasicType_as_index(BasicType type) {
|
||||
int i = 0;
|
||||
switch (type) {
|
||||
case T_BOOLEAN: i = 0; break;
|
||||
case T_CHAR : i = 1; break;
|
||||
case T_BYTE : i = 2; break;
|
||||
case T_SHORT : i = 3; break;
|
||||
case T_INT : i = 4; break;
|
||||
case T_LONG : i = 5; break;
|
||||
case T_VOID : i = 6; break;
|
||||
case T_FLOAT : i = 7; break;
|
||||
case T_DOUBLE : i = 8; break;
|
||||
case T_OBJECT : i = 9; break;
|
||||
case T_ARRAY : i = 9; break;
|
||||
default : ShouldNotReachHere();
|
||||
}
|
||||
assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers,
|
||||
"index out of bounds");
|
||||
return i;
|
||||
}
|
||||
#endif // _LP64
|
||||
|
||||
// These should never be compiled since the interpreter will prefer
|
||||
// the compiled version to the intrinsic version.
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
switch (method_kind(m)) {
|
||||
case Interpreter::java_lang_math_sin : // fall thru
|
||||
case Interpreter::java_lang_math_cos : // fall thru
|
||||
case Interpreter::java_lang_math_tan : // fall thru
|
||||
case Interpreter::java_lang_math_abs : // fall thru
|
||||
case Interpreter::java_lang_math_log : // fall thru
|
||||
case Interpreter::java_lang_math_log10 : // fall thru
|
||||
case Interpreter::java_lang_math_sqrt : // fall thru
|
||||
case Interpreter::java_lang_math_pow : // fall thru
|
||||
case Interpreter::java_lang_math_exp :
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// How much stack a method activation needs in words.
|
||||
int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
|
||||
const int entry_size = frame::interpreter_frame_monitor_size();
|
||||
|
||||
// total overhead size: entry_size + (saved rbp thru expr stack
|
||||
// bottom). be sure to change this if you add/subtract anything
|
||||
// to/from the overhead area
|
||||
const int overhead_size =
|
||||
-(frame::interpreter_frame_initial_sp_offset) + entry_size;
|
||||
|
||||
#ifndef _LP64
|
||||
const int stub_code = 4; // see generate_call_stub
|
||||
#else
|
||||
const int stub_code = frame::entry_frame_after_call_words;
|
||||
#endif
|
||||
|
||||
const int method_stack = (method->max_locals() + method->max_stack()) *
|
||||
Interpreter::stackElementWords;
|
||||
return (overhead_size + method_stack + stub_code);
|
||||
}
|
||||
|
||||
#endif // CC_INTERP
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,8 @@
|
||||
#define __ _masm->
|
||||
|
||||
// Global Register Names
|
||||
Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
||||
Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
||||
static const Register rbcp = LP64_ONLY(r13) NOT_LP64(rsi);
|
||||
static const Register rlocals = LP64_ONLY(r14) NOT_LP64(rdi);
|
||||
|
||||
// Platform-dependent initialization
|
||||
void TemplateTable::pd_initialize() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -38,7 +38,6 @@
|
||||
#include "prims/jvmtiThreadState.hpp"
|
||||
#include "prims/methodHandles.hpp"
|
||||
#include "runtime/arguments.hpp"
|
||||
#include "runtime/deoptimization.hpp"
|
||||
#include "runtime/frame.inline.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
#include "runtime/stubRoutines.hpp"
|
||||
@ -74,7 +73,3 @@ address InterpreterGenerator::generate_abstract_entry() {
|
||||
bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Deoptimization::unwind_callee_save_values(frame* f,
|
||||
vframeArray* vframe_array) {
|
||||
}
|
||||
|
@ -571,6 +571,23 @@ void Deoptimization::cleanup_deopt_info(JavaThread *thread,
|
||||
thread->dec_in_deopt_handler();
|
||||
}
|
||||
|
||||
// Moved from cpu directories because none of the cpus has callee save values.
|
||||
// If a cpu implements callee save values, move this to deoptimization_<cpu>.cpp.
|
||||
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
// the days we had adapter frames. When we deoptimize a situation where a
|
||||
// compiled caller calls a compiled caller will have registers it expects
|
||||
// to survive the call to the callee. If we deoptimize the callee the only
|
||||
// way we can restore these registers is to have the oldest interpreter
|
||||
// frame that we create restore these values. That is what this routine
|
||||
// will accomplish.
|
||||
|
||||
// At the moment we have modified c2 to not have any callee save registers
|
||||
// so this problem does not exist and this routine is just a place holder.
|
||||
|
||||
assert(f->is_interpreted_frame(), "must be interpreted");
|
||||
}
|
||||
|
||||
// Return BasicType of value being returned
|
||||
JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_mode))
|
||||
|
Loading…
x
Reference in New Issue
Block a user