Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/runtime/javaCalls.cpp
48785 views
/*1* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/systemDictionary.hpp"26#include "classfile/vmSymbols.hpp"27#include "code/nmethod.hpp"28#include "compiler/compileBroker.hpp"29#include "interpreter/interpreter.hpp"30#include "interpreter/linkResolver.hpp"31#include "memory/universe.inline.hpp"32#include "oops/oop.inline.hpp"33#include "prims/jniCheck.hpp"34#include "runtime/compilationPolicy.hpp"35#include "runtime/handles.inline.hpp"36#include "runtime/interfaceSupport.hpp"37#include "runtime/javaCalls.hpp"38#include "runtime/mutexLocker.hpp"39#include "runtime/signature.hpp"40#include "runtime/stubRoutines.hpp"41#include "runtime/thread.inline.hpp"4243// -----------------------------------------------------44// Implementation of JavaCallWrapper4546JavaCallWrapper::JavaCallWrapper(methodHandle callee_method, Handle receiver, JavaValue* result, TRAPS) {47JavaThread* thread = (JavaThread *)THREAD;48bool clear_pending_exception = true;4950guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");51assert(!thread->owns_locks(), "must release all locks when leaving VM");52guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler");53_result = result;5455// Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub,56// since it can potentially block.57JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);5859// After this, we are official in JavaCode. This needs to be done before we change any of the thread local60// info, since we cannot find oops before the new information is set up completely.61ThreadStateTransition::transition(thread, _thread_in_vm, _thread_in_Java);6263// Make sure that we handle asynchronous stops and suspends _before_ we clear all thread state64// in JavaCallWrapper::JavaCallWrapper(). This way, we can decide if we need to do any pd actions65// to prepare for stop/suspend (flush register windows on sparcs, cache sp, or other state).66if (thread->has_special_runtime_exit_condition()) {67thread->handle_special_runtime_exit_condition();68if (HAS_PENDING_EXCEPTION) {69clear_pending_exception = false;70}71}727374// Make sure to set the oop's after the thread transition - since we can block there. No one is GC'ing75// the JavaCallWrapper before the entry frame is on the stack.76_callee_method = callee_method();77_receiver = receiver();7879#ifdef CHECK_UNHANDLED_OOPS80THREAD->allow_unhandled_oop(&_receiver);81#endif // CHECK_UNHANDLED_OOPS8283_thread = (JavaThread *)thread;84_handles = _thread->active_handles(); // save previous handle block & Java frame linkage8586// For the profiler, the last_Java_frame information in thread must always be in87// legal state. We have no last Java frame if last_Java_sp == NULL so88// the valid transition is to clear _last_Java_sp and then reset the rest of89// the (platform specific) state.9091_anchor.copy(_thread->frame_anchor());92_thread->frame_anchor()->clear();9394debug_only(_thread->inc_java_call_counter());95_thread->set_active_handles(new_handles); // install new handle block and reset Java frame linkage9697assert (_thread->thread_state() != _thread_in_native, "cannot set native pc to NULL");9899// clear any pending exception in thread (native calls start with no exception pending)100if(clear_pending_exception) {101_thread->clear_pending_exception();102}103104if (_anchor.last_Java_sp() == NULL) {105_thread->record_base_of_stack_pointer();106}107}108109110JavaCallWrapper::~JavaCallWrapper() {111assert(_thread == JavaThread::current(), "must still be the same thread");112113// restore previous handle block & Java frame linkage114JNIHandleBlock *_old_handles = _thread->active_handles();115_thread->set_active_handles(_handles);116117_thread->frame_anchor()->zap();118119debug_only(_thread->dec_java_call_counter());120121if (_anchor.last_Java_sp() == NULL) {122_thread->set_base_of_stack_pointer(NULL);123}124125126// Old thread-local info. has been restored. We are not back in the VM.127ThreadStateTransition::transition_from_java(_thread, _thread_in_vm);128129// State has been restored now make the anchor frame visible for the profiler.130// Do this after the transition because this allows us to put an assert131// the Java->vm transition which checks to see that stack is not walkable132// on sparc/ia64 which will catch violations of the reseting of last_Java_frame133// invariants (i.e. _flags always cleared on return to Java)134135_thread->frame_anchor()->copy(&_anchor);136137// Release handles after we are marked as being inside the VM again, since this138// operation might block139JNIHandleBlock::release_block(_old_handles, _thread);140}141142143void JavaCallWrapper::oops_do(OopClosure* f) {144f->do_oop((oop*)&_receiver);145handles()->oops_do(f);146}147148149// Helper methods150static BasicType runtime_type_from(JavaValue* result) {151switch (result->get_type()) {152case T_BOOLEAN: // fall through153case T_CHAR : // fall through154case T_SHORT : // fall through155case T_INT : // fall through156#ifndef _LP64157case T_OBJECT : // fall through158case T_ARRAY : // fall through159#endif160case T_BYTE : // fall through161case T_VOID : return T_INT;162case T_LONG : return T_LONG;163case T_FLOAT : return T_FLOAT;164case T_DOUBLE : return T_DOUBLE;165#ifdef _LP64166case T_ARRAY : // fall through167case T_OBJECT: return T_OBJECT;168#endif169}170ShouldNotReachHere();171return T_ILLEGAL;172}173174// ===== object constructor calls =====175176void JavaCalls::call_default_constructor(JavaThread* thread, methodHandle method, Handle receiver, TRAPS) {177assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor");178assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor");179180InstanceKlass* ik = method->method_holder();181if (ik->is_initialized() && ik->has_vanilla_constructor()) {182// safe to skip constructor call183} else {184static JavaValue result(T_VOID);185JavaCallArguments args(receiver);186call(&result, method, &args, CHECK);187}188}189190// ============ Virtual calls ============191192void JavaCalls::call_virtual(JavaValue* result, KlassHandle spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {193CallInfo callinfo;194Handle receiver = args->receiver();195KlassHandle recvrKlass(THREAD, receiver.is_null() ? (Klass*)NULL : receiver->klass());196LinkResolver::resolve_virtual_call(197callinfo, receiver, recvrKlass, spec_klass, name, signature,198KlassHandle(), false, true, CHECK);199methodHandle method = callinfo.selected_method();200assert(method.not_null(), "should have thrown exception");201202// Invoke the method203JavaCalls::call(result, method, args, CHECK);204}205206207void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, TRAPS) {208JavaCallArguments args(receiver); // One oop argument209call_virtual(result, spec_klass, name, signature, &args, CHECK);210}211212213void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {214JavaCallArguments args(receiver); // One oop argument215args.push_oop(arg1);216call_virtual(result, spec_klass, name, signature, &args, CHECK);217}218219220221void JavaCalls::call_virtual(JavaValue* result, Handle receiver, KlassHandle spec_klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {222JavaCallArguments args(receiver); // One oop argument223args.push_oop(arg1);224args.push_oop(arg2);225call_virtual(result, spec_klass, name, signature, &args, CHECK);226}227228229// ============ Special calls ============230231void JavaCalls::call_special(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {232CallInfo callinfo;233LinkResolver::resolve_special_call(callinfo, args->receiver(), klass, name, signature, KlassHandle(), false, CHECK);234methodHandle method = callinfo.selected_method();235assert(method.not_null(), "should have thrown exception");236237// Invoke the method238JavaCalls::call(result, method, args, CHECK);239}240241242void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {243JavaCallArguments args(receiver); // One oop argument244call_special(result, klass, name, signature, &args, CHECK);245}246247248void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {249JavaCallArguments args(receiver); // One oop argument250args.push_oop(arg1);251call_special(result, klass, name, signature, &args, CHECK);252}253254255void JavaCalls::call_special(JavaValue* result, Handle receiver, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {256JavaCallArguments args(receiver); // One oop argument257args.push_oop(arg1);258args.push_oop(arg2);259call_special(result, klass, name, signature, &args, CHECK);260}261262263// ============ Static calls ============264265void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {266CallInfo callinfo;267LinkResolver::resolve_static_call(callinfo, klass, name, signature, KlassHandle(), false, true, CHECK);268methodHandle method = callinfo.selected_method();269assert(method.not_null(), "should have thrown exception");270271// Invoke the method272JavaCalls::call(result, method, args, CHECK);273}274275276void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {277JavaCallArguments args; // No argument278call_static(result, klass, name, signature, &args, CHECK);279}280281282void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, TRAPS) {283JavaCallArguments args(arg1); // One oop argument284call_static(result, klass, name, signature, &args, CHECK);285}286287288void JavaCalls::call_static(JavaValue* result, KlassHandle klass, Symbol* name, Symbol* signature, Handle arg1, Handle arg2, TRAPS) {289JavaCallArguments args; // One oop argument290args.push_oop(arg1);291args.push_oop(arg2);292call_static(result, klass, name, signature, &args, CHECK);293}294295296// -------------------------------------------------297// Implementation of JavaCalls (low level)298299300void JavaCalls::call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS) {301// Check if we need to wrap a potential OS exception handler around thread302// This is used for e.g. Win32 structured exception handlers303assert(THREAD->is_Java_thread(), "only JavaThreads can make JavaCalls");304// Need to wrap each and everytime, since there might be native code down the305// stack that has installed its own exception handlers306os::os_exception_wrapper(call_helper, result, &method, args, THREAD);307}308309void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArguments* args, TRAPS) {310// During dumping, Java execution environment is not fully initialized. Also, Java execution311// may cause undesirable side-effects in the class metadata.312assert(!DumpSharedSpaces, "must not execute Java bytecodes when dumping");313314methodHandle method = *m;315JavaThread* thread = (JavaThread*)THREAD;316assert(thread->is_Java_thread(), "must be called by a java thread");317assert(method.not_null(), "must have a method to call");318assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");319assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");320321322CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)323324// Verify the arguments325326if (CheckJNICalls) {327args->verify(method, result->get_type());328}329else debug_only(args->verify(method, result->get_type()));330331// Ignore call if method is empty332if (method->is_empty_method()) {333assert(result->get_type() == T_VOID, "an empty method must return a void value");334return;335}336337338#ifdef ASSERT339{ InstanceKlass* holder = method->method_holder();340// A klass might not be initialized since JavaCall's might be used during the executing of341// the <clinit>. For example, a Thread.start might start executing on an object that is342// not fully initialized! (bad Java programming style)343assert(holder->is_linked(), "rewritting must have taken place");344}345#endif346347348assert(!thread->is_Compiler_thread(), "cannot compile from the compiler");349if (CompilationPolicy::must_be_compiled(method)) {350CompileBroker::compile_method(method, InvocationEntryBci,351CompilationPolicy::policy()->initial_compile_level(),352methodHandle(), 0, "must_be_compiled", CHECK);353}354355// Since the call stub sets up like the interpreter we call the from_interpreted_entry356// so we can go compiled via a i2c. Otherwise initial entry method will always357// run interpreted.358address entry_point = method->from_interpreted_entry();359if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {360entry_point = method->interpreter_entry();361}362363// Figure out if the result value is an oop or not (Note: This is a different value364// than result_type. result_type will be T_INT of oops. (it is about size)365BasicType result_type = runtime_type_from(result);366bool oop_result_flag = (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY);367368// NOTE: if we move the computation of the result_val_address inside369// the call to call_stub, the optimizer produces wrong code.370intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());371372// Find receiver373Handle receiver = (!method->is_static()) ? args->receiver() : Handle();374375// When we reenter Java, we need to reenable the yellow zone which376// might already be disabled when we are in VM.377if (thread->stack_yellow_zone_disabled()) {378thread->reguard_stack();379}380381// Check that there are shadow pages available before changing thread state382// to Java383if (!os::stack_shadow_pages_available(THREAD, method)) {384// Throw stack overflow exception with preinitialized exception.385Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);386return;387} else {388// Touch pages checked if the OS needs them to be touched to be mapped.389os::bang_stack_shadow_pages();390}391392// do call393{ JavaCallWrapper link(method, receiver, result, CHECK);394{ HandleMark hm(thread); // HandleMark used by HandleMarkCleaner395396StubRoutines::call_stub()(397(address)&link,398// (intptr_t*)&(result->_value), // see NOTE above (compiler problem)399result_val_address, // see NOTE above (compiler problem)400result_type,401method(),402entry_point,403args->parameters(),404args->size_of_parameters(),405CHECK406);407408result = link.result(); // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)409// Preserve oop return value across possible gc points410if (oop_result_flag) {411thread->set_vm_result((oop) result->get_jobject());412}413}414} // Exit JavaCallWrapper (can block - potential return oop must be preserved)415416// Check if a thread stop or suspend should be executed417// The following assert was not realistic. Thread.stop can set that bit at any moment.418//assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed");419420// Restore possible oop return421if (oop_result_flag) {422result->set_jobject((jobject)thread->vm_result());423thread->set_vm_result(NULL);424}425}426427428//--------------------------------------------------------------------------------------429// Implementation of JavaCallArguments430431inline bool is_value_state_indirect_oop(uint state) {432assert(state != JavaCallArguments::value_state_oop,433"Checking for handles after removal");434assert(state < JavaCallArguments::value_state_limit, "Invalid value state");435return state != JavaCallArguments::value_state_primitive;436}437438inline oop resolve_indirect_oop(intptr_t value, uint state) {439switch (state) {440case JavaCallArguments::value_state_handle:441{442oop* ptr = reinterpret_cast<oop*>(value);443return Handle::raw_resolve(ptr);444}445446case JavaCallArguments::value_state_jobject:447{448jobject obj = reinterpret_cast<jobject>(value);449return JNIHandles::resolve(obj);450}451452default:453ShouldNotReachHere();454return NULL;455}456}457458intptr_t* JavaCallArguments::parameters() {459// First convert all handles to oops460for(int i = 0; i < _size; i++) {461uint state = _value_state[i];462assert(state != value_state_oop, "Multiple handle conversions");463if (is_value_state_indirect_oop(state)) {464oop obj = resolve_indirect_oop(_value[i], state);465_value[i] = cast_from_oop<intptr_t>(obj);466_value_state[i] = value_state_oop;467}468}469// Return argument vector470return _value;471}472473474class SignatureChekker : public SignatureIterator {475private:476int _pos;477BasicType _return_type;478u_char* _value_state;479intptr_t* _value;480481public:482bool _is_return;483484SignatureChekker(Symbol* signature,485BasicType return_type,486bool is_static,487u_char* value_state,488intptr_t* value) :489SignatureIterator(signature),490_pos(0),491_return_type(return_type),492_value_state(value_state),493_value(value),494_is_return(false)495{496if (!is_static) {497check_value(true); // Receiver must be an oop498}499}500501void check_value(bool type) {502uint state = _value_state[_pos++];503if (type) {504guarantee(is_value_state_indirect_oop(state),505"signature does not match pushed arguments");506} else {507guarantee(state == JavaCallArguments::value_state_primitive,508"signature does not match pushed arguments");509}510}511512void check_doing_return(bool state) { _is_return = state; }513514void check_return_type(BasicType t) {515guarantee(_is_return && t == _return_type, "return type does not match");516}517518void check_int(BasicType t) {519if (_is_return) {520check_return_type(t);521return;522}523check_value(false);524}525526void check_double(BasicType t) { check_long(t); }527528void check_long(BasicType t) {529if (_is_return) {530check_return_type(t);531return;532}533534check_value(false);535check_value(false);536}537538void check_obj(BasicType t) {539if (_is_return) {540check_return_type(t);541return;542}543544intptr_t v = _value[_pos];545if (v != 0) {546// v is a "handle" referring to an oop, cast to integral type.547// There shouldn't be any handles in very low memory.548guarantee((size_t)v >= (size_t)os::vm_page_size(),549"Bad JNI oop argument");550// Verify the pointee.551oop vv = resolve_indirect_oop(v, _value_state[_pos]);552guarantee(vv->is_oop_or_null(true),553"Bad JNI oop argument");554}555556check_value(true); // Verify value state.557}558559void do_bool() { check_int(T_BOOLEAN); }560void do_char() { check_int(T_CHAR); }561void do_float() { check_int(T_FLOAT); }562void do_double() { check_double(T_DOUBLE); }563void do_byte() { check_int(T_BYTE); }564void do_short() { check_int(T_SHORT); }565void do_int() { check_int(T_INT); }566void do_long() { check_long(T_LONG); }567void do_void() { check_return_type(T_VOID); }568void do_object(int begin, int end) { check_obj(T_OBJECT); }569void do_array(int begin, int end) { check_obj(T_OBJECT); }570};571572573void JavaCallArguments::verify(methodHandle method, BasicType return_type) {574guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");575576// Treat T_OBJECT and T_ARRAY as the same577if (return_type == T_ARRAY) return_type = T_OBJECT;578579// Check that oop information is correct580Symbol* signature = method->signature();581582SignatureChekker sc(signature,583return_type,584method->is_static(),585_value_state,586_value);587sc.iterate_parameters();588sc.check_doing_return(true);589sc.iterate_returntype();590}591592593