< 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,28 @@
  
  
  // 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;
+     case T_PRIMITIVE_OBJECT: return T_PRIMITIVE_OBJECT;
  #endif
      default:
        ShouldNotReachHere();
        return T_ILLEGAL;
    }

@@ -287,10 +290,23 @@
  
  // ============ allocate and initialize new object instance ============
  
  Handle JavaCalls::construct_new_instance(InstanceKlass* klass, Symbol* constructor_signature, JavaCallArguments* args, TRAPS) {
    klass->initialize(CHECK_NH); // Quick no-op if already initialized.
+ 
+   // Special case for factory methods
+   if (EnableValhalla && !constructor_signature->is_void_method_signature()) {
+     guarantee(klass->is_inline_klass(), "inline classes must use factory methods");
+     JavaValue factory_result(T_OBJECT);
+     JavaCalls::call_static(&factory_result, klass,
+                            vmSymbols::inline_factory_name(),
+                            constructor_signature, args, CHECK_NH);
+     return Handle(THREAD, factory_result.get_oop());
+   }
+ 
+   // main branch of code creates a non-inline object:
+   assert(!klass->is_inline_klass(), "classic constructors are only for non-inline classes");
    Handle obj = klass->allocate_instance_handle(CHECK_NH);
    JavaValue void_result(T_VOID);
    args->set_receiver(obj); // inserts <obj> as the first argument.
    JavaCalls::call_special(&void_result, klass,
                            vmSymbols::object_initializer_name(),

@@ -388,10 +404,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_PRIMITIVE_OBJECT || 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 +466,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);
    }
  }
  
  
  //--------------------------------------------------------------------------------------

@@ -574,10 +603,11 @@
      case T_LONG:
      case T_DOUBLE:
        check_double_word(); break;
      case T_ARRAY:
      case T_OBJECT:
+     case T_PRIMITIVE_OBJECT:
        check_reference(); break;
      default:
        ShouldNotReachHere();
      }
    }

@@ -586,11 +616,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 >