Path: blob/jdk8u272-b10-aarch32-20201026/hotspot/src/share/vm/runtime/interfaceSupport.hpp
48773 views
/*1* Copyright (c) 1997, 2018, 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#ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP25#define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP2627#include "memory/gcLocker.hpp"28#include "runtime/handles.inline.hpp"29#include "runtime/mutexLocker.hpp"30#include "runtime/orderAccess.hpp"31#include "runtime/os.hpp"32#include "runtime/safepoint.hpp"33#include "runtime/thread.inline.hpp"34#include "runtime/vmThread.hpp"35#include "utilities/globalDefinitions.hpp"36#include "utilities/preserveException.hpp"37#include "utilities/top.hpp"3839// Wrapper for all entry points to the virtual machine.40// The HandleMarkCleaner is a faster version of HandleMark.41// It relies on the fact that there is a HandleMark further42// down the stack (in JavaCalls::call_helper), and just resets43// to the saved values in that HandleMark.4445class HandleMarkCleaner: public StackObj {46private:47Thread* _thread;48public:49HandleMarkCleaner(Thread* thread) {50_thread = thread;51_thread->last_handle_mark()->push();52}53~HandleMarkCleaner() {54_thread->last_handle_mark()->pop_and_restore();55}5657private:58inline void* operator new(size_t size, void* ptr) throw() {59return ptr;60}61};6263// InterfaceSupport provides functionality used by the VM_LEAF_BASE and64// VM_ENTRY_BASE macros. These macros are used to guard entry points into65// the VM and perform checks upon leave of the VM.666768class InterfaceSupport: AllStatic {69# ifdef ASSERT70public:71static long _scavenge_alot_counter;72static long _fullgc_alot_counter;73static long _number_of_calls;74static long _fullgc_alot_invocation;7576// tracing77static void trace(const char* result_type, const char* header);7879// Helper methods used to implement +ScavengeALot and +FullGCALot80static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }81static void gc_alot();8283static void walk_stack_from(vframe* start_vf);84static void walk_stack();8586# ifdef ENABLE_ZAP_DEAD_LOCALS87static void zap_dead_locals_old();88# endif8990static void zombieAll();91static void unlinkSymbols();92static void deoptimizeAll();93static void stress_derived_pointers();94static void verify_stack();95static void verify_last_frame();96# endif9798public:99// OS dependent stuff100#ifdef TARGET_OS_FAMILY_linux101# include "interfaceSupport_linux.hpp"102#endif103#ifdef TARGET_OS_FAMILY_solaris104# include "interfaceSupport_solaris.hpp"105#endif106#ifdef TARGET_OS_FAMILY_windows107# include "interfaceSupport_windows.hpp"108#endif109#ifdef TARGET_OS_FAMILY_aix110# include "interfaceSupport_aix.hpp"111#endif112#ifdef TARGET_OS_FAMILY_bsd113# include "interfaceSupport_bsd.hpp"114#endif115116};117118119// Basic class for all thread transition classes.120121class ThreadStateTransition : public StackObj {122protected:123JavaThread* _thread;124public:125ThreadStateTransition(JavaThread *thread) {126_thread = thread;127assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");128}129130// Change threadstate in a manner, so safepoint can detect changes.131// Time-critical: called on exit from every runtime routine132static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {133assert(from != _thread_in_Java, "use transition_from_java");134assert(from != _thread_in_native, "use transition_from_native");135assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");136assert(thread->thread_state() == from, "coming from wrong thread state");137// Change to transition state (assumes total store ordering! -Urs)138thread->set_thread_state((JavaThreadState)(from + 1));139140// Make sure new state is seen by VM thread141if (os::is_MP()) {142if (UseMembar) {143// Force a fence between the write above and read below144OrderAccess::fence();145} else {146// store to serialize page so VM thread can do pseudo remote membar147os::write_memory_serialize_page(thread);148}149}150151if (SafepointSynchronize::do_call_back()) {152SafepointSynchronize::block(thread);153}154thread->set_thread_state(to);155156CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)157}158159// transition_and_fence must be used on any thread state transition160// where there might not be a Java call stub on the stack, in161// particular on Windows where the Structured Exception Handler is162// set up in the call stub. os::write_memory_serialize_page() can163// fault and we can't recover from it on Windows without a SEH in164// place.165static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {166assert(thread->thread_state() == from, "coming from wrong thread state");167assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");168// Change to transition state (assumes total store ordering! -Urs)169thread->set_thread_state((JavaThreadState)(from + 1));170171// Make sure new state is seen by VM thread172if (os::is_MP()) {173if (UseMembar) {174// Force a fence between the write above and read below175OrderAccess::fence();176} else {177// Must use this rather than serialization page in particular on Windows178InterfaceSupport::serialize_memory(thread);179}180}181182if (SafepointSynchronize::do_call_back()) {183SafepointSynchronize::block(thread);184}185thread->set_thread_state(to);186187CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)188}189190// Same as above, but assumes from = _thread_in_Java. This is simpler, since we191// never block on entry to the VM. This will break the code, since e.g. preserve arguments192// have not been setup.193static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {194assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");195thread->set_thread_state(to);196}197198static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {199assert((to & 1) == 0, "odd numbers are transitions states");200assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");201// Change to transition state (assumes total store ordering! -Urs)202thread->set_thread_state(_thread_in_native_trans);203204// Make sure new state is seen by GC thread205if (os::is_MP()) {206if (UseMembar) {207// Force a fence between the write above and read below208OrderAccess::fence();209} else {210// Must use this rather than serialization page in particular on Windows211InterfaceSupport::serialize_memory(thread);212}213}214215// We never install asynchronous exceptions when coming (back) in216// to the runtime from native code because the runtime is not set217// up to handle exceptions floating around at arbitrary points.218if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {219JavaThread::check_safepoint_and_suspend_for_native_trans(thread);220221// Clear unhandled oops anywhere where we could block, even if we don't.222CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)223}224225thread->set_thread_state(to);226}227protected:228void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }229void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }230void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }231void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }232};233234235class ThreadInVMfromJava : public ThreadStateTransition {236public:237ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {238trans_from_java(_thread_in_vm);239}240~ThreadInVMfromJava() {241trans(_thread_in_vm, _thread_in_Java);242// Check for pending. async. exceptions or suspends.243if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();244}245};246247248class ThreadInVMfromUnknown {249private:250JavaThread* _thread;251public:252ThreadInVMfromUnknown() : _thread(NULL) {253Thread* t = Thread::current();254if (t->is_Java_thread()) {255JavaThread* t2 = (JavaThread*) t;256if (t2->thread_state() == _thread_in_native) {257_thread = t2;258ThreadStateTransition::transition_from_native(t2, _thread_in_vm);259// Used to have a HandleMarkCleaner but that is dangerous as260// it could free a handle in our (indirect, nested) caller.261// We expect any handles will be short lived and figure we262// don't need an actual HandleMark.263}264}265}266~ThreadInVMfromUnknown() {267if (_thread) {268ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);269}270}271};272273274class ThreadInVMfromNative : public ThreadStateTransition {275public:276ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {277trans_from_native(_thread_in_vm);278}279~ThreadInVMfromNative() {280trans_and_fence(_thread_in_vm, _thread_in_native);281}282};283284285class ThreadToNativeFromVM : public ThreadStateTransition {286public:287ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {288// We are leaving the VM at this point and going directly to native code.289// Block, if we are in the middle of a safepoint synchronization.290assert(!thread->owns_locks(), "must release all locks when leaving VM");291thread->frame_anchor()->make_walkable(thread);292trans_and_fence(_thread_in_vm, _thread_in_native);293// Check for pending. async. exceptions or suspends.294if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);295}296297~ThreadToNativeFromVM() {298trans_from_native(_thread_in_vm);299// We don't need to clear_walkable because it will happen automagically when we return to java300}301};302303304class ThreadBlockInVM : public ThreadStateTransition {305public:306ThreadBlockInVM(JavaThread *thread)307: ThreadStateTransition(thread) {308// Once we are blocked vm expects stack to be walkable309thread->frame_anchor()->make_walkable(thread);310trans_and_fence(_thread_in_vm, _thread_blocked);311}312~ThreadBlockInVM() {313trans_and_fence(_thread_blocked, _thread_in_vm);314// We don't need to clear_walkable because it will happen automagically when we return to java315}316};317318319// This special transition class is only used to prevent asynchronous exceptions320// from being installed on vm exit in situations where we can't tolerate them.321// See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.322class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {323public:324ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {325trans_from_java(_thread_in_vm);326}327~ThreadInVMfromJavaNoAsyncException() {328trans(_thread_in_vm, _thread_in_Java);329// NOTE: We do not check for pending. async. exceptions.330// If we did and moved the pending async exception over into the331// pending exception field, we would need to deopt (currently C2332// only). However, to do so would require that we transition back333// to the _thread_in_vm state. Instead we postpone the handling of334// the async exception.335336// Check for pending. suspends only.337if (_thread->has_special_runtime_exit_condition())338_thread->handle_special_runtime_exit_condition(false);339}340};341342// Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.343// Can be used to verify properties on enter/exit of the VM.344345#ifdef ASSERT346class VMEntryWrapper {347public:348VMEntryWrapper() {349if (VerifyLastFrame) {350InterfaceSupport::verify_last_frame();351}352}353354~VMEntryWrapper() {355InterfaceSupport::check_gc_alot();356if (WalkStackALot) {357InterfaceSupport::walk_stack();358}359#ifdef ENABLE_ZAP_DEAD_LOCALS360if (ZapDeadLocalsOld) {361InterfaceSupport::zap_dead_locals_old();362}363#endif364#ifdef COMPILER2365// This option is not used by Compiler 1366if (StressDerivedPointers) {367InterfaceSupport::stress_derived_pointers();368}369#endif370if (DeoptimizeALot || DeoptimizeRandom) {371InterfaceSupport::deoptimizeAll();372}373if (ZombieALot) {374InterfaceSupport::zombieAll();375}376if (UnlinkSymbolsALot) {377InterfaceSupport::unlinkSymbols();378}379// do verification AFTER potential deoptimization380if (VerifyStack) {381InterfaceSupport::verify_stack();382}383384}385};386387388class VMNativeEntryWrapper {389public:390VMNativeEntryWrapper() {391if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();392}393394~VMNativeEntryWrapper() {395if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();396}397};398399#endif400401402// VM-internal runtime interface support403404#ifdef ASSERT405406class RuntimeHistogramElement : public HistogramElement {407public:408RuntimeHistogramElement(const char* name);409};410411#define TRACE_CALL(result_type, header) \412InterfaceSupport::_number_of_calls++; \413if (TraceRuntimeCalls) \414InterfaceSupport::trace(#result_type, #header); \415if (CountRuntimeCalls) { \416static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \417if (e != NULL) e->increment_count(); \418}419#else420#define TRACE_CALL(result_type, header) \421/* do nothing */422#endif423424425// LEAF routines do not lock, GC or throw exceptions426427#define VM_LEAF_BASE(result_type, header) \428TRACE_CALL(result_type, header) \429debug_only(NoHandleMark __hm;) \430os::verify_stack_alignment(); \431/* begin of body */432433#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \434TRACE_CALL(result_type, header) \435debug_only(ResetNoHandleMark __rnhm;) \436HandleMarkCleaner __hm(thread); \437Thread* THREAD = thread; \438os::verify_stack_alignment(); \439/* begin of body */440441442// ENTRY routines may lock, GC and throw exceptions443444#define VM_ENTRY_BASE(result_type, header, thread) \445TRACE_CALL(result_type, header) \446HandleMarkCleaner __hm(thread); \447Thread* THREAD = thread; \448os::verify_stack_alignment(); \449/* begin of body */450451452// QUICK_ENTRY routines behave like ENTRY but without a handle mark453454#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \455TRACE_CALL(result_type, header) \456debug_only(NoHandleMark __hm;) \457Thread* THREAD = thread; \458os::verify_stack_alignment(); \459/* begin of body */460461462// Definitions for IRT (Interpreter Runtime)463// (thread is an argument passed in to all these routines)464465#define IRT_ENTRY(result_type, header) \466result_type header { \467ThreadInVMfromJava __tiv(thread); \468VM_ENTRY_BASE(result_type, header, thread) \469debug_only(VMEntryWrapper __vew;)470471472#define IRT_LEAF(result_type, header) \473result_type header { \474VM_LEAF_BASE(result_type, header) \475debug_only(No_Safepoint_Verifier __nspv(true);)476477478#define IRT_ENTRY_NO_ASYNC(result_type, header) \479result_type header { \480ThreadInVMfromJavaNoAsyncException __tiv(thread); \481VM_ENTRY_BASE(result_type, header, thread) \482debug_only(VMEntryWrapper __vew;)483484#define IRT_END }485486487// Definitions for JRT (Java (Compiler/Shared) Runtime)488489#define JRT_ENTRY(result_type, header) \490result_type header { \491ThreadInVMfromJava __tiv(thread); \492VM_ENTRY_BASE(result_type, header, thread) \493debug_only(VMEntryWrapper __vew;)494495496#define JRT_LEAF(result_type, header) \497result_type header { \498VM_LEAF_BASE(result_type, header) \499debug_only(JRT_Leaf_Verifier __jlv;)500501502#define JRT_ENTRY_NO_ASYNC(result_type, header) \503result_type header { \504ThreadInVMfromJavaNoAsyncException __tiv(thread); \505VM_ENTRY_BASE(result_type, header, thread) \506debug_only(VMEntryWrapper __vew;)507508// Same as JRT Entry but allows for return value after the safepoint509// to get back into Java from the VM510#define JRT_BLOCK_ENTRY(result_type, header) \511result_type header { \512TRACE_CALL(result_type, header) \513HandleMarkCleaner __hm(thread);514515#define JRT_BLOCK \516{ \517ThreadInVMfromJava __tiv(thread); \518Thread* THREAD = thread; \519debug_only(VMEntryWrapper __vew;)520521#define JRT_BLOCK_END }522523#define JRT_END }524525// Definitions for JNI526527#define JNI_ENTRY(result_type, header) \528JNI_ENTRY_NO_PRESERVE(result_type, header) \529WeakPreserveExceptionMark __wem(thread);530531#define JNI_ENTRY_NO_PRESERVE(result_type, header) \532extern "C" { \533result_type JNICALL header { \534JavaThread* thread=JavaThread::thread_from_jni_environment(env); \535assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \536ThreadInVMfromNative __tiv(thread); \537debug_only(VMNativeEntryWrapper __vew;) \538VM_ENTRY_BASE(result_type, header, thread)539540541// Ensure that the VMNativeEntryWrapper constructor, which can cause542// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).543#define JNI_QUICK_ENTRY(result_type, header) \544extern "C" { \545result_type JNICALL header { \546JavaThread* thread=JavaThread::thread_from_jni_environment(env); \547assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \548ThreadInVMfromNative __tiv(thread); \549debug_only(VMNativeEntryWrapper __vew;) \550VM_QUICK_ENTRY_BASE(result_type, header, thread)551552553#define JNI_LEAF(result_type, header) \554extern "C" { \555result_type JNICALL header { \556JavaThread* thread=JavaThread::thread_from_jni_environment(env); \557assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \558VM_LEAF_BASE(result_type, header)559560561// Close the routine and the extern "C"562#define JNI_END } }563564565566// Definitions for JVM567568#define JVM_ENTRY(result_type, header) \569extern "C" { \570result_type JNICALL header { \571JavaThread* thread=JavaThread::thread_from_jni_environment(env); \572ThreadInVMfromNative __tiv(thread); \573debug_only(VMNativeEntryWrapper __vew;) \574VM_ENTRY_BASE(result_type, header, thread)575576577#define JVM_ENTRY_NO_ENV(result_type, header) \578extern "C" { \579result_type JNICALL header { \580JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); \581ThreadInVMfromNative __tiv(thread); \582debug_only(VMNativeEntryWrapper __vew;) \583VM_ENTRY_BASE(result_type, header, thread)584585586#define JVM_QUICK_ENTRY(result_type, header) \587extern "C" { \588result_type JNICALL header { \589JavaThread* thread=JavaThread::thread_from_jni_environment(env); \590ThreadInVMfromNative __tiv(thread); \591debug_only(VMNativeEntryWrapper __vew;) \592VM_QUICK_ENTRY_BASE(result_type, header, thread)593594595#define JVM_LEAF(result_type, header) \596extern "C" { \597result_type JNICALL header { \598VM_Exit::block_if_vm_exited(); \599VM_LEAF_BASE(result_type, header)600601602#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \603{ { \604JavaThread* thread=JavaThread::thread_from_jni_environment(env); \605ThreadInVMfromNative __tiv(thread); \606debug_only(VMNativeEntryWrapper __vew;) \607VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)608609610#define JVM_END } }611612#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP613614615