src/hotspot/share/runtime/interfaceSupport.hpp
changeset 49449 ef5d5d343e2a
parent 49448 b91b558a9076
child 49450 5d2adef239d6
equal deleted inserted replaced
49448:b91b558a9076 49449:ef5d5d343e2a
     1 /*
       
     2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. 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 it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 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 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #ifndef SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
       
    26 #define SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP
       
    27 
       
    28 #include "gc/shared/gcLocker.hpp"
       
    29 #include "runtime/handles.inline.hpp"
       
    30 #include "runtime/mutexLocker.hpp"
       
    31 #include "runtime/orderAccess.hpp"
       
    32 #include "runtime/os.hpp"
       
    33 #include "runtime/safepointMechanism.inline.hpp"
       
    34 #include "runtime/thread.inline.hpp"
       
    35 #include "runtime/vmThread.hpp"
       
    36 #include "utilities/globalDefinitions.hpp"
       
    37 #include "utilities/macros.hpp"
       
    38 #include "utilities/preserveException.hpp"
       
    39 
       
    40 // 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 further
       
    43 // down the stack (in JavaCalls::call_helper), and just resets
       
    44 // to the saved values in that HandleMark.
       
    45 
       
    46 class HandleMarkCleaner: public StackObj {
       
    47  private:
       
    48   Thread* _thread;
       
    49  public:
       
    50   HandleMarkCleaner(Thread* thread) {
       
    51     _thread = thread;
       
    52     _thread->last_handle_mark()->push();
       
    53   }
       
    54   ~HandleMarkCleaner() {
       
    55     _thread->last_handle_mark()->pop_and_restore();
       
    56   }
       
    57 
       
    58  private:
       
    59   inline void* operator new(size_t size, void* ptr) throw() {
       
    60     return ptr;
       
    61   }
       
    62 };
       
    63 
       
    64 // InterfaceSupport provides functionality used by the VM_LEAF_BASE and
       
    65 // VM_ENTRY_BASE macros. These macros are used to guard entry points into
       
    66 // the VM and perform checks upon leave of the VM.
       
    67 
       
    68 
       
    69 class InterfaceSupport: AllStatic {
       
    70 # ifdef ASSERT
       
    71  public:
       
    72   static long _scavenge_alot_counter;
       
    73   static long _fullgc_alot_counter;
       
    74   static long _number_of_calls;
       
    75   static long _fullgc_alot_invocation;
       
    76 
       
    77   // Helper methods used to implement +ScavengeALot and +FullGCALot
       
    78   static void check_gc_alot() { if (ScavengeALot || FullGCALot) gc_alot(); }
       
    79   static void gc_alot();
       
    80 
       
    81   static void walk_stack_from(vframe* start_vf);
       
    82   static void walk_stack();
       
    83 
       
    84   static void zombieAll();
       
    85   static void unlinkSymbols();
       
    86   static void deoptimizeAll();
       
    87   static void stress_derived_pointers();
       
    88   static void verify_stack();
       
    89   static void verify_last_frame();
       
    90 # endif
       
    91 
       
    92  public:
       
    93   static void serialize_thread_state_with_handler(JavaThread* thread) {
       
    94     serialize_thread_state_internal(thread, true);
       
    95   }
       
    96 
       
    97   // Should only call this if we know that we have a proper SEH set up.
       
    98   static void serialize_thread_state(JavaThread* thread) {
       
    99     serialize_thread_state_internal(thread, false);
       
   100   }
       
   101 
       
   102  private:
       
   103   static void serialize_thread_state_internal(JavaThread* thread, bool needs_exception_handler) {
       
   104     // Make sure new state is seen by VM thread
       
   105     if (os::is_MP()) {
       
   106       if (UseMembar) {
       
   107         // Force a fence between the write above and read below
       
   108         OrderAccess::fence();
       
   109       } else {
       
   110         // store to serialize page so VM thread can do pseudo remote membar
       
   111         if (needs_exception_handler) {
       
   112           os::write_memory_serialize_page_with_handler(thread);
       
   113         } else {
       
   114           os::write_memory_serialize_page(thread);
       
   115         }
       
   116       }
       
   117     }
       
   118   }
       
   119 };
       
   120 
       
   121 
       
   122 // Basic class for all thread transition classes.
       
   123 
       
   124 class ThreadStateTransition : public StackObj {
       
   125  protected:
       
   126   JavaThread* _thread;
       
   127  public:
       
   128   ThreadStateTransition(JavaThread *thread) {
       
   129     _thread = thread;
       
   130     assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
       
   131   }
       
   132 
       
   133   // Change threadstate in a manner, so safepoint can detect changes.
       
   134   // Time-critical: called on exit from every runtime routine
       
   135   static inline void transition(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
       
   136     assert(from != _thread_in_Java, "use transition_from_java");
       
   137     assert(from != _thread_in_native, "use transition_from_native");
       
   138     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
       
   139     assert(thread->thread_state() == from, "coming from wrong thread state");
       
   140     // Change to transition state
       
   141     thread->set_thread_state((JavaThreadState)(from + 1));
       
   142 
       
   143     InterfaceSupport::serialize_thread_state(thread);
       
   144 
       
   145     SafepointMechanism::block_if_requested(thread);
       
   146     thread->set_thread_state(to);
       
   147 
       
   148     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
       
   149   }
       
   150 
       
   151   // transition_and_fence must be used on any thread state transition
       
   152   // where there might not be a Java call stub on the stack, in
       
   153   // particular on Windows where the Structured Exception Handler is
       
   154   // set up in the call stub. os::write_memory_serialize_page() can
       
   155   // fault and we can't recover from it on Windows without a SEH in
       
   156   // place.
       
   157   static inline void transition_and_fence(JavaThread *thread, JavaThreadState from, JavaThreadState to) {
       
   158     assert(thread->thread_state() == from, "coming from wrong thread state");
       
   159     assert((from & 1) == 0 && (to & 1) == 0, "odd numbers are transitions states");
       
   160     // Change to transition state
       
   161     thread->set_thread_state((JavaThreadState)(from + 1));
       
   162 
       
   163     InterfaceSupport::serialize_thread_state_with_handler(thread);
       
   164 
       
   165     SafepointMechanism::block_if_requested(thread);
       
   166     thread->set_thread_state(to);
       
   167 
       
   168     CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
       
   169   }
       
   170 
       
   171   // Same as above, but assumes from = _thread_in_Java. This is simpler, since we
       
   172   // never block on entry to the VM. This will break the code, since e.g. preserve arguments
       
   173   // have not been setup.
       
   174   static inline void transition_from_java(JavaThread *thread, JavaThreadState to) {
       
   175     assert(thread->thread_state() == _thread_in_Java, "coming from wrong thread state");
       
   176     thread->set_thread_state(to);
       
   177   }
       
   178 
       
   179   static inline void transition_from_native(JavaThread *thread, JavaThreadState to) {
       
   180     assert((to & 1) == 0, "odd numbers are transitions states");
       
   181     assert(thread->thread_state() == _thread_in_native, "coming from wrong thread state");
       
   182     // Change to transition state
       
   183     thread->set_thread_state(_thread_in_native_trans);
       
   184 
       
   185     InterfaceSupport::serialize_thread_state_with_handler(thread);
       
   186 
       
   187     // We never install asynchronous exceptions when coming (back) in
       
   188     // to the runtime from native code because the runtime is not set
       
   189     // up to handle exceptions floating around at arbitrary points.
       
   190     if (SafepointMechanism::poll(thread) || thread->is_suspend_after_native()) {
       
   191       JavaThread::check_safepoint_and_suspend_for_native_trans(thread);
       
   192 
       
   193       // Clear unhandled oops anywhere where we could block, even if we don't.
       
   194       CHECK_UNHANDLED_OOPS_ONLY(thread->clear_unhandled_oops();)
       
   195     }
       
   196 
       
   197     thread->set_thread_state(to);
       
   198   }
       
   199  protected:
       
   200    void trans(JavaThreadState from, JavaThreadState to)  { transition(_thread, from, to); }
       
   201    void trans_from_java(JavaThreadState to)              { transition_from_java(_thread, to); }
       
   202    void trans_from_native(JavaThreadState to)            { transition_from_native(_thread, to); }
       
   203    void trans_and_fence(JavaThreadState from, JavaThreadState to) { transition_and_fence(_thread, from, to); }
       
   204 };
       
   205 
       
   206 class ThreadInVMForHandshake : public ThreadStateTransition {
       
   207   const JavaThreadState _original_state;
       
   208 
       
   209   void transition_back() {
       
   210     // This can be invoked from transition states and must return to the original state properly
       
   211     assert(_thread->thread_state() == _thread_in_vm, "should only call when leaving VM after handshake");
       
   212     _thread->set_thread_state(_thread_in_vm_trans);
       
   213 
       
   214     InterfaceSupport::serialize_thread_state(_thread);
       
   215 
       
   216     SafepointMechanism::block_if_requested(_thread);
       
   217 
       
   218     _thread->set_thread_state(_original_state);
       
   219   }
       
   220 
       
   221  public:
       
   222 
       
   223   ThreadInVMForHandshake(JavaThread* thread) : ThreadStateTransition(thread),
       
   224       _original_state(thread->thread_state()) {
       
   225 
       
   226     if (thread->has_last_Java_frame()) {
       
   227       thread->frame_anchor()->make_walkable(thread);
       
   228     }
       
   229 
       
   230     thread->set_thread_state(_thread_in_vm);
       
   231   }
       
   232 
       
   233   ~ThreadInVMForHandshake() {
       
   234     transition_back();
       
   235   }
       
   236 
       
   237 };
       
   238 
       
   239 class ThreadInVMfromJava : public ThreadStateTransition {
       
   240  public:
       
   241   ThreadInVMfromJava(JavaThread* thread) : ThreadStateTransition(thread) {
       
   242     trans_from_java(_thread_in_vm);
       
   243   }
       
   244   ~ThreadInVMfromJava()  {
       
   245     if (_thread->stack_yellow_reserved_zone_disabled()) {
       
   246       _thread->enable_stack_yellow_reserved_zone();
       
   247     }
       
   248     trans(_thread_in_vm, _thread_in_Java);
       
   249     // Check for pending. async. exceptions or suspends.
       
   250     if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition();
       
   251   }
       
   252 };
       
   253 
       
   254 
       
   255 class ThreadInVMfromUnknown {
       
   256  private:
       
   257   JavaThread* _thread;
       
   258  public:
       
   259   ThreadInVMfromUnknown() : _thread(NULL) {
       
   260     Thread* t = Thread::current();
       
   261     if (t->is_Java_thread()) {
       
   262       JavaThread* t2 = (JavaThread*) t;
       
   263       if (t2->thread_state() == _thread_in_native) {
       
   264         _thread = t2;
       
   265         ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
       
   266         // Used to have a HandleMarkCleaner but that is dangerous as
       
   267         // it could free a handle in our (indirect, nested) caller.
       
   268         // We expect any handles will be short lived and figure we
       
   269         // don't need an actual HandleMark.
       
   270       }
       
   271     }
       
   272   }
       
   273   ~ThreadInVMfromUnknown()  {
       
   274     if (_thread) {
       
   275       ThreadStateTransition::transition_and_fence(_thread, _thread_in_vm, _thread_in_native);
       
   276     }
       
   277   }
       
   278 };
       
   279 
       
   280 
       
   281 class ThreadInVMfromNative : public ThreadStateTransition {
       
   282  public:
       
   283   ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
       
   284     trans_from_native(_thread_in_vm);
       
   285   }
       
   286   ~ThreadInVMfromNative() {
       
   287     trans_and_fence(_thread_in_vm, _thread_in_native);
       
   288   }
       
   289 };
       
   290 
       
   291 
       
   292 class ThreadToNativeFromVM : public ThreadStateTransition {
       
   293  public:
       
   294   ThreadToNativeFromVM(JavaThread *thread) : ThreadStateTransition(thread) {
       
   295     // We are leaving the VM at this point and going directly to native code.
       
   296     // Block, if we are in the middle of a safepoint synchronization.
       
   297     assert(!thread->owns_locks(), "must release all locks when leaving VM");
       
   298     thread->frame_anchor()->make_walkable(thread);
       
   299     trans_and_fence(_thread_in_vm, _thread_in_native);
       
   300     // Check for pending. async. exceptions or suspends.
       
   301     if (_thread->has_special_runtime_exit_condition()) _thread->handle_special_runtime_exit_condition(false);
       
   302   }
       
   303 
       
   304   ~ThreadToNativeFromVM() {
       
   305     trans_from_native(_thread_in_vm);
       
   306     assert(!_thread->is_pending_jni_exception_check(), "Pending JNI Exception Check");
       
   307     // We don't need to clear_walkable because it will happen automagically when we return to java
       
   308   }
       
   309 };
       
   310 
       
   311 
       
   312 class ThreadBlockInVM : public ThreadStateTransition {
       
   313  public:
       
   314   ThreadBlockInVM(JavaThread *thread)
       
   315   : ThreadStateTransition(thread) {
       
   316     // Once we are blocked vm expects stack to be walkable
       
   317     thread->frame_anchor()->make_walkable(thread);
       
   318     trans_and_fence(_thread_in_vm, _thread_blocked);
       
   319   }
       
   320   ~ThreadBlockInVM() {
       
   321     trans_and_fence(_thread_blocked, _thread_in_vm);
       
   322     // We don't need to clear_walkable because it will happen automagically when we return to java
       
   323   }
       
   324 };
       
   325 
       
   326 
       
   327 // This special transition class is only used to prevent asynchronous exceptions
       
   328 // from being installed on vm exit in situations where we can't tolerate them.
       
   329 // See bugs: 4324348, 4854693, 4998314, 5040492, 5050705.
       
   330 class ThreadInVMfromJavaNoAsyncException : public ThreadStateTransition {
       
   331  public:
       
   332   ThreadInVMfromJavaNoAsyncException(JavaThread* thread) : ThreadStateTransition(thread) {
       
   333     trans_from_java(_thread_in_vm);
       
   334   }
       
   335   ~ThreadInVMfromJavaNoAsyncException()  {
       
   336     if (_thread->stack_yellow_reserved_zone_disabled()) {
       
   337       _thread->enable_stack_yellow_reserved_zone();
       
   338     }
       
   339     trans(_thread_in_vm, _thread_in_Java);
       
   340     // NOTE: We do not check for pending. async. exceptions.
       
   341     // If we did and moved the pending async exception over into the
       
   342     // pending exception field, we would need to deopt (currently C2
       
   343     // only). However, to do so would require that we transition back
       
   344     // to the _thread_in_vm state. Instead we postpone the handling of
       
   345     // the async exception.
       
   346 
       
   347 
       
   348     // Check for pending. suspends only.
       
   349     if (_thread->has_special_runtime_exit_condition())
       
   350       _thread->handle_special_runtime_exit_condition(false);
       
   351   }
       
   352 };
       
   353 
       
   354 // Debug class instantiated in JRT_ENTRY and ITR_ENTRY macro.
       
   355 // Can be used to verify properties on enter/exit of the VM.
       
   356 
       
   357 #ifdef ASSERT
       
   358 class VMEntryWrapper {
       
   359  public:
       
   360   VMEntryWrapper() {
       
   361     if (VerifyLastFrame) {
       
   362       InterfaceSupport::verify_last_frame();
       
   363     }
       
   364   }
       
   365 
       
   366   ~VMEntryWrapper() {
       
   367     InterfaceSupport::check_gc_alot();
       
   368     if (WalkStackALot) {
       
   369       InterfaceSupport::walk_stack();
       
   370     }
       
   371 #ifdef COMPILER2
       
   372     // This option is not used by Compiler 1
       
   373     if (StressDerivedPointers) {
       
   374       InterfaceSupport::stress_derived_pointers();
       
   375     }
       
   376 #endif
       
   377     if (DeoptimizeALot || DeoptimizeRandom) {
       
   378       InterfaceSupport::deoptimizeAll();
       
   379     }
       
   380     if (ZombieALot) {
       
   381       InterfaceSupport::zombieAll();
       
   382     }
       
   383     if (UnlinkSymbolsALot) {
       
   384       InterfaceSupport::unlinkSymbols();
       
   385     }
       
   386     // do verification AFTER potential deoptimization
       
   387     if (VerifyStack) {
       
   388       InterfaceSupport::verify_stack();
       
   389     }
       
   390 
       
   391   }
       
   392 };
       
   393 
       
   394 
       
   395 class VMNativeEntryWrapper {
       
   396  public:
       
   397   VMNativeEntryWrapper() {
       
   398     if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
       
   399   }
       
   400 
       
   401   ~VMNativeEntryWrapper() {
       
   402     if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
       
   403   }
       
   404 };
       
   405 
       
   406 #endif
       
   407 
       
   408 
       
   409 // VM-internal runtime interface support
       
   410 
       
   411 #ifdef ASSERT
       
   412 
       
   413 class RuntimeHistogramElement : public HistogramElement {
       
   414   public:
       
   415    RuntimeHistogramElement(const char* name);
       
   416 };
       
   417 
       
   418 #define TRACE_CALL(result_type, header)                            \
       
   419   InterfaceSupport::_number_of_calls++;                            \
       
   420   if (CountRuntimeCalls) {                                         \
       
   421     static RuntimeHistogramElement* e = new RuntimeHistogramElement(#header); \
       
   422     if (e != NULL) e->increment_count();                           \
       
   423   }
       
   424 #else
       
   425 #define TRACE_CALL(result_type, header)                            \
       
   426   /* do nothing */
       
   427 #endif
       
   428 
       
   429 
       
   430 // LEAF routines do not lock, GC or throw exceptions
       
   431 
       
   432 #define VM_LEAF_BASE(result_type, header)                            \
       
   433   TRACE_CALL(result_type, header)                                    \
       
   434   debug_only(NoHandleMark __hm;)                                     \
       
   435   os::verify_stack_alignment();                                      \
       
   436   /* begin of body */
       
   437 
       
   438 #define VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)         \
       
   439   TRACE_CALL(result_type, header)                                    \
       
   440   debug_only(ResetNoHandleMark __rnhm;)                              \
       
   441   HandleMarkCleaner __hm(thread);                                    \
       
   442   Thread* THREAD = thread;                                           \
       
   443   os::verify_stack_alignment();                                      \
       
   444   /* begin of body */
       
   445 
       
   446 
       
   447 // ENTRY routines may lock, GC and throw exceptions
       
   448 
       
   449 #define VM_ENTRY_BASE(result_type, header, thread)                   \
       
   450   TRACE_CALL(result_type, header)                                    \
       
   451   HandleMarkCleaner __hm(thread);                                    \
       
   452   Thread* THREAD = thread;                                           \
       
   453   os::verify_stack_alignment();                                      \
       
   454   /* begin of body */
       
   455 
       
   456 
       
   457 // QUICK_ENTRY routines behave like ENTRY but without a handle mark
       
   458 
       
   459 #define VM_QUICK_ENTRY_BASE(result_type, header, thread)             \
       
   460   TRACE_CALL(result_type, header)                                    \
       
   461   debug_only(NoHandleMark __hm;)                                     \
       
   462   Thread* THREAD = thread;                                           \
       
   463   os::verify_stack_alignment();                                      \
       
   464   /* begin of body */
       
   465 
       
   466 
       
   467 // Definitions for IRT (Interpreter Runtime)
       
   468 // (thread is an argument passed in to all these routines)
       
   469 
       
   470 #define IRT_ENTRY(result_type, header)                               \
       
   471   result_type header {                                               \
       
   472     ThreadInVMfromJava __tiv(thread);                                \
       
   473     VM_ENTRY_BASE(result_type, header, thread)                       \
       
   474     debug_only(VMEntryWrapper __vew;)
       
   475 
       
   476 
       
   477 #define IRT_LEAF(result_type, header)                                \
       
   478   result_type header {                                               \
       
   479     VM_LEAF_BASE(result_type, header)                                \
       
   480     debug_only(NoSafepointVerifier __nspv(true);)
       
   481 
       
   482 
       
   483 #define IRT_ENTRY_NO_ASYNC(result_type, header)                      \
       
   484   result_type header {                                               \
       
   485     ThreadInVMfromJavaNoAsyncException __tiv(thread);                \
       
   486     VM_ENTRY_BASE(result_type, header, thread)                       \
       
   487     debug_only(VMEntryWrapper __vew;)
       
   488 
       
   489 #define IRT_END }
       
   490 
       
   491 
       
   492 // Definitions for JRT (Java (Compiler/Shared) Runtime)
       
   493 
       
   494 #define JRT_ENTRY(result_type, header)                               \
       
   495   result_type header {                                               \
       
   496     ThreadInVMfromJava __tiv(thread);                                \
       
   497     VM_ENTRY_BASE(result_type, header, thread)                       \
       
   498     debug_only(VMEntryWrapper __vew;)
       
   499 
       
   500 
       
   501 #define JRT_LEAF(result_type, header)                                \
       
   502   result_type header {                                               \
       
   503   VM_LEAF_BASE(result_type, header)                                  \
       
   504   debug_only(JRTLeafVerifier __jlv;)
       
   505 
       
   506 
       
   507 #define JRT_ENTRY_NO_ASYNC(result_type, header)                      \
       
   508   result_type header {                                               \
       
   509     ThreadInVMfromJavaNoAsyncException __tiv(thread);                \
       
   510     VM_ENTRY_BASE(result_type, header, thread)                       \
       
   511     debug_only(VMEntryWrapper __vew;)
       
   512 
       
   513 // Same as JRT Entry but allows for return value after the safepoint
       
   514 // to get back into Java from the VM
       
   515 #define JRT_BLOCK_ENTRY(result_type, header)                         \
       
   516   result_type header {                                               \
       
   517     TRACE_CALL(result_type, header)                                  \
       
   518     HandleMarkCleaner __hm(thread);
       
   519 
       
   520 #define JRT_BLOCK                                                    \
       
   521     {                                                                \
       
   522     ThreadInVMfromJava __tiv(thread);                                \
       
   523     Thread* THREAD = thread;                                         \
       
   524     debug_only(VMEntryWrapper __vew;)
       
   525 
       
   526 #define JRT_BLOCK_NO_ASYNC                                           \
       
   527     {                                                                \
       
   528     ThreadInVMfromJavaNoAsyncException __tiv(thread);                \
       
   529     Thread* THREAD = thread;                                         \
       
   530     debug_only(VMEntryWrapper __vew;)
       
   531 
       
   532 #define JRT_BLOCK_END }
       
   533 
       
   534 #define JRT_END }
       
   535 
       
   536 // Definitions for JNI
       
   537 
       
   538 #define JNI_ENTRY(result_type, header)                               \
       
   539     JNI_ENTRY_NO_PRESERVE(result_type, header)                       \
       
   540     WeakPreserveExceptionMark __wem(thread);
       
   541 
       
   542 #define JNI_ENTRY_NO_PRESERVE(result_type, header)                   \
       
   543 extern "C" {                                                         \
       
   544   result_type JNICALL header {                                       \
       
   545     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   546     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
       
   547     ThreadInVMfromNative __tiv(thread);                              \
       
   548     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   549     VM_ENTRY_BASE(result_type, header, thread)
       
   550 
       
   551 
       
   552 // Ensure that the VMNativeEntryWrapper constructor, which can cause
       
   553 // a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE).
       
   554 #define JNI_QUICK_ENTRY(result_type, header)                         \
       
   555 extern "C" {                                                         \
       
   556   result_type JNICALL header {                                       \
       
   557     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   558     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
       
   559     ThreadInVMfromNative __tiv(thread);                              \
       
   560     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   561     VM_QUICK_ENTRY_BASE(result_type, header, thread)
       
   562 
       
   563 
       
   564 #define JNI_LEAF(result_type, header)                                \
       
   565 extern "C" {                                                         \
       
   566   result_type JNICALL header {                                       \
       
   567     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   568     assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \
       
   569     VM_LEAF_BASE(result_type, header)
       
   570 
       
   571 
       
   572 // Close the routine and the extern "C"
       
   573 #define JNI_END } }
       
   574 
       
   575 
       
   576 
       
   577 // Definitions for JVM
       
   578 
       
   579 #define JVM_ENTRY(result_type, header)                               \
       
   580 extern "C" {                                                         \
       
   581   result_type JNICALL header {                                       \
       
   582     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   583     ThreadInVMfromNative __tiv(thread);                              \
       
   584     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   585     VM_ENTRY_BASE(result_type, header, thread)
       
   586 
       
   587 
       
   588 #define JVM_ENTRY_NO_ENV(result_type, header)                        \
       
   589 extern "C" {                                                         \
       
   590   result_type JNICALL header {                                       \
       
   591     JavaThread* thread = JavaThread::current();                      \
       
   592     ThreadInVMfromNative __tiv(thread);                              \
       
   593     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   594     VM_ENTRY_BASE(result_type, header, thread)
       
   595 
       
   596 
       
   597 #define JVM_QUICK_ENTRY(result_type, header)                         \
       
   598 extern "C" {                                                         \
       
   599   result_type JNICALL header {                                       \
       
   600     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   601     ThreadInVMfromNative __tiv(thread);                              \
       
   602     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   603     VM_QUICK_ENTRY_BASE(result_type, header, thread)
       
   604 
       
   605 
       
   606 #define JVM_LEAF(result_type, header)                                \
       
   607 extern "C" {                                                         \
       
   608   result_type JNICALL header {                                       \
       
   609     VM_Exit::block_if_vm_exited();                                   \
       
   610     VM_LEAF_BASE(result_type, header)
       
   611 
       
   612 
       
   613 #define JVM_ENTRY_FROM_LEAF(env, result_type, header)                \
       
   614   { {                                                                \
       
   615     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
       
   616     ThreadInVMfromNative __tiv(thread);                              \
       
   617     debug_only(VMNativeEntryWrapper __vew;)                          \
       
   618     VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
       
   619 
       
   620 
       
   621 #define JVM_END } }
       
   622 
       
   623 #endif // SHARE_VM_RUNTIME_INTERFACESUPPORT_HPP