Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/runtime/interfaceSupport.hpp
32285 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/threadWXSetters.inline.hpp"35#include "runtime/vmThread.hpp"36#include "utilities/globalDefinitions.hpp"37#include "utilities/preserveException.hpp"38#include "utilities/top.hpp"3940// Wrapper for all entry points to the virtual machine.41// The HandleMarkCleaner is a faster version of HandleMark.42// It relies on the fact that there is a HandleMark further43// down the stack (in JavaCalls::call_helper), and just resets44// to the saved values in that HandleMark.4546class HandleMarkCleaner: public StackObj {47private:48Thread* _thread;49public:50HandleMarkCleaner(Thread* thread) {51_thread = thread;52_thread->last_handle_mark()->push();53}54~HandleMarkCleaner() {55_thread->last_handle_mark()->pop_and_restore();56}5758private:59inline void* operator new(size_t size, void* ptr) throw() {60return ptr;61}62};6364// InterfaceSupport provides functionality used by the VM_LEAF_BASE and65// VM_ENTRY_BASE macros. These macros are used to guard entry points into66// the VM and perform checks upon leave of the VM.676869class InterfaceSupport: AllStatic {70# ifdef ASSERT71public:72static long _scavenge_alot_counter;73static long _fullgc_alot_counter;74static long _number_of_calls;75static long _fullgc_alot_invocation;7677// tracing78static void trace(const char* result_type, const char* header);7980// Helper methods used to implement +ScavengeALot and +FullGCALot81static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }82static void gc_alot();8384static void walk_stack_from(vframe* start_vf);85static void walk_stack();8687# ifdef ENABLE_ZAP_DEAD_LOCALS88static void zap_dead_locals_old();89# endif9091static void zombieAll();92static void unlinkSymbols();93static void deoptimizeAll();94static void stress_derived_pointers();95static void verify_stack();96static void verify_last_frame();97# endif9899public:100// OS dependent stuff101#ifdef TARGET_OS_FAMILY_linux102# include "interfaceSupport_linux.hpp"103#endif104#ifdef TARGET_OS_FAMILY_solaris105# include "interfaceSupport_solaris.hpp"106#endif107#ifdef TARGET_OS_FAMILY_windows108# include "interfaceSupport_windows.hpp"109#endif110#ifdef TARGET_OS_FAMILY_aix111# include "interfaceSupport_aix.hpp"112#endif113#ifdef TARGET_OS_FAMILY_bsd114# include "interfaceSupport_bsd.hpp"115#endif116117};118119120// Basic class for all thread transition classes.121122class ThreadStateTransition : public StackObj {123protected:124JavaThread* _thread;125public:126ThreadStateTransition(JavaThread *thread) {127_thread = thread;128assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");129}130131// Change threadstate in a manner, so safepoint can detect changes.132// Time-critical: called on exit from every runtime routine133static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {134assert(from != _thread_in_Java, "use transition_from_java");135assert(from != _thread_in_native, "use transition_from_native");136assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");137assert(thread->thread_state() == from, "coming from wrong thread state");138// Change to transition state (assumes total store ordering! -Urs)139thread->set_thread_state((JavaThreadState)(from + 1));140141// Make sure new state is seen by VM thread142if (os::is_MP()) {143if (UseMembar) {144// Force a fence between the write above and read below145OrderAccess::fence();146} else {147// store to serialize page so VM thread can do pseudo remote membar148os::write_memory_serialize_page(thread);149}150}151152if (SafepointSynchronize::do_call_back()) {153SafepointSynchronize::block(thread);154}155thread->set_thread_state(to);156157CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)158}159160// transition_and_fence must be used on any thread state transition161// where there might not be a Java call stub on the stack, in162// particular on Windows where the Structured Exception Handler is163// set up in the call stub. os::write_memory_serialize_page() can164// fault and we can't recover from it on Windows without a SEH in165// place.166static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {167assert(thread->thread_state() == from, "coming from wrong thread state");168assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");169// Change to transition state (assumes total store ordering! -Urs)170thread->set_thread_state((JavaThreadState)(from + 1));171172// Make sure new state is seen by VM thread173if (os::is_MP()) {174if (UseMembar) {175// Force a fence between the write above and read below176OrderAccess::fence();177} else {178// Must use this rather than serialization page in particular on Windows179InterfaceSupport::serialize_memory(thread);180}181}182183if (SafepointSynchronize::do_call_back()) {184SafepointSynchronize::block(thread);185}186thread->set_thread_state(to);187188CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)189}190191// Same as above, but assumes from = _thread_in_Java. This is simpler, since we192// never block on entry to the VM. This will break the code, since e.g. preserve arguments193// have not been setup.194static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {195assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");196thread->set_thread_state(to);197}198199static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {200assert((to & 1) == 0, "odd numbers are transitions states");201assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");202// Change to transition state (assumes total store ordering! -Urs)203thread->set_thread_state(_thread_in_native_trans);204205// Make sure new state is seen by GC thread206if (os::is_MP()) {207if (UseMembar) {208// Force a fence between the write above and read below209OrderAccess::fence();210} else {211// Must use this rather than serialization page in particular on Windows212InterfaceSupport::serialize_memory(thread);213}214}215216// We never install asynchronous exceptions when coming (back) in217// to the runtime from native code because the runtime is not set218// up to handle exceptions floating around at arbitrary points.219if (SafepointSynchronize::do_call_back() || thread->is_suspend_after_native()) {220JavaThread::check_safepoint_and_suspend_for_native_trans(thread);221222// Clear unhandled oops anywhere where we could block, even if we don't.223CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)224}225226thread->set_thread_state(to);227}228protected:229void trans(JavaThreadState from, JavaThreadState to) { transition(_thread, from, to); }230void trans_from_java(JavaThreadState to) { transition_from_java(_thread, to); }231void trans_from_native(JavaThreadState to) { transition_from_native(_thread, to); }232void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }233};234235236class ThreadInVMfromJava : public ThreadStateTransition {237public:238ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {239trans_from_java(_thread_in_vm);240}241~ThreadInVMfromJava() {242trans(_thread_in_vm, _thread_in_Java);243// Check for pending. async. exceptions or suspends.244if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();245}246};247248249class ThreadInVMfromUnknown {250private:251JavaThread* _thread;252public:253ThreadInVMfromUnknown() : _thread(NULL) {254Thread* t = Thread::current();255if (t->is_Java_thread()) {256JavaThread* t2 = (JavaThread*) t;257if (t2->thread_state() == _thread_in_native) {258_thread = t2;259ThreadStateTransition::transition_from_native(t2, _thread_in_vm);260// Used to have a HandleMarkCleaner but that is dangerous as261// it could free a handle in our (indirect, nested) caller.262// We expect any handles will be short lived and figure we263// don't need an actual HandleMark.264}265}266}267~ThreadInVMfromUnknown() {268if (_thread) {269ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);270}271}272};273274275class ThreadInVMfromNative : public ThreadStateTransition {276public:277ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {278trans_from_native(_thread_in_vm);279}280~ThreadInVMfromNative() {281trans_and_fence(_thread_in_vm, _thread_in_native);282}283};284285286class ThreadToNativeFromVM : public ThreadStateTransition {287public:288ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {289// We are leaving the VM at this point and going directly to native code.290// Block, if we are in the middle of a safepoint synchronization.291assert(!thread->owns_locks(), "must release all locks when leaving VM");292thread->frame_anchor()->make_walkable(thread);293trans_and_fence(_thread_in_vm, _thread_in_native);294// Check for pending. async. exceptions or suspends.295if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);296}297298~ThreadToNativeFromVM() {299trans_from_native(_thread_in_vm);300// We don't need to clear_walkable because it will happen automagically when we return to java301}302};303304305class ThreadBlockInVM : public ThreadStateTransition {306public:307ThreadBlockInVM(JavaThread *thread)308: ThreadStateTransition(thread) {309// Once we are blocked vm expects stack to be walkable310thread->frame_anchor()->make_walkable(thread);311trans_and_fence(_thread_in_vm, _thread_blocked);312}313~ThreadBlockInVM() {314trans_and_fence(_thread_blocked, _thread_in_vm);315// We don't need to clear_walkable because it will happen automagically when we return to java316}317};318319320// This special transition class is only used to prevent asynchronous exceptions321// from being installed on vm exit in situations where we can't tolerate them.322// See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.323class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {324public:325ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {326trans_from_java(_thread_in_vm);327}328~ThreadInVMfromJavaNoAsyncException() {329trans(_thread_in_vm, _thread_in_Java);330// NOTE: We do not check for pending. async. exceptions.331// If we did and moved the pending async exception over into the332// pending exception field, we would need to deopt (currently C2333// only). However, to do so would require that we transition back334// to the _thread_in_vm state. Instead we postpone the handling of335// the async exception.336337// Check for pending. suspends only.338if (_thread->has_special_runtime_exit_condition())339_thread->handle_special_runtime_exit_condition(false);340}341};342343// Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.344// Can be used to verify properties on enter/exit of the VM.345346#ifdef ASSERT347class VMEntryWrapper {348public:349VMEntryWrapper() {350if (VerifyLastFrame) {351InterfaceSupport::verify_last_frame();352}353}354355~VMEntryWrapper() {356InterfaceSupport::check_gc_alot();357if (WalkStackALot) {358InterfaceSupport::walk_stack();359}360#ifdef ENABLE_ZAP_DEAD_LOCALS361if (ZapDeadLocalsOld) {362InterfaceSupport::zap_dead_locals_old();363}364#endif365#ifdef COMPILER2366// This option is not used by Compiler 1367if (StressDerivedPointers) {368InterfaceSupport::stress_derived_pointers();369}370#endif371if (DeoptimizeALot || DeoptimizeRandom) {372InterfaceSupport::deoptimizeAll();373}374if (ZombieALot) {375InterfaceSupport::zombieAll();376}377if (UnlinkSymbolsALot) {378InterfaceSupport::unlinkSymbols();379}380// do verification AFTER potential deoptimization381if (VerifyStack) {382InterfaceSupport::verify_stack();383}384385}386};387388389class VMNativeEntryWrapper {390public:391VMNativeEntryWrapper() {392if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();393}394395~VMNativeEntryWrapper() {396if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();397}398};399400#endif401402403// VM-internal runtime interface support404405#ifdef ASSERT406407class RuntimeHistogramElement : public HistogramElement {408public:409RuntimeHistogramElement(const char* name);410};411412#define TRACE_CALL(result_type, header) \413InterfaceSupport::_number_of_calls++; \414if (TraceRuntimeCalls) \415InterfaceSupport::trace(#result_type, #header); \416if (CountRuntimeCalls) { \417static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \418if (e != NULL) e->increment_count(); \419}420#else421#define TRACE_CALL(result_type, header) \422/* do nothing */423#endif424425426// LEAF routines do not lock, GC or throw exceptions427428#define VM_LEAF_BASE(result_type, header) \429TRACE_CALL(result_type, header) \430debug_only(NoHandleMark __hm;) \431MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, \432JavaThread::current())); \433os::verify_stack_alignment(); \434/* begin of body */435436#define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread) \437TRACE_CALL(result_type, header) \438debug_only(ResetNoHandleMark __rnhm;) \439HandleMarkCleaner __hm(thread); \440Thread* THREAD = thread; \441os::verify_stack_alignment(); \442/* begin of body */443444445// ENTRY routines may lock, GC and throw exceptions446447#define VM_ENTRY_BASE(result_type, header, thread) \448TRACE_CALL(result_type, header) \449HandleMarkCleaner __hm(thread); \450Thread* THREAD = thread; \451os::verify_stack_alignment(); \452/* begin of body */453454455// QUICK_ENTRY routines behave like ENTRY but without a handle mark456457#define VM_QUICK_ENTRY_BASE(result_type, header, thread) \458TRACE_CALL(result_type, header) \459debug_only(NoHandleMark __hm;) \460Thread* THREAD = thread; \461os::verify_stack_alignment(); \462/* begin of body */463464465// Definitions for IRT (Interpreter Runtime)466// (thread is an argument passed in to all these routines)467468#define IRT_ENTRY(result_type, header) \469result_type header { \470ThreadInVMfromJava __tiv(thread); \471VM_ENTRY_BASE(result_type, header, thread) \472debug_only(VMEntryWrapper __vew;)473474475#define IRT_LEAF(result_type, header) \476result_type header { \477VM_LEAF_BASE(result_type, header) \478debug_only(No_Safepoint_Verifier __nspv(true);)479480481#define IRT_ENTRY_NO_ASYNC(result_type, header) \482result_type header { \483ThreadInVMfromJavaNoAsyncException __tiv(thread); \484VM_ENTRY_BASE(result_type, header, thread) \485debug_only(VMEntryWrapper __vew;)486487#define IRT_END }488489490// Definitions for JRT (Java (Compiler/Shared) Runtime)491492#define JRT_ENTRY(result_type, header) \493result_type header { \494MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \495ThreadInVMfromJava __tiv(thread); \496VM_ENTRY_BASE(result_type, header, thread) \497debug_only(VMEntryWrapper __vew;)498499500#define JRT_LEAF(result_type, header) \501result_type header { \502VM_LEAF_BASE(result_type, header) \503debug_only(JRT_Leaf_Verifier __jlv;)504505506#define JRT_ENTRY_NO_ASYNC(result_type, header) \507result_type header { \508MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \509ThreadInVMfromJavaNoAsyncException __tiv(thread); \510VM_ENTRY_BASE(result_type, header, thread) \511debug_only(VMEntryWrapper __vew;)512513// Same as JRT Entry but allows for return value after the safepoint514// to get back into Java from the VM515#define JRT_BLOCK_ENTRY(result_type, header) \516result_type header { \517MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \518TRACE_CALL(result_type, header) \519HandleMarkCleaner __hm(thread);520521#define JRT_BLOCK \522{ \523ThreadInVMfromJava __tiv(thread); \524Thread* THREAD = thread; \525debug_only(VMEntryWrapper __vew;)526527#define JRT_BLOCK_END }528529#define JRT_END }530531// Definitions for JNI532533#define JNI_ENTRY(result_type, header) \534JNI_ENTRY_NO_PRESERVE(result_type, header) \535WeakPreserveExceptionMark __wem(thread);536537#define JNI_ENTRY_NO_PRESERVE(result_type, header) \538extern "C" { \539result_type JNICALL header { \540JavaThread* thread=JavaThread::thread_from_jni_environment(env); \541assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \542MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \543ThreadInVMfromNative __tiv(thread); \544debug_only(VMNativeEntryWrapper __vew;) \545VM_ENTRY_BASE(result_type, header, thread)546547548// Ensure that the VMNativeEntryWrapper constructor, which can cause549// a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).550#define JNI_QUICK_ENTRY(result_type, header) \551extern "C" { \552result_type JNICALL header { \553JavaThread* thread=JavaThread::thread_from_jni_environment(env); \554assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \555ThreadInVMfromNative __tiv(thread); \556debug_only(VMNativeEntryWrapper __vew;) \557VM_QUICK_ENTRY_BASE(result_type, header, thread)558559560#define JNI_LEAF(result_type, header) \561extern "C" { \562result_type JNICALL header { \563JavaThread* thread=JavaThread::thread_from_jni_environment(env); \564assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \565VM_LEAF_BASE(result_type, header)566567568// Close the routine and the extern "C"569#define JNI_END } }570571572573// Definitions for JVM574575#define JVM_ENTRY(result_type, header) \576extern "C" { \577result_type JNICALL header { \578JavaThread* thread=JavaThread::thread_from_jni_environment(env); \579MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \580ThreadInVMfromNative __tiv(thread); \581debug_only(VMNativeEntryWrapper __vew;) \582VM_ENTRY_BASE(result_type, header, thread)583584585#define JVM_ENTRY_NO_ENV(result_type, header) \586extern "C" { \587result_type JNICALL header { \588JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread(); \589MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread)); \590ThreadInVMfromNative __tiv(thread); \591debug_only(VMNativeEntryWrapper __vew;) \592VM_ENTRY_BASE(result_type, header, thread)593594595#define JVM_QUICK_ENTRY(result_type, header) \596extern "C" { \597result_type JNICALL header { \598JavaThread* thread=JavaThread::thread_from_jni_environment(env); \599ThreadInVMfromNative __tiv(thread); \600debug_only(VMNativeEntryWrapper __vew;) \601VM_QUICK_ENTRY_BASE(result_type, header, thread)602603604#define JVM_LEAF(result_type, header) \605extern "C" { \606result_type JNICALL header { \607VM_Exit::block_if_vm_exited(); \608VM_LEAF_BASE(result_type, header)609610611#define JVM_ENTRY_FROM_LEAF(env, result_type, header) \612{ { \613JavaThread* thread=JavaThread::thread_from_jni_environment(env); \614ThreadInVMfromNative __tiv(thread); \615debug_only(VMNativeEntryWrapper __vew;) \616VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)617618619#define JVM_END } }620621#endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP622623624