< prev index next >

src/hotspot/share/runtime/javaCalls.cpp

Print this page
@@ -31,10 +31,11 @@
  #include "interpreter/interpreter.hpp"
  #include "interpreter/linkResolver.hpp"
  #include "memory/universe.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/oop.inline.hpp"
+ #include "oops/inlineKlass.hpp"
  #include "prims/jniCheck.hpp"
  #include "prims/jvmtiExport.hpp"
  #include "runtime/handles.inline.hpp"
  #include "runtime/interfaceSupport.inline.hpp"
  #include "runtime/javaCalls.hpp"

@@ -144,26 +145,27 @@
  
  
  // Helper methods
  static BasicType runtime_type_from(JavaValue* result) {
    switch (result->get_type()) {
-     case T_BOOLEAN: // fall through
-     case T_CHAR   : // fall through
-     case T_SHORT  : // fall through
-     case T_INT    : // fall through
+     case T_BOOLEAN  : // fall through
+     case T_CHAR     : // fall through
+     case T_SHORT    : // fall through
+     case T_INT      : // fall through
  #ifndef _LP64
-     case T_OBJECT : // fall through
-     case T_ARRAY  : // fall through
+     case T_OBJECT   : // fall through
+     case T_ARRAY    : // fall through
+     case T_PRIMITIVE_OBJECT: // fall through
  #endif
-     case T_BYTE   : // fall through
-     case T_VOID   : return T_INT;
-     case T_LONG   : return T_LONG;
-     case T_FLOAT  : return T_FLOAT;
-     case T_DOUBLE : return T_DOUBLE;
+     case T_BYTE     : // fall through
+     case T_VOID     : return T_INT;
+     case T_LONG     : return T_LONG;
+     case T_FLOAT    : return T_FLOAT;
+     case T_DOUBLE   : return T_DOUBLE;
  #ifdef _LP64
-     case T_ARRAY  : // fall through
-     case T_OBJECT:  return T_OBJECT;
+     case T_ARRAY    : // fall through
+     case T_OBJECT   : return T_OBJECT;
  #endif
      default:
        ShouldNotReachHere();
        return T_ILLEGAL;
    }

@@ -388,10 +390,22 @@
    } else {
      // Touch pages checked if the OS needs them to be touched to be mapped.
      os::map_stack_shadow_pages(sp);
    }
  
+   jobject value_buffer = nullptr;
+   if (InlineTypeReturnedAsFields && (result->get_type() == T_OBJECT)) {
+     // Pre allocate a buffered inline type in case the result is returned
+     // flattened by compiled code
+     InlineKlass* vk = method->returns_inline_type(thread);
+     if (vk != nullptr && vk->can_be_returned_as_fields()) {
+       oop instance = vk->allocate_instance(CHECK);
+       value_buffer = JNIHandles::make_local(thread, instance);
+       result->set_jobject(value_buffer);
+     }
+   }
+ 
    // do call
    { JavaCallWrapper link(method, receiver, result, CHECK);
      { HandleMark hm(thread);  // HandleMark used by HandleMarkCleaner
  
        // NOTE: if we move the computation of the result_val_address inside

@@ -438,10 +452,11 @@
  
    // Restore possible oop return
    if (oop_result_flag) {
      result->set_oop(thread->vm_result());
      thread->set_vm_result(nullptr);
+     JNIHandles::destroy_local(value_buffer);
    }
  }
  
  
  //--------------------------------------------------------------------------------------

@@ -586,11 +601,11 @@
  
  void JavaCallArguments::verify(const methodHandle& method, BasicType return_type) {
    guarantee(method->size_of_parameters() == size_of_parameters(), "wrong no. of arguments pushed");
  
    // Treat T_OBJECT and T_ARRAY as the same
-   if (is_reference_type(return_type)) return_type = T_OBJECT;
+   if (return_type == T_ARRAY) return_type = T_OBJECT;
  
    // Check that oop information is correct
    Symbol* signature = method->signature();
  
    SignatureChekker sc(signature,
< prev index next >