Path: blob/master/src/hotspot/share/runtime/javaCalls.cpp
40951 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2021, Azul Systems, Inc. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "classfile/vmSymbols.hpp"27#include "code/nmethod.hpp"28#include "compiler/compilationPolicy.hpp"29#include "compiler/compileBroker.hpp"30#include "interpreter/interpreter.hpp"31#include "interpreter/linkResolver.hpp"32#if INCLUDE_JVMCI33#include "jvmci/jvmciJavaClasses.hpp"34#endif35#include "memory/universe.hpp"36#include "oops/method.inline.hpp"37#include "oops/oop.inline.hpp"38#include "prims/jniCheck.hpp"39#include "prims/jvmtiExport.hpp"40#include "runtime/handles.inline.hpp"41#include "runtime/interfaceSupport.inline.hpp"42#include "runtime/javaCalls.hpp"43#include "runtime/jniHandles.inline.hpp"44#include "runtime/mutexLocker.hpp"45#include "runtime/os.inline.hpp"46#include "runtime/sharedRuntime.hpp"47#include "runtime/signature.hpp"48#include "runtime/stubRoutines.hpp"49#include "runtime/thread.inline.hpp"5051// -----------------------------------------------------52// Implementation of JavaCallWrapper5354JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS) {55JavaThread* thread = THREAD;56bool clear_pending_exception = true;5758guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");59assert(!thread->owns_locks(), "must release all locks when leaving VM");60guarantee(thread->can_call_java(), "cannot make java calls from the native compiler");61_result = result;6263// Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub,64// since it can potentially block.65JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);6667// After this, we are official in JavaCode. This needs to be done before we change any of the thread local68// info, since we cannot find oops before the new information is set up completely.69ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java);7071// Make sure that we handle asynchronous stops and suspends _before_ we clear all thread state72// in JavaCallWrapper::JavaCallWrapper(). This way, we can decide if we need to do any pd actions73// to prepare for stop/suspend (flush register windows on sparcs, cache sp, or other state).74if (thread->has_special_runtime_exit_condition()) {75thread->handle_special_runtime_exit_condition();76if (HAS_PENDING_EXCEPTION) {77clear_pending_exception = false;78}79}8081// Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing82// the JavaCallWrapper before the entry frame is on the stack.83_callee_method = callee_method();84_receiver = receiver();8586#ifdef CHECK_UNHANDLED_OOPS87THREAD->allow_unhandled_oop(&_receiver);88#endif // CHECK_UNHANDLED_OOPS8990_thread = thread;91_handles = _thread->active_handles(); // save previous handle block & Java frame linkage9293// For the profiler, the last_Java_frame information in thread must always be in94// legal state. We have no last Java frame if last_Java_sp == NULL so95// the valid transition is to clear _last_Java_sp and then reset the rest of96// the (platform specific) state.9798_anchor.copy(_thread->frame_anchor());99_thread->frame_anchor()->clear();100101debug_only(_thread->inc_java_call_counter());102_thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage103104assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL");105106// clear any pending exception in thread (native calls start with no exception pending)107if(clear_pending_exception) {108_thread->clear_pending_exception();109}110111MACOS_AARCH64_ONLY(_thread->enable_wx(WXExec));112}113114115JavaCallWrapper::~JavaCallWrapper() {116assert(_thread == JavaThread::current(), "must still be the same thread");117118MACOS_AARCH64_ONLY(_thread->enable_wx(WXWrite));119120// restore previous handle block & Java frame linkage121JNIHandleBlock *_old_handles = _thread->active_handles();122_thread->set_active_handles(_handles);123124_thread->frame_anchor()->zap();125126debug_only(_thread->dec_java_call_counter());127128// Old thread-local info. has been restored. We are not back in the VM.129ThreadStateTransition::transition_from_java(_thread, _thread_in_vm);130131// State has been restored now make the anchor frame visible for the profiler.132// Do this after the transition because this allows us to put an assert133// the Java->vm transition which checks to see that stack is not walkable134// on sparc/ia64 which will catch violations of the reseting of last_Java_frame135// invariants (i.e. _flags always cleared on return to Java)136137_thread->frame_anchor()->copy(&_anchor);138139// Release handles after we are marked as being inside the VM again, since this140// operation might block141JNIHandleBlock::release_block(_old_handles, _thread);142143if (_thread->has_pending_exception() && _thread->has_last_Java_frame()) {144// If we get here, the Java code threw an exception that unwound a frame.145// It could be that the new frame anchor has not passed through the required146// StackWatermark barriers. Therefore, we process any such deferred unwind147// requests here.148StackWatermarkSet::after_unwind(_thread);149}150}151152153void JavaCallWrapper::oops_do(OopClosure* f) {154f->do_oop((oop*)&_receiver);155handles()->oops_do(f);156}157158159// Helper methods160static BasicType runtime_type_from(JavaValue* result) {161switch (result->get_type()) {162case T_BOOLEAN: // fall through163case T_CHAR : // fall through164case T_SHORT : // fall through165case T_INT : // fall through166#ifndef _LP64167case T_OBJECT : // fall through168case T_ARRAY : // fall through169#endif170case T_BYTE : // fall through171case T_VOID : return T_INT;172case T_LONG : return T_LONG;173case T_FLOAT : return T_FLOAT;174case T_DOUBLE : return T_DOUBLE;175#ifdef _LP64176case T_ARRAY : // fall through177case T_OBJECT: return T_OBJECT;178#endif179default:180ShouldNotReachHere();181return T_ILLEGAL;182}183}184185// ============ Virtual calls ============186187void JavaCalls::call_virtual(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {188CallInfo callinfo;189Handle receiver = args->receiver();190Klass* recvrKlass = receiver.is_null() ? (Klass*)NULL : receiver->klass();191LinkInfo link_info(spec_klass, name, signature);192LinkResolver::resolve_virtual_call(193callinfo, receiver, recvrKlass, link_info, true, CHECK);194methodHandle method(THREAD, callinfo.selected_method());195assert(method.not_null(), "should have thrown exception");196197// Invoke the method198JavaCalls::call(result, method, args, CHECK);199}200201202void JavaCalls::call_virtual(JavaValue* result, Handle receiver, Klass* spec_klass, Symbol* name, Symbol* signature, TRAPS) {203JavaCallArguments args(receiver);204call_virtual(result, spec_klass, name, signature, &args, CHECK);205}206207208void JavaCalls::call_virtual(JavaValue* result, Handle receiver, Klass* spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {209JavaCallArguments args(receiver);210args.push_oop(arg1);211call_virtual(result, spec_klass, name, signature, &args, CHECK);212}213214215216void JavaCalls::call_virtual(JavaValue* result, Handle receiver, Klass* spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {217JavaCallArguments args(receiver);218args.push_oop(arg1);219args.push_oop(arg2);220call_virtual(result, spec_klass, name, signature, &args, CHECK);221}222223224// ============ Special calls ============225226void JavaCalls::call_special(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {227CallInfo callinfo;228LinkInfo link_info(klass, name, signature);229LinkResolver::resolve_special_call(callinfo, args->receiver(), link_info, CHECK);230methodHandle method(THREAD, callinfo.selected_method());231assert(method.not_null(), "should have thrown exception");232233// Invoke the method234JavaCalls::call(result, method, args, CHECK);235}236237238void JavaCalls::call_special(JavaValue* result, Handle receiver, Klass* klass, Symbol* name, Symbol* signature, TRAPS) {239JavaCallArguments args(receiver);240call_special(result, klass, name, signature, &args, CHECK);241}242243244void JavaCalls::call_special(JavaValue* result, Handle receiver, Klass* klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {245JavaCallArguments args(receiver);246args.push_oop(arg1);247call_special(result, klass, name, signature, &args, CHECK);248}249250251void JavaCalls::call_special(JavaValue* result, Handle receiver, Klass* klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {252JavaCallArguments args(receiver);253args.push_oop(arg1);254args.push_oop(arg2);255call_special(result, klass, name, signature, &args, CHECK);256}257258259// ============ Static calls ============260261void JavaCalls::call_static(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {262CallInfo callinfo;263LinkInfo link_info(klass, name, signature);264LinkResolver::resolve_static_call(callinfo, link_info, true, CHECK);265methodHandle method(THREAD, callinfo.selected_method());266assert(method.not_null(), "should have thrown exception");267268// Invoke the method269JavaCalls::call(result, method, args, CHECK);270}271272273void JavaCalls::call_static(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, TRAPS) {274JavaCallArguments args;275call_static(result, klass, name, signature, &args, CHECK);276}277278279void JavaCalls::call_static(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {280JavaCallArguments args(arg1);281call_static(result, klass, name, signature, &args, CHECK);282}283284285void JavaCalls::call_static(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {286JavaCallArguments args;287args.push_oop(arg1);288args.push_oop(arg2);289call_static(result, klass, name, signature, &args, CHECK);290}291292293void JavaCalls::call_static(JavaValue* result, Klass* klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, Handle arg3, TRAPS) {294JavaCallArguments args;295args.push_oop(arg1);296args.push_oop(arg2);297args.push_oop(arg3);298call_static(result, klass, name, signature, &args, CHECK);299}300301// ============ allocate and initialize new object instance ============302303Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, JavaCallArguments* args, TRAPS) {304klass->initialize(CHECK_NH); // Quick no-op if already initialized.305Handle obj = klass->allocate_instance_handle(CHECK_NH);306JavaValue void_result(T_VOID);307args->set_receiver(obj); // inserts <obj> as the first argument.308JavaCalls::call_special(&void_result, klass,309vmSymbols::object_initializer_name(),310constructor_signature, args, CHECK_NH);311// Already returned a Null Handle if any exception is pending.312return obj;313}314315Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, TRAPS) {316JavaCallArguments args;317return JavaCalls::construct_new_instance(klass, constructor_signature, &args, THREAD);318}319320Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, Handle arg1, TRAPS) {321JavaCallArguments args;322args.push_oop(arg1);323return JavaCalls::construct_new_instance(klass, constructor_signature, &args, THREAD);324}325326Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, Handle arg1, Handle arg2, TRAPS) {327JavaCallArguments args;328args.push_oop(arg1);329args.push_oop(arg2);330return JavaCalls::construct_new_instance(klass, constructor_signature, &args, THREAD);331}332333// -------------------------------------------------334// Implementation of JavaCalls (low level)335336337void JavaCalls::call(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS) {338// Check if we need to wrap a potential OS exception handler around thread.339// This is used for e.g. Win32 structured exception handlers.340// Need to wrap each and every time, since there might be native code down the341// stack that has installed its own exception handlers.342os::os_exception_wrapper(call_helper, result, method, args, THREAD);343}344345void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS) {346347JavaThread* thread = THREAD;348assert(method.not_null(), "must have a method to call");349assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");350assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");351352// Verify the arguments353if (JVMCI_ONLY(args->alternative_target().is_null() &&) (DEBUG_ONLY(true ||) CheckJNICalls)) {354args->verify(method, result->get_type());355}356// Ignore call if method is empty357if (JVMCI_ONLY(args->alternative_target().is_null() &&) method->is_empty_method()) {358assert(result->get_type() == T_VOID, "an empty method must return a void value");359return;360}361362#ifdef ASSERT363{ InstanceKlass* holder = method->method_holder();364// A klass might not be initialized since JavaCall's might be used during the executing of365// the <clinit>. For example, a Thread.start might start executing on an object that is366// not fully initialized! (bad Java programming style)367assert(holder->is_linked(), "rewriting must have taken place");368}369#endif370371CompilationPolicy::compile_if_required(method, CHECK);372373// Since the call stub sets up like the interpreter we call the from_interpreted_entry374// so we can go compiled via a i2c. Otherwise initial entry method will always375// run interpreted.376address entry_point = method->from_interpreted_entry();377if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {378entry_point = method->interpreter_entry();379}380381// Figure out if the result value is an oop or not (Note: This is a different value382// than result_type. result_type will be T_INT of oops. (it is about size)383BasicType result_type = runtime_type_from(result);384bool oop_result_flag = is_reference_type(result->get_type());385386// Find receiver387Handle receiver = (!method->is_static()) ? args->receiver() : Handle();388389// When we reenter Java, we need to reenable the reserved/yellow zone which390// might already be disabled when we are in VM.391thread->stack_overflow_state()->reguard_stack_if_needed();392393// Check that there are shadow pages available before changing thread state394// to Java. Calculate current_stack_pointer here to make sure395// stack_shadow_pages_available() and bang_stack_shadow_pages() use the same sp.396address sp = os::current_stack_pointer();397if (!os::stack_shadow_pages_available(THREAD, method, sp)) {398// Throw stack overflow exception with preinitialized exception.399Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);400return;401} else {402// Touch pages checked if the OS needs them to be touched to be mapped.403os::map_stack_shadow_pages(sp);404}405406// do call407{ JavaCallWrapper link(method, receiver, result, CHECK);408{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner409410// NOTE: if we move the computation of the result_val_address inside411// the call to call_stub, the optimizer produces wrong code.412intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());413intptr_t* parameter_address = args->parameters();414#if INCLUDE_JVMCI415// Gets the alternative target (if any) that should be called416Handle alternative_target = args->alternative_target();417if (!alternative_target.is_null()) {418// Must extract verified entry point from HotSpotNmethod after VM to Java419// transition in JavaCallWrapper constructor so that it is safe with420// respect to nmethod sweeping.421address verified_entry_point = (address) HotSpotJVMCI::InstalledCode::entryPoint(NULL, alternative_target());422if (verified_entry_point != NULL) {423thread->set_jvmci_alternate_call_target(verified_entry_point);424entry_point = method->adapter()->get_i2c_entry();425}426}427#endif428StubRoutines::call_stub()(429(address)&link,430// (intptr_t*)&(result->_value), // see NOTE above (compiler problem)431result_val_address, // see NOTE above (compiler problem)432result_type,433method(),434entry_point,435parameter_address,436args->size_of_parameters(),437CHECK438);439440result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)441// Preserve oop return value across possible gc points442if (oop_result_flag) {443thread->set_vm_result(result->get_oop());444}445}446} // Exit JavaCallWrapper (can block - potential return oop must be preserved)447448// Check if a thread stop or suspend should be executed449// The following assert was not realistic. Thread.stop can set that bit at any moment.450//assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed");451452// Restore possible oop return453if (oop_result_flag) {454result->set_oop(thread->vm_result());455thread->set_vm_result(NULL);456}457}458459460//--------------------------------------------------------------------------------------461// Implementation of JavaCallArguments462463inline bool is_value_state_indirect_oop(uint state) {464assert(state != JavaCallArguments::value_state_oop,465"Checking for handles after removal");466assert(state < JavaCallArguments::value_state_limit,467"Invalid value state %u", state);468return state != JavaCallArguments::value_state_primitive;469}470471inline oop resolve_indirect_oop(intptr_t value, uint state) {472switch (state) {473case JavaCallArguments::value_state_handle:474{475oop* ptr = reinterpret_cast<oop*>(value);476return Handle::raw_resolve(ptr);477}478479case JavaCallArguments::value_state_jobject:480{481jobject obj = reinterpret_cast<jobject>(value);482return JNIHandles::resolve(obj);483}484485default:486ShouldNotReachHere();487return NULL;488}489}490491intptr_t* JavaCallArguments::parameters() {492// First convert all handles to oops493for(int i = 0; i < _size; i++) {494uint state = _value_state[i];495assert(state != value_state_oop, "Multiple handle conversions");496if (is_value_state_indirect_oop(state)) {497oop obj = resolve_indirect_oop(_value[i], state);498_value[i] = cast_from_oop<intptr_t>(obj);499_value_state[i] = value_state_oop;500}501}502// Return argument vector503return _value;504}505506507class SignatureChekker : public SignatureIterator {508private:509int _pos;510BasicType _return_type;511u_char* _value_state;512intptr_t* _value;513514public:515SignatureChekker(Symbol* signature,516BasicType return_type,517bool is_static,518u_char* value_state,519intptr_t* value) :520SignatureIterator(signature),521_pos(0),522_return_type(return_type),523_value_state(value_state),524_value(value)525{526if (!is_static) {527check_value(true); // Receiver must be an oop528}529do_parameters_on(this);530check_return_type(return_type);531}532533private:534void check_value(bool is_reference) {535uint state = _value_state[_pos++];536if (is_reference) {537guarantee(is_value_state_indirect_oop(state),538"signature does not match pushed arguments: %u at %d",539state, _pos - 1);540} else {541guarantee(state == JavaCallArguments::value_state_primitive,542"signature does not match pushed arguments: %u at %d",543state, _pos - 1);544}545}546547void check_return_type(BasicType t) {548guarantee(t == _return_type, "return type does not match");549}550551void check_single_word() {552check_value(false);553}554555void check_double_word() {556check_value(false);557check_value(false);558}559560void check_reference() {561intptr_t v = _value[_pos];562if (v != 0) {563// v is a "handle" referring to an oop, cast to integral type.564// There shouldn't be any handles in very low memory.565guarantee((size_t)v >= (size_t)os::vm_page_size(),566"Bad JNI oop argument %d: " PTR_FORMAT, _pos, v);567// Verify the pointee.568oop vv = resolve_indirect_oop(v, _value_state[_pos]);569guarantee(oopDesc::is_oop_or_null(vv, true),570"Bad JNI oop argument %d: " PTR_FORMAT " -> " PTR_FORMAT,571_pos, v, p2i(vv));572}573574check_value(true); // Verify value state.575}576577friend class SignatureIterator; // so do_parameters_on can call do_type578void do_type(BasicType type) {579switch (type) {580case T_BYTE:581case T_BOOLEAN:582case T_CHAR:583case T_SHORT:584case T_INT:585case T_FLOAT: // this one also586check_single_word(); break;587case T_LONG:588case T_DOUBLE:589check_double_word(); break;590case T_ARRAY:591case T_OBJECT:592check_reference(); break;593default:594ShouldNotReachHere();595}596}597};598599600void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {601guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");602603// Treat T_OBJECT and T_ARRAY as the same604if (is_reference_type(return_type)) return_type = T_OBJECT;605606// Check that oop information is correct607Symbol* signature = method->signature();608609SignatureChekker sc(signature,610return_type,611method->is_static(),612_value_state,613_value);614}615616617