< prev index next >

src/hotspot/share/runtime/javaCalls.cpp

Print this page

 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "classfile/vmSymbols.hpp"
 27 #include "code/nmethod.hpp"
 28 #include "compiler/compilationPolicy.hpp"
 29 #include "compiler/compileBroker.hpp"
 30 #include "interpreter/interpreter.hpp"
 31 #include "interpreter/linkResolver.hpp"
 32 #include "memory/universe.hpp"

 33 #include "oops/method.inline.hpp"
 34 #include "oops/oop.inline.hpp"
 35 #include "prims/jniCheck.hpp"
 36 #include "prims/jvmtiExport.hpp"
 37 #include "runtime/handles.inline.hpp"
 38 #include "runtime/interfaceSupport.inline.hpp"
 39 #include "runtime/javaCalls.hpp"
 40 #include "runtime/javaThread.hpp"
 41 #include "runtime/jniHandles.inline.hpp"
 42 #include "runtime/mutexLocker.hpp"
 43 #include "runtime/os.inline.hpp"
 44 #include "runtime/sharedRuntime.hpp"
 45 #include "runtime/signature.hpp"
 46 #include "runtime/stubRoutines.hpp"
 47 #include "runtime/thread.inline.hpp"
 48 
 49 // -----------------------------------------------------
 50 // Implementation of JavaCallWrapper
 51 
 52 JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS) {

117 
118   if (_thread->has_pending_exception() && _thread->has_last_Java_frame()) {
119     // If we get here, the Java code threw an exception that unwound a frame.
120     // It could be that the new frame anchor has not passed through the required
121     // StackWatermark barriers. Therefore, we process any such deferred unwind
122     // requests here.
123     StackWatermarkSet::after_unwind(_thread);
124   }
125 }
126 
127 
128 void JavaCallWrapper::oops_do(OopClosure* f) {
129   f->do_oop((oop*)&_receiver);
130   handles()->oops_do(f);
131 }
132 
133 
134 // Helper methods
135 static BasicType runtime_type_from(JavaValue* result) {
136   switch (result->get_type()) {
137     case T_BOOLEAN: // fall through
138     case T_CHAR   : // fall through
139     case T_SHORT  : // fall through
140     case T_INT    : // fall through
141 #ifndef _LP64
142     case T_OBJECT : // fall through
143     case T_ARRAY  : // fall through

144 #endif
145     case T_BYTE   : // fall through
146     case T_VOID   : return T_INT;
147     case T_LONG   : return T_LONG;
148     case T_FLOAT  : return T_FLOAT;
149     case T_DOUBLE : return T_DOUBLE;
150 #ifdef _LP64
151     case T_ARRAY  : // fall through
152     case T_OBJECT:  return T_OBJECT;
153 #endif
154     default:
155       ShouldNotReachHere();
156       return T_ILLEGAL;
157   }
158 }
159 
160 // ============ Virtual calls ============
161 
162 void JavaCalls::call_virtual(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
163   CallInfo callinfo;
164   Handle receiver = args->receiver();
165   Klass* recvrKlass = receiver.is_null() ? (Klass*)nullptr : receiver->klass();
166   LinkInfo link_info(spec_klass, name, signature);
167   LinkResolver::resolve_virtual_call(
168           callinfo, receiver, recvrKlass, link_info, true, CHECK);
169   methodHandle method(THREAD, callinfo.selected_method());
170   assert(method.not_null(), "should have thrown exception");
171 
172   // Invoke the method

353   // Find receiver
354   Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
355 
356   // When we reenter Java, we need to re-enable the reserved/yellow zone which
357   // might already be disabled when we are in VM.
358   thread->stack_overflow_state()->reguard_stack_if_needed();
359 
360   // Check that there are shadow pages available before changing thread state
361   // to Java. Calculate current_stack_pointer here to make sure
362   // stack_shadow_pages_available() and map_stack_shadow_pages() use the same sp.
363   address sp = os::current_stack_pointer();
364   if (!os::stack_shadow_pages_available(THREAD, method, sp)) {
365     // Throw stack overflow exception with preinitialized exception.
366     Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
367     return;
368   } else {
369     // Touch pages checked if the OS needs them to be touched to be mapped.
370     os::map_stack_shadow_pages(sp);
371   }
372 












373   // do call
374   { JavaCallWrapper link(method, receiver, result, CHECK);
375     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
376 
377       // NOTE: if we move the computation of the result_val_address inside
378       // the call to call_stub, the optimizer produces wrong code.
379       intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
380       intptr_t* parameter_address = args->parameters();
381 
382       address entry_point;
383       {
384         // The enter_interp_only_mode use handshake to set interp_only mode
385         // so no safepoint should be allowed between is_interp_only_mode() and call
386         NoSafepointVerifier nsv;
387         if (JvmtiExport::can_post_interpreter_events() && thread->is_interp_only_mode()) {

388           entry_point = method->interpreter_entry();
389         } else {
390           // Since the call stub sets up like the interpreter we call the from_interpreted_entry
391           // so we can go compiled via a i2c.
392           entry_point = method->from_interpreted_entry();
393         }
394       }
395       {
396         MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXExec, thread));
397         StubRoutines::call_stub()(
398           (address)&link,
399           // (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
400           result_val_address,          // see NOTE above (compiler problem)
401           result_type,
402           method(),
403           entry_point,
404           parameter_address,
405           args->size_of_parameters(),
406           CHECK
407         );
408       }
409 
410       result = link.result();  // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)
411       // Preserve oop return value across possible gc points
412       if (oop_result_flag) {
413         thread->set_vm_result_oop(result->get_oop());
414       }
415     }
416   } // Exit JavaCallWrapper (can block - potential return oop must be preserved)
417 
418   // Check if a thread stop or suspend should be executed
419   // The following assert was not realistic.  Thread.stop can set that bit at any moment.
420   //assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed");
421 
422   // Restore possible oop return
423   if (oop_result_flag) {
424     result->set_oop(thread->vm_result_oop());
425     thread->set_vm_result_oop(nullptr);

426   }
427 }
428 
429 
430 //--------------------------------------------------------------------------------------
431 // Implementation of JavaCallArguments
432 
433 inline bool is_value_state_indirect_oop(uint state) {
434   assert(state != JavaCallArguments::value_state_oop,
435          "Checking for handles after removal");
436   assert(state < JavaCallArguments::value_state_limit,
437          "Invalid value state %u", state);
438   return state != JavaCallArguments::value_state_primitive;
439 }
440 
441 inline oop resolve_indirect_oop(intptr_t value, uint state) {
442   switch (state) {
443   case JavaCallArguments::value_state_handle:
444   {
445     oop* ptr = reinterpret_cast<oop*>(value);

554     case T_INT:
555     case T_FLOAT:  // this one also
556       check_single_word(); break;
557     case T_LONG:
558     case T_DOUBLE:
559       check_double_word(); break;
560     case T_ARRAY:
561     case T_OBJECT:
562       check_reference(); break;
563     default:
564       ShouldNotReachHere();
565     }
566   }
567 };
568 
569 
570 void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {
571   guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
572 
573   // Treat T_OBJECT and T_ARRAY as the same
574   if (is_reference_type(return_type)) return_type = T_OBJECT;
575 
576   // Check that oop information is correct
577   Symbol* signature = method->signature();
578 
579   SignatureChekker sc(signature,
580                       return_type,
581                       method->is_static(),
582                       _value_state,
583                       _value);
584 }

 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #include "classfile/vmSymbols.hpp"
 27 #include "code/nmethod.hpp"
 28 #include "compiler/compilationPolicy.hpp"
 29 #include "compiler/compileBroker.hpp"
 30 #include "interpreter/interpreter.hpp"
 31 #include "interpreter/linkResolver.hpp"
 32 #include "memory/universe.hpp"
 33 #include "oops/inlineKlass.hpp"
 34 #include "oops/method.inline.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "prims/jniCheck.hpp"
 37 #include "prims/jvmtiExport.hpp"
 38 #include "runtime/handles.inline.hpp"
 39 #include "runtime/interfaceSupport.inline.hpp"
 40 #include "runtime/javaCalls.hpp"
 41 #include "runtime/javaThread.hpp"
 42 #include "runtime/jniHandles.inline.hpp"
 43 #include "runtime/mutexLocker.hpp"
 44 #include "runtime/os.inline.hpp"
 45 #include "runtime/sharedRuntime.hpp"
 46 #include "runtime/signature.hpp"
 47 #include "runtime/stubRoutines.hpp"
 48 #include "runtime/thread.inline.hpp"
 49 
 50 // -----------------------------------------------------
 51 // Implementation of JavaCallWrapper
 52 
 53 JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS) {

118 
119   if (_thread->has_pending_exception() && _thread->has_last_Java_frame()) {
120     // If we get here, the Java code threw an exception that unwound a frame.
121     // It could be that the new frame anchor has not passed through the required
122     // StackWatermark barriers. Therefore, we process any such deferred unwind
123     // requests here.
124     StackWatermarkSet::after_unwind(_thread);
125   }
126 }
127 
128 
129 void JavaCallWrapper::oops_do(OopClosure* f) {
130   f->do_oop((oop*)&_receiver);
131   handles()->oops_do(f);
132 }
133 
134 
135 // Helper methods
136 static BasicType runtime_type_from(JavaValue* result) {
137   switch (result->get_type()) {
138     case T_BOOLEAN  : // fall through
139     case T_CHAR     : // fall through
140     case T_SHORT    : // fall through
141     case T_INT      : // fall through
142 #ifndef _LP64
143     case T_OBJECT   : // fall through
144     case T_ARRAY    : // fall through
145     case T_FLAT_ELEMENT: // fall through
146 #endif
147     case T_BYTE     : // fall through
148     case T_VOID     : return T_INT;
149     case T_LONG     : return T_LONG;
150     case T_FLOAT    : return T_FLOAT;
151     case T_DOUBLE   : return T_DOUBLE;
152 #ifdef _LP64
153     case T_ARRAY    : // fall through
154     case T_OBJECT   : return T_OBJECT;
155 #endif
156     default:
157       ShouldNotReachHere();
158       return T_ILLEGAL;
159   }
160 }
161 
162 // ============ Virtual calls ============
163 
164 void JavaCalls::call_virtual(JavaValue* result, Klass* spec_klass, Symbol* name, Symbol* signature, JavaCallArguments* args, TRAPS) {
165   CallInfo callinfo;
166   Handle receiver = args->receiver();
167   Klass* recvrKlass = receiver.is_null() ? (Klass*)nullptr : receiver->klass();
168   LinkInfo link_info(spec_klass, name, signature);
169   LinkResolver::resolve_virtual_call(
170           callinfo, receiver, recvrKlass, link_info, true, CHECK);
171   methodHandle method(THREAD, callinfo.selected_method());
172   assert(method.not_null(), "should have thrown exception");
173 
174   // Invoke the method

355   // Find receiver
356   Handle receiver = (!method->is_static()) ? args->receiver() : Handle();
357 
358   // When we reenter Java, we need to re-enable the reserved/yellow zone which
359   // might already be disabled when we are in VM.
360   thread->stack_overflow_state()->reguard_stack_if_needed();
361 
362   // Check that there are shadow pages available before changing thread state
363   // to Java. Calculate current_stack_pointer here to make sure
364   // stack_shadow_pages_available() and map_stack_shadow_pages() use the same sp.
365   address sp = os::current_stack_pointer();
366   if (!os::stack_shadow_pages_available(THREAD, method, sp)) {
367     // Throw stack overflow exception with preinitialized exception.
368     Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method);
369     return;
370   } else {
371     // Touch pages checked if the OS needs them to be touched to be mapped.
372     os::map_stack_shadow_pages(sp);
373   }
374 
375   jobject value_buffer = nullptr;
376   if (InlineTypeReturnedAsFields && (result->get_type() == T_OBJECT)) {
377     // Pre allocate a buffered inline type in case the result is returned
378     // flattened by compiled code
379     InlineKlass* vk = method->returns_inline_type();
380     if (vk != nullptr && vk->can_be_returned_as_fields()) {
381       oop instance = vk->allocate_instance(CHECK);
382       value_buffer = JNIHandles::make_local(thread, instance);
383       result->set_jobject(value_buffer);
384     }
385   }
386 
387   // do call
388   { JavaCallWrapper link(method, receiver, result, CHECK);
389     { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
390 
391       // NOTE: if we move the computation of the result_val_address inside
392       // the call to call_stub, the optimizer produces wrong code.
393       intptr_t* result_val_address = (intptr_t*)(result->get_value_addr());
394       intptr_t* parameter_address = args->parameters();
395 
396       address entry_point;
397       {
398         // The enter_interp_only_mode use handshake to set interp_only mode
399         // so no safepoint should be allowed between is_interp_only_mode() and call
400         NoSafepointVerifier nsv;
401         bool is_interp_only_mode = (StressCallingConvention && (os::random() % (1 << 10)) == 0) || thread->is_interp_only_mode();
402         if (JvmtiExport::can_post_interpreter_events() && is_interp_only_mode) {
403           entry_point = method->interpreter_entry();
404         } else {
405           // Since the call stub sets up like the interpreter we call the from_interpreted_entry
406           // so we can go compiled via a i2c.
407           entry_point = method->from_interpreted_entry();
408         }
409       }
410       {
411         MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXExec, thread));
412         StubRoutines::call_stub()(
413           (address)&link,
414           // (intptr_t*)&(result->_value), // see NOTE above (compiler problem)
415           result_val_address,          // see NOTE above (compiler problem)
416           result_type,
417           method(),
418           entry_point,
419           parameter_address,
420           args->size_of_parameters(),
421           CHECK
422         );
423       }
424 
425       result = link.result();  // circumvent MS C++ 5.0 compiler bug (result is clobbered across call)
426       // Preserve oop return value across possible gc points
427       if (oop_result_flag) {
428         thread->set_vm_result_oop(result->get_oop());
429       }
430     }
431   } // Exit JavaCallWrapper (can block - potential return oop must be preserved)
432 
433   // Check if a thread stop or suspend should be executed
434   // The following assert was not realistic.  Thread.stop can set that bit at any moment.
435   //assert(!thread->has_special_runtime_exit_condition(), "no async. exceptions should be installed");
436 
437   // Restore possible oop return
438   if (oop_result_flag) {
439     result->set_oop(thread->vm_result_oop());
440     thread->set_vm_result_oop(nullptr);
441     JNIHandles::destroy_local(value_buffer);
442   }
443 }
444 
445 
446 //--------------------------------------------------------------------------------------
447 // Implementation of JavaCallArguments
448 
449 inline bool is_value_state_indirect_oop(uint state) {
450   assert(state != JavaCallArguments::value_state_oop,
451          "Checking for handles after removal");
452   assert(state < JavaCallArguments::value_state_limit,
453          "Invalid value state %u", state);
454   return state != JavaCallArguments::value_state_primitive;
455 }
456 
457 inline oop resolve_indirect_oop(intptr_t value, uint state) {
458   switch (state) {
459   case JavaCallArguments::value_state_handle:
460   {
461     oop* ptr = reinterpret_cast<oop*>(value);

570     case T_INT:
571     case T_FLOAT:  // this one also
572       check_single_word(); break;
573     case T_LONG:
574     case T_DOUBLE:
575       check_double_word(); break;
576     case T_ARRAY:
577     case T_OBJECT:
578       check_reference(); break;
579     default:
580       ShouldNotReachHere();
581     }
582   }
583 };
584 
585 
586 void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {
587   guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
588 
589   // Treat T_OBJECT and T_ARRAY as the same
590   if (return_type == T_ARRAY) return_type = T_OBJECT;
591 
592   // Check that oop information is correct
593   Symbol* signature = method->signature();
594 
595   SignatureChekker sc(signature,
596                       return_type,
597                       method->is_static(),
598                       _value_state,
599                       _value);
600 }
< prev index next >