src/share/vm/runtime/interfaceSupport.hpp

Thu, 24 May 2018 19:24:53 +0800

author
aoqi
date
Thu, 24 May 2018 19:24:53 +0800
changeset 8861
2a33b32dd03c
parent 6876
710a3c8b516e
child 9572
624a0741915c
permissions
-rw-r--r--

#7046 Disable the compilation when branch offset is beyond short branch
Contributed-by: fujie, aoqi

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

mercurial