/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 "classfile/systemDictionary.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/compiledIC.hpp"
#include "code/scopeDesc.hpp"
#include "code/vtableStubs.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "memory/gcLocker.inline.hpp"
#include "memory/universe.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiRedefineClassesTrace.hpp"
#include "prims/methodHandles.hpp"
#include "prims/nativeLookup.hpp"
#include "runtime/arguments.hpp"
#include "runtime/biasedLocking.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/hashtable.inline.hpp"
#include "utilities/xmlstream.hpp"
#ifdef TARGET_ARCH_x86
# include "nativeInst_x86.hpp"
# include "vmreg_x86.inline.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "nativeInst_sparc.hpp"
# include "vmreg_sparc.inline.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "nativeInst_zero.hpp"
# include "vmreg_zero.inline.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "nativeInst_arm.hpp"
# include "vmreg_arm.inline.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "nativeInst_ppc.hpp"
# include "vmreg_ppc.inline.hpp"
#endif
#ifdef COMPILER1
#include "c1/c1_Runtime1.hpp"
#endif
// Shared stub locations
#ifdef COMPILER2
#endif // COMPILER2
//----------------------------generate_stubs-----------------------------------
_wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method), "wrong_method_stub");
_ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss), "ic_miss_stub");
_resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C), "resolve_opt_virtual_call");
_resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), "resolve_virtual_call");
_resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), "resolve_static_call");
#ifdef COMPILER2
// Vectors are generated only by C2.
if (is_wide_vector(MaxVectorSize)) {
_polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
}
#endif // COMPILER2
_polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
_polling_page_return_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
#ifdef COMPILER2
#endif // COMPILER2
}
#include <math.h>
#ifndef USDT2
char*, int, char*, int, char*, int);
char*, int, char*, int, char*, int);
#endif /* !USDT2 */
// Implementation of SharedRuntime
#ifndef PRODUCT
// For statistics
for (int i = 0; i < _ICmiss_index; i++) {
if (_ICmiss_at[i] == at) {
_ICmiss_count[i]++;
return;
}
}
}
if (ICMissHistogram) {
int tot_misses = 0;
for (int i = 0; i < _ICmiss_index; i++) {
tot_misses += _ICmiss_count[i];
}
}
}
#endif // PRODUCT
#ifndef SERIALGC
// G1 write-barrier pre: executed before a pointer store.
assert(false, "should be optimized out");
return;
}
// store the original value that was in the field reference
// G1 write-barrier post: executed after a pointer store.
#endif // !SERIALGC
return x * y;
return x;
} else {
return x / y;
}
return 0;
} else {
return x % y;
}
#ifdef _WIN64
// 64-bit Windows on amd64 returns the wrong values for
// infinity operands.
xbits.f = x;
ybits.f = y;
// x Mod Infinity == x unless x is infinity
return x;
}
#endif
#ifdef _WIN64
xbits.d = x;
ybits.d = y;
// x Mod Infinity == x unless x is infinity
return x;
}
#endif
#ifdef __SOFTFP__
return x + y;
return x - y;
return x * y;
return x / y;
return x + y;
return x - y;
return x * y;
return x / y;
return (jfloat)x;
return (jdouble)x;
return (jdouble)x;
return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan*/
return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */
return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan */
return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */
// Functions to return the opposite of the aeabi functions for nan.
// Intrinsics make gcc generate code for these.
return -f;
}
return -f;
}
#endif // __SOFTFP__
#if defined(__SOFTFP__) || defined(E500V2)
// Intrinsics make gcc generate code for these.
return (f <= (double)0.0) ? (double)0.0 - f : f;
}
#endif
#if defined(__SOFTFP__) || defined(PPC)
return sqrt(f);
}
#endif
if (g_isnan(x))
return 0;
return max_jint;
return min_jint;
return (jint) x;
if (g_isnan(x))
return 0;
return max_jlong;
return min_jlong;
return (jlong) x;
if (g_isnan(x))
return 0;
return max_jint;
return min_jint;
return (jint) x;
if (g_isnan(x))
return 0;
return max_jlong;
return min_jlong;
return (jlong) x;
return (jfloat)x;
return (jfloat)x;
return (jdouble)x;
// Exception handling accross interpreter/compiler boundaries
//
// exception_handler_for_return_address(...) returns the continuation address.
// The continuation address is the entry point of the exception handler of the
// previous frame depending on the return address.
address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) {
assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address));
// Reset method handle flag.
thread->set_is_method_handle_return(false);
// The fastest case first
// Set flag if return address is a method handle call site.
// native nmethods don't have exception handlers
} else {
return nm->exception_begin();
}
}
// Entry code
return StubRoutines::catch_exception_entry();
}
// Interpreted code
return Interpreter::rethrow_exception_entry();
}
guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!");
#ifndef PRODUCT
tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address);
}
#endif // PRODUCT
return NULL;
}
JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address))
// Look up the code blob
// Should be an nmethod
// Look up the relocation information
"safepoint polling: type must be poll" );
"Only polling locations are used for safepoint");
if (at_poll_return) {
"polling page return stub not created yet");
} else if (has_wide_vectors) {
"polling page vectors safepoint stub not created yet");
} else {
"polling page safepoint stub not created yet");
}
#ifndef PRODUCT
if( TraceSafepoint ) {
"... found polling page %s exception at pc = "
}
#endif // PRODUCT
return stub;
}
assert(args_size <= caller.interpreter_frame_expression_stack_size(), "receiver must be on interpreter stack");
return result;
}
if (JvmtiExport::can_post_on_exceptions()) {
}
}
void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message) {
}
// The interpreter code to call this tracing function is only
// set. Since obsolete methods are never compiled, we don't have
// to modify the compilers to generate calls to this function.
//
if (method->is_obsolete()) {
// We are calling an obsolete method, but this is not necessarily
// an error. Our method could have been redefined just after we
// fetched the methodOop from the constant pool.
// RC_TRACE macro has an embedded ResourceMark
("calling obsolete method '%s'",
if (RC_TRACE_ENABLED(0x00002000)) {
// this option is provided to debug calls to obsolete methods
guarantee(false, "faulting at call to an obsolete method.");
}
}
return 0;
// ret_pc points into caller; we are returning caller's exception handler
// for given exception
bool force_unwind, bool top_frame_only) {
// determine handler bci, if any
int scope_depth = 0;
if (!force_unwind) {
bool recursive_exception = false;
do {
bool skip_scope_increment = false;
// exception handler lookup
if (HAS_PENDING_EXCEPTION) {
recursive_exception = true;
// We threw an exception while trying to find the exception handler.
// Transfer the new exception to the exception handle which will
// be set into thread local storage, and do another lookup for an
// exception handler for this exception, this time starting at the
// BCI of the exception handler which caused the exception to be
// thrown (bugs 4307310 and 4546590). Set "exception" reference
// argument to ensure that the correct exception is thrown (4870175).
if (handler_bci >= 0) {
bci = handler_bci;
handler_bci = -1;
skip_scope_increment = true;
}
}
else {
recursive_exception = false;
}
}
++scope_depth;
}
}
// found handling method => lookup exception handler
// Allow abbreviated catch tables. The idea is to allow a method
// to materialize its exceptions without committing to the exact
// routing of exceptions. In particular this is needed for adding
// a synthethic handler to unlock monitors when inlining
// synchonized methods since the unlock path isn't represented in
// the bytecodes.
}
#ifdef COMPILER1
return nm->unwind_handler_begin();
}
#endif
if (t == NULL) {
tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
nm->print_code();
guarantee(false, "missing exception handler");
return NULL;
}
}
// These errors occur only at call sites
// These errors occur only at call sites
throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub");
// This entry point is effectively only used for NullPointerExceptions which occur at inline
// cache sites (when the callee activation is not yet set up) so we are at a call site
// We avoid using the normal exception construction in this case because
// it performs an upcall to Java, and we're already out of stack space.
if (StackTraceInThrowable) {
}
{
#ifdef CC_INTERP
// C++ interpreter doesn't throw implicit exceptions
#else
switch (exception_kind) {
default: ShouldNotReachHere();
}
#endif // !CC_INTERP
} else {
switch (exception_kind) {
case STACK_OVERFLOW: {
// Stack overflow only occurs upon frame setup; the callee is
// going to be unwound. Dispatch to a shared runtime stub
// which will cause the StackOverflowError to be fabricated
// and processed.
// For stack overflow in deoptimization blob, cleanup thread.
}
return StubRoutines::throw_StackOverflowError_entry();
}
case IMPLICIT_NULL: {
// We haven't yet entered the callee frame. Fabricate an
// exception and begin dispatching it in the caller. Since
// the caller was at a call site, it's safe to destroy all
// caller-saved registers, as these entry points do.
// If vt_stub is NULL, then return NULL to signal handler to report the SEGV error.
assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
return StubRoutines::throw_AbstractMethodError_entry();
} else {
}
} else {
// If code blob is NULL, then return NULL to signal handler to report the SEGV error.
// Exception happened in CodeCache. Must be either:
// 1. Inline-cache check in C2I handler blob,
// 2. Inline-cache check in nmethod, or
// 3. Implict null exception in nmethod
if (!cb->is_nmethod()) {
"exception happened outside interpreter, nmethods and vtable stubs (1)");
// There is no handler here, so we will simply unwind.
}
// Otherwise, it's an nmethod. Consult its exception handlers.
// exception happened inside inline-cache check code
// => the nmethod is not yet active (i.e., the frame
// is not set up yet) => use return address pushed by
// caller => don't push another return address
}
// exception happened inside MH dispatch code, similar to a vtable stub
}
#ifndef PRODUCT
#endif
// If there's an unexpected fault, target_pc might be NULL,
// in which case we want to fall through into the normal
// error handling code.
}
break; // fall through
}
case IMPLICIT_DIVIDE_BY_ZERO: {
#ifndef PRODUCT
#endif
// If there's an unexpected fault, target_pc might be NULL,
// in which case we want to fall through into the normal
// error handling code.
break; // fall through
}
default: ShouldNotReachHere();
}
assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind");
// for AbortVMOnException flag
if (exception_kind == IMPLICIT_NULL) {
Events::log_exception(thread, "Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
} else {
Events::log_exception(thread, "Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
}
return target_pc;
}
return NULL;
}
/**
* Throws an java/lang/UnsatisfiedLinkError. The address of this method is
* installed in the native function entry of all native Java methods before
* they get linked to their actual native methods.
*
* \note
* This method actually never gets called! The reason is because
* the interpreter's native entries call NativeLookup::lookup() which
* throws the exception when the lookup fails. The exception is then
* caught and forwarded on the return from NativeLookup::lookup() call
* before the call to the native function. This might change in the future.
*/
{
// We return a bad value here to make sure that the exception is
// forwarded before we look at the return value.
}
}
#ifndef PRODUCT
JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
#ifndef PRODUCT
#endif // !PRODUCT
return preserve_this_value;
#endif // !PRODUCT
if (thread->is_Java_thread()) {
}
}
return 0;
}
/**
* This function ought to be a void function, but cannot be because
* it gets turned into a tail-call on sparc, which runs into dtrace bug
* 6254741. Once that is fixed we can remove the dummy return value.
*/
}
#ifndef USDT2
#else /* USDT2 */
#endif /* USDT2 */
return 0;
}
#ifndef USDT2
#else /* USDT2 */
#endif /* USDT2 */
return 0;
#ifndef USDT2
#else /* USDT2 */
#endif /* USDT2 */
return 0;
// Finds receiver, CallInfo (i.e. receiver method), and calling bytecode)
// for a call current in progress, i.e., arguments has been pushed on stack
// vtable updates, etc. Caller frame must be compiled.
Handle SharedRuntime::find_callee_info(JavaThread* thread, Bytecodes::Code& bc, CallInfo& callinfo, TRAPS) {
// last java frame on stack (which includes native call frames)
}
// Finds receiver, CallInfo (i.e. receiver method), and calling bytecode
// for a call current in progress, i.e., arguments has been pushed on stack
// but callee has not been invoked yet. Caller frame must be compiled.
// Find caller and bci from vframe
// Find bytecode
// Find receiver for non-static call
// This register map must be update since we need to find the receiver for
// compiled frames. The receiver might be in a register.
// Caller-frame is a compiled frame
}
// Retrieve from a compiled argument list
}
}
// Resolve method. This is parameterized by bytecode.
LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle));
#ifdef ASSERT
// Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
// klass is already loaded
// Method handle invokes might have been optimized to a direct call
// so don't check for the receiver class.
// FIXME this weakens the assert too much
"actual receiver must be subclass of static receiver klass");
if (receiver_klass->oop_is_instance()) {
}
assert(!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
}
}
#endif
return receiver;
}
// We need first to check if any Java activations (compiled, interpreted)
// exist on the stack since last JavaCall. If not, we need
// to get the target method from the JavaCall wrapper.
// No Java frames were found on stack since we did the JavaCall.
// Hence the stack can only contain an entry_frame. We need to
// find the target method from the stub frame.
// fr is now pointing to the entry frame.
assert(fr.entry_frame_call_wrapper()->receiver() == NULL || !callee_method->is_static(), "non-null receiver for static call??");
} else {
}
return callee_method;
}
// Resolves a call.
bool is_virtual,
bool is_optimized, TRAPS) {
if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
int retry_count = 0;
// If has a pending exception then there is no need to re-try to
// resolve this method.
// If the method has been redefined, we need to try again.
// Hack: we have no way to update the vtables of arrays, so don't
// require that java.lang.Object has been updated.
// It is very unlikely that method is redefined more than 100 times
// in the middle of resolve. If it is looping here more than 100 times
// means then there could be a bug here.
"Could not resolve to latest version of redefined method");
// method is redefined in the middle of resolve so re-try.
}
}
return callee_method;
}
// Resolves a call. The compilers generate code for calls that go here
// and are patched with the real destination of the call.
bool is_virtual,
bool is_optimized, TRAPS) {
// make sure caller is not getting deoptimized
// and removed before we are done with it.
// CLEANUP - with lazy deopt shouldn't need this lock
// determine call info & receiver
// note: a) receiver is NULL for static calls
// b) an exception is thrown if receiver is NULL for non-static calls
#ifndef PRODUCT
(is_virtual) ? (&_resolve_virtual_ctr) :
if (TraceCallFixup) {
tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT, caller_frame.pc(), callee_method->code());
}
#endif
// JSR 292 key invariant:
// If the resolved method is a MethodHandle invoke target the call
// site must be a MethodHandle call site, because the lambda form might tail-call
// leaving the stack in a state unknown to either caller or callee
// TODO detune for now but we might need it again
// assert(!callee_method->is_compiled_lambda_form() ||
// caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
// Compute entry points. This might require generation of C2I converter
// frames, so we cannot be holding any locks here. Furthermore, the
// computation of the entry points is independent of patching the call. We
// always return the entry-point, but we only patch the stub if the call has
// not been deoptimized. Return values: For a virtual call this is an
// virtual this is just a destination address.
// Make sure the callee nmethod does not get deoptimized and removed before
// we are done patching the code.
#ifdef ASSERT
#endif
if (is_virtual) {
CHECK_(methodHandle()));
} else {
// static call
}
// grab lock, check for deoptimization and potentially patch caller
{
// Now that we are ready to patch if the methodOop was redefined then
// don't update call site and let the caller retry.
if (!callee_method->is_old()) {
#ifdef ASSERT
// We must not try to patch to jump to an already unloaded method.
if (dest_entry_point != 0) {
"should not unload nmethod while locked");
}
#endif
if (is_virtual) {
if (inline_cache->is_clean()) {
}
} else {
}
}
} // unlock CompiledIC_lock
return callee_method;
}
// Inline caches exist only in compiled code
#ifdef ASSERT
#endif /* ASSERT */
// Return methodOop through TLS
// return compiled code entry point after potential safepoints
return callee_method->verified_code_entry();
// Handle call site that has been made non-entrant
// 6243940 We might end up in here if the callee is deoptimized
// as we race to call it. We don't want to take a safepoint if
// the caller was interpreted because the caller frame will look
// interpreted to the stack walkers and arguments are now
// "compiled" so it is much better to make this transition
// invisible to the stack walking code. The i2c path will
// place the callee method in the callee_target. It is stashed
// there because if we try and find the callee by normal means a
// safepoint is possible and have trouble gc'ing the compiled args.
// MethodHandle invokes don't have a CompiledIC and should always
// simply redispatch to the callee_target.
if (caller_frame.is_interpreted_frame() ||
return callee->get_c2i_entry();
}
// Must be compiled to compiled path which is safe to stackwalk
// Force resolving of caller (if we called from compiled frame)
// return compiled code entry point after potential safepoints
return callee_method->verified_code_entry();
// resolve a static call and patch code
// return compiled code entry point after potential safepoints
return callee_method->verified_code_entry();
// resolve virtual call and update inline cache to monomorphic
// return compiled code entry point after potential safepoints
return callee_method->verified_code_entry();
// Resolve a virtual call that can be statically bound (e.g., always
// monomorphic, so it has no inline cache). Patch code to resolved target.
// return compiled code entry point after potential safepoints
return callee_method->verified_code_entry();
// receiver is NULL for static calls. An exception is thrown for NULL
// receivers for non-static calls
CHECK_(methodHandle()));
// Compiler1 can produce virtual call sites that can actually be statically bound
// If we fell thru to below we would think that the site was going megamorphic
// when in fact the site can never miss. Worse because we'd think it was megamorphic
// we'd try and do a vtable dispatch however methods that can be statically bound
// don't have vtable entries (vtable_index < 0) and we'd blow up. So we force a
// reresolution of the call site (as if we did a handle_wrong_method and not an
// plain ic_miss) and the site will be converted to an optimized virtual call site
// never to miss again. I don't believe C2 will produce code like this but if it
// did this would still be the correct thing to do for it too, hence no ifdef.
//
if (TraceCallFixup) {
}
return callee_method;
}
bool should_be_mono = false;
#ifndef PRODUCT
// Statistics & Tracing
if (TraceCallFixup) {
}
if (ICMissHistogram) {
// produce statistics under the lock
trace_ic_miss(f.pc());
}
#endif
// install an event collector so that when a vtable stub is created the
// profiler can be notified via a DYNAMIC_CODE_GENERATED event. The
// event can't be posted when the stub is created as locks are held
// - instead the event will be deferred until the event collector goes
// out of scope.
// Update inline cache to megamorphic. Skip update if caller has been
// made non-entrant or we are called from interpreted.
// Not a non-entrant nmethod, so find inline_cache
bool should_be_mono = false;
if (inline_cache->is_optimized()) {
if (TraceCallFixup) {
}
should_be_mono = true;
} else {
// This isn't a real miss. We must have seen that compiled code
// is now available and we want the call site converted to a
// monomorphic compiled call site.
// We can't assert for callee_method->code() != NULL because it
// could have been deoptimized in the meantime
if (TraceCallFixup) {
}
should_be_mono = true;
}
}
}
if (should_be_mono) {
// We have a path that was monomorphic but was going interpreted
// and now we have (or had) a compiled entry. We correct the IC
// by using a new icBuffer.
false,
// Change to megamorphic
} else {
// Either clean or megamorphic
}
}
} // Release CompiledIC_lock
return callee_method;
}
//
// Resets a call-site in compiled code so it will get resolved again.
// This routines handles both virtual call sites, optimized virtual call
// sites, and static call sites. Typically used to change a call sites
// destination from compiled to interpreted.
//
// Do nothing if the frame isn't a live compiled frame.
// nmethod could be deoptimized by the time we get here
// so no update to the caller is needed.
// Default call_addr is the location of the "basic" call.
// Determine the address of the call we a reresolving. With
// Inline Caches we will always find a recognizable call.
// With Inline Caches disabled we may or may not find a
// recognizable call. We will always find a call for static
// calls and for optimized virtual calls. For vanilla virtual
// calls it depends on the state of the UseInlineCaches switch.
//
// With Inline Caches disabled we can get here for a virtual call
// for two reasons:
// 1 - calling an abstract method. The vtable for abstract methods
// will run us thru handle_wrong_method and we will eventually
// end up in the interpreter to throw the ame.
// 2 - a racing deoptimization. We could be doing a vanilla vtable
// call and between the time we fetch the entry address and
// we jump to it the target gets deoptimized. Similar to 1
// we will wind up in the interprter (thru a c2i with c2).
//
{
// Get call instruction under lock because another thread may be
// busy patching it.
// Location of call instruction
}
}
// Check for static or virtual call
bool is_static_call = false;
// Make sure nmethod doesn't get deoptimized and removed until
// this is done with it.
// CLEANUP - with lazy deopt shouldn't need this lock
if (ret) {
is_static_call = true;
} else {
, "unexpected relocInfo. type");
}
} else {
}
// Cleaning the inline cache will force a new resolve. This is more robust
// than directly setting it to the new destination, since resolving of calls
// is always done through the same code path. (experience shows that it
// leads to very hard to track down bugs, if an inline cache gets updated
// to a wrong method). It should not be performance critical, since the
// resolve is only done once.
//
// We do not patch the call site if the nmethod has been made non-entrant
// as it is a waste of time
//
if (is_static_call) {
ssc->set_to_clean();
} else {
// compiled, dispatched call (which used to call an interpreted method)
}
}
}
}
#ifndef PRODUCT
if (TraceCallFixup) {
}
#endif
return callee_method;
}
#ifdef ASSERT
int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1, is_outgoing);
for (int i = 0; i < member_arg_pos; i++) {
assert(a->value() == b->value(), err_msg_res("register allocation mismatch: a=%d, b=%d", a->value(), b->value()));
}
}
#endif
// ---------------------------------------------------------------------------
// We are calling the interpreter via a c2i. Normally this would mean that
// we were called by a compiled method. However we could have lost a race
// where we went int -> i2c -> c2i and so the caller could in fact be
// interpreted. If the caller is compiled we attempt to patch the caller
// so he no longer calls into the interpreter.
// It's possible that deoptimization can occur at a call site which hasn't
// been resolved yet, in which case this function will be called from
// an nmethod that has been patched for deopt and we can ignore the
// request for a fixup.
// Also it is possible that we lost a race in that from_compiled_entry
// is now back to the i2c in that case we don't need to patch and if
// we did we'd leap into space because the callsite needs to use
// "to interpreter" stub in order to load up the methodOop. Don't
// ask me how I know this...
return;
}
// The check above makes sure this is a nmethod.
// Get the return PC for the passed caller PC.
// There is a benign race here. We could be attempting to patch to a compiled
// entry point at the same time the callee is being deoptimized. If that is
// the case then entry_point may in fact point to a c2i and we'd patch the
// call site with the same old data. clear_code will set code() to NULL
// at the end of it. If we happen to see that NULL then we can skip trying
// to patch. If we hit the window where the callee has a c2i in the
// from_compiled_entry and the NULL isn't present yet then we lose the race
// and patch the code with the same old data. Asi es la vida.
// Expect to find a native call there (unless it was no-inline cache vtable dispatch)
//
// bug 6281185. We might get here after resolving a call site to a vanilla
// virtual call. Because the resolvee uses the verified entry it may then
// see compiled code and attempt to patch the site by calling us. This would
// then incorrectly convert the call site to optimized and its downhill from
// there. If you're lucky you'll get the assert in the bugid, if not you've
// just made a call site that could be megamorphic into a monomorphic site
// for the rest of its life! Just another racing bug in the life of
// fixup_callers_callsite ...
//
return;
}
if (destination != entry_point) {
// callee == cb seems weird. It means calling interpreter thru stub.
// static call or optimized virtual
if (TraceCallFixup) {
}
} else {
if (TraceCallFixup) {
}
// assert is too strong could also be resolve destinations.
// assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
}
} else {
if (TraceCallFixup) {
}
}
}
}
// same as JVM_Arraycopy, but called directly from compiled code
JavaThread* thread)) {
#ifndef PRODUCT
#endif
// Check if we have null pointers
}
// Do the copy. The casts to arrayOop are necessary to the copy_array API,
// even though the copy_array API also performs dynamic checks to ensure
// that src and dest are truly arrays (and are conformable).
// The copy_array mechanism is awkward and could be removed, but
// the compilers don't call this function except as a last resort,
// so it probably doesn't matter.
}
// Get target class name from the checkcast instruction
}
// Shouldn't happen, but don't cause even more problems if it does
} else {
}
return message;
}
// Handles the uncommon case in locking, i.e., contention or an inflated lock.
#ifndef PRODUCT
#endif
JRT_ENTRY_NO_ASYNC(void, SharedRuntime::complete_monitor_locking_C(oopDesc* _obj, BasicLock* lock, JavaThread* thread))
#ifndef PRODUCT
_monitor_enter_ctr++; // monitor enter slow
#endif
if (PrintBiasedLockingStatistics) {
}
if (UseBiasedLocking) {
// Retry fast entry if bias is revoked to avoid unnecessary inflation
} else {
}
#ifndef PRODUCT
#endif
// Handles the uncommon cases of monitor unlocking in compiled code
#ifndef PRODUCT
_monitor_exit_ctr++; // monitor exit slow
#endif
// I'm not convinced we need the code contained by MIGHT_HAVE_PENDING anymore
// testing was unable to ever fire the assert that guarded it so I have removed it.
#ifdef MIGHT_HAVE_PENDING
// Save and restore any pending_exception around the exception mark.
// While the slow_exit must not throw an exception, we could come into
// this routine with one set.
const char* pending_file;
int pending_line;
if (HAS_PENDING_EXCEPTION) {
}
#endif /* MIGHT_HAVE_PENDING */
{
// Exit must be non-blocking, and therefore no exceptions can be thrown.
}
#ifdef MIGHT_HAVE_PENDING
if (pending_excep != NULL) {
}
#endif /* MIGHT_HAVE_PENDING */
#ifndef PRODUCT
if (CountRemovableExceptions) {
if (_nof_removable_exceptions > 0) {
Unimplemented(); // this counter is not yet incremented
}
}
// Dump the JRT_ENTRY counters
if( _checkcast_array_copy_ctr ) tty->print_cr("%5d checkcast array copies", _checkcast_array_copy_ctr );
}
inline double percent(int x, int y) {
}
class MethodArityHistogram {
public:
private:
}
const int N = MIN2(5, n);
double sum = 0;
double weighted_sum = 0;
int i;
for (i = 0; i <= N; i++) {
}
}
void print_histogram() {
}
public:
_max_arity = _max_size = 0;
}
};
int mono_i = _nof_interface_calls - _nof_optimized_interface_calls - _nof_megamorphic_interface_calls;
tty->print_cr("\t%9d (%4.1f%%) virtual calls ", _nof_normal_calls, percent(_nof_normal_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_calls, percent(_nof_inlined_calls, _nof_normal_calls));
tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_calls, percent(_nof_optimized_calls, _nof_normal_calls));
tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_calls, percent(_nof_megamorphic_calls, _nof_normal_calls));
tty->print_cr("\t%9d (%4.1f%%) interface calls ", _nof_interface_calls, percent(_nof_interface_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_interface_calls, percent(_nof_inlined_interface_calls, _nof_interface_calls));
tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_interface_calls, percent(_nof_optimized_interface_calls, _nof_interface_calls));
tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_interface_calls, percent(_nof_megamorphic_interface_calls, _nof_interface_calls));
tty->print_cr("\t%9d (%4.1f%%) static/special calls", _nof_static_calls, percent(_nof_static_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_static_calls, percent(_nof_inlined_static_calls, _nof_static_calls));
}
#endif
// A simple wrapper class around the calling convention information
// that allows sharing of adapters for the same calling convention.
private:
enum {
};
// TO DO: Consider integrating this with a more global scheme for compressing signatures.
union {
int* _fingerprint;
} _value;
// Otherwise _value._fingerprint is the array.
// Remap BasicTypes that are handled equivalently by the adapters.
// These are correct for the current system but someday it might be
// necessary to make this mapping platform dependent.
switch(in) {
case T_BOOLEAN:
case T_BYTE:
case T_SHORT:
case T_CHAR:
// There are all promoted to T_INT in the calling convention
return T_INT;
case T_OBJECT:
case T_ARRAY:
// In other words, we assume that any register good enough for
// an int or long is good enough for a managed pointer.
#ifdef _LP64
return T_LONG;
#else
return T_INT;
#endif
case T_INT:
case T_LONG:
case T_FLOAT:
case T_DOUBLE:
case T_VOID:
return in;
default:
return T_CONFLICT;
}
}
public:
// The fingerprint is based on the BasicType signature encoded
// into an array of ints with eight entries per int.
int* ptr;
if (len <= _compact_int_count) {
// Storing the signature encoded as signed chars hits about 98%
// of the time.
} else {
}
// Now pack the BasicTypes with 8 per int
int sig_index = 0;
int value = 0;
: 0);
}
}
}
~AdapterFingerPrint() {
if (_length > 0) {
}
}
if (_length < 0) {
}
}
int length() {
return _length;
}
bool is_compact() {
return _length <= 0;
}
unsigned int compute_hash() {
int hash = 0;
for (int i = 0; i < length(); i++) {
int v = value(i);
}
return (unsigned int)hash;
}
const char* as_string() {
for (int i = 0; i < length(); i++) {
}
}
return false;
}
if (_length < 0) {
} else {
for (int i = 0; i < _length; i++) {
return false;
}
}
}
return true;
}
};
// A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries
friend class AdapterHandlerTableIterator;
private:
#ifndef PRODUCT
#endif
}
public:
// Create a new entry suitable for insertion in the table
AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
return entry;
}
// Insert an entry into the table
}
entry->deallocate();
}
// Find a entry with the same fingerprint if it exists
NOT_PRODUCT(_lookups++);
NOT_PRODUCT(_buckets++);
NOT_PRODUCT(_equals++);
#ifndef PRODUCT
_hits++;
#endif
return e;
}
}
}
return NULL;
}
#ifndef PRODUCT
void print_statistics() {
int longest = 0;
int empty = 0;
int total = 0;
int nonempty = 0;
int count = 0;
count++;
}
}
}
#endif
};
#ifndef PRODUCT
#endif
private:
int _index;
void scan() {
_index++;
if (a != NULL) {
_current = a;
return;
}
}
}
public:
scan();
}
bool has_next() {
}
return result;
} else {
return NULL;
}
}
};
// ---------------------------------------------------------------------------
// Implementation of AdapterHandlerLibrary
// Should be called only when AdapterHandlerLibrary_lock is active.
return _buffer;
}
_adapters = new AdapterHandlerTable();
// Create a special handler for abstract methods. Abstract methods
// are never compiled so an i2c entry is somewhat meaningless, but
// fill it in with something appropriate just in case. Pass handle
// wrong method for the c2i transitions.
}
}
// Use customized signature handler. Need to lock around updates to
// the AdapterHandlerTable (it is not safe for concurrent readers
// and a single writer: this could be fixed if it becomes a
// problem).
// Get the address of the ic_miss handlers before we grab the
// AdapterHandlerLibrary_lock. This fixes bug 6236259 which
// was caused by the initialization of the stubs happening
// while we held the lock and then notifying jvmti while
// holding it. This just forces the initialization to be a little
// earlier.
NOT_PRODUCT(int insts_size);
AdapterBlob* B = NULL;
{
// make sure data structure is initialized
initialize();
if (method->is_abstract()) {
return _abstract_method_handler;
}
// Fill in the signature array, for the calling-convention call.
int i = 0;
}
// Lookup method signature's fingerprint
#ifdef ASSERT
}
#endif
return entry;
}
// Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
// Make a C heap allocated version of the fingerprint to store in the adapter
// Create I2C & C2I handlers
sizeof(buffer_locs)/sizeof(relocInfo));
regs,
#ifdef ASSERT
if (VerifyAdapterSharing) {
if (shared_entry != NULL) {
assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt),
"code must match");
// Release the one just created and return the original
return shared_entry;
} else {
}
}
#endif
}
if (B == NULL) {
// CodeCache is full, disable compilation
// Ought to log this but compile log is only per compile thread
// and we're some non descript Java thread.
return NULL; // Out of CodeCache space
}
#ifndef PRODUCT
// debugging suppport
if (PrintAdapterHandlers || PrintStubCode) {
if (Verbose || PrintStubCode) {
}
}
}
#endif
}
// Outside of the lock
if (B != NULL) {
sizeof(blob_id),
"%s(%s)@" PTR_FORMAT,
B->name(),
fingerprint->as_string(),
B->content_begin());
}
}
return entry;
}
return base;
}
if (_i2c_entry != NULL)
_i2c_entry += delta;
if (_c2i_entry != NULL)
_c2i_entry += delta;
if (_c2i_unverified_entry != NULL)
}
delete _fingerprint;
#ifdef ASSERT
#endif
}
#ifdef ASSERT
// Capture the code before relocation so that it can be compared
// against other versions. If the code is captured after relocation
// then relative instructions won't be equivalent.
void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
}
bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
if (length != _code_length) {
return false;
}
for (int i = 0; i < length; i++) {
if (buffer[i] != _saved_code[i]) {
return false;
}
}
return true;
}
#endif
// Create a native wrapper for this native method. The wrapper converts the
// java compiled calling convention to the native convention, handlizes
// arguments, and transitions to native. On return from the native we transition
// back to java blocking if a safepoint is in progress.
{
// perform the work while holding the lock, but perform any printing outside the lock
// See if somebody beat us to it
if (nm) {
return nm;
}
// Fill in the signature array, for the calling-convention call.
int i=0;
}
// Now get the compiled-Java layout as input (or output) arguments.
// NOTE: Stubs for compiled entry points of method handle intrinsics
// are just trampolines so the argument registers must be outgoing ones.
int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
// Generate the compiled-to-native wrapper code
regs,
ret_type);
}
}
// Must unlock before calling set_code
// Install the generated code.
if (PrintCompilation) {
}
} else {
// CodeCache is full, disable compilation
}
return nm;
}
// The code is about to enter a JNI lazy critical native method and
// _needs_gc is true, so if this thread is already in a critical
// section then just return, otherwise this thread should block
// until needs_gc has been cleared.
if (thread->in_critical()) {
return;
}
// Lock and unlock a critical section to give the system a chance to block
#ifdef HAVE_DTRACE_H
// Create a dtrace nmethod for this method. The wrapper converts the
// java compiled calling convention to the native convention, makes a dummy call
// (actually nops for the size of the call instruction, which become a trap if
// probe is enabled). The returns to the caller. Since this all looks like a
// leaf no thread transition is needed.
if (PrintCompilation) {
}
}
{
// perform the work while holding the lock, but perform any printing
// outside the lock
// See if somebody beat us to it
if (nm) {
return nm;
}
// Need a few relocation entries
// Generate the compiled-to-native wrapper code
}
}
return nm;
}
// the dtrace method needs to convert java lang string to utf8 string.
}
#endif // ndef HAVE_DTRACE_H
// -------------------------------------------------------------------------
// Java-Java calling convention
// (what you use when Java calls Java)
//------------------------------name_for_receiver----------------------------------
// For a given signature, return the VMReg for parameter 0.
// Return argument 0 register. In the LP64 build pointers
// take 2 registers, but the VM wants only the 'main' name.
}
// This method is returning a data structure allocating as a
// ResourceObject, so do not put any ResourceMarks in here.
char *s = sig->as_C_string();
*s++; len--; // Skip opening paren
char *t = s+len;
while( *(--t) != ')' ) ; // Find close paren
int cnt = 0;
if (has_receiver) {
}
while( s < t ) {
switch( *s++ ) { // Switch on signature character
case 'L': // Oop
while( *s++ != ';' ) ; // Skip signature
break;
case '[': { // Array
do { // Skip optional size
while( *s >= '0' && *s <= '9' ) s++;
} while( *s++ == '[' ); // Nested arrays?
// Skip element type
if( s[-1] == 'L' )
while( *s++ != ';' ) ; // Skip signature
break;
}
default : ShouldNotReachHere();
}
}
int comp_args_on_stack;
// the calling convention doesn't count out_preserve_stack_slots so
// we must add that in to get "true" stack offsets.
if (comp_args_on_stack) {
for (int i = 0; i < cnt; i++) {
// Yuck
}
// Yuck
}
}
}
// results
return regs;
}
// OSR Migration Code
//
// This code is used convert interpreter frames into compiled frames. It is
// called from very start of a compiled OSR nmethod. A temp array is
// allocated to hold the interesting bits of the interpreter frame. All
// active locks are inflated to allow them to move. The displaced headers and
// active interpeter locals are copied into the temp buffer. Then we return
// back to the compiled code. The compiled code then pops the current
// interpreter frame off the stack and pushes a new compiled frame. Then it
// copies the interpreter locals and displaced headers where it wants.
// Finally it calls back to free the temp buffer.
//
// All of this is done NOT at any Safepoint, nor is any safepoint or GC allowed.
#ifdef IA64
ShouldNotReachHere(); // NYI
#endif /* IA64 */
//
// This code is dependent on the memory layout of the interpreter local
// array and the monitors. On all of our platforms the layout is identical
// so this code is shared. If some platform lays the their arrays out
// differently then this code could move to platform specific code or
// the code here could be modified to copy items one at a time using
// frame accessor methods and be platform independent.
// Figure out how many monitors are active.
int active_monitor_count = 0;
}
// QQQ we could place number of active monitors in the array so that compiled code
// could double check it.
// Allocate temp buffer, 1 word per local & 2 per active monitor
// Copy the locals. Order is preserved so that loading of longs works.
// Since there's no GC I can copy the oops blindly.
// Inflate locks. Copy the displaced headers. Be careful, there can be holes.
int i = max_locals;
// Inflate so the displaced header becomes position-independent
// Now the displaced header is free to move
}
}
return buf;
}
return false;
}
a->print_adapter_on(tty);
return;
}
}
assert(false, "Should have found handler");
}
st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
}
#ifndef PRODUCT
void AdapterHandlerLibrary::print_statistics() {
}
#endif /* PRODUCT */