< prev index next >

src/hotspot/share/runtime/javaCalls.cpp

Print this page
*** 34,10 ***
--- 34,11 ---
  #include "jvmci/jvmciJavaClasses.hpp"
  #endif
  #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"

*** 145,26 ***
  
  
  // 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
  #ifndef _LP64
!     case T_OBJECT : // fall through
!     case T_ARRAY  : // 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;
  #ifdef _LP64
!     case T_ARRAY  : // fall through
!     case T_OBJECT:  return T_OBJECT;
  #endif
      default:
        ShouldNotReachHere();
        return T_ILLEGAL;
    }
--- 146,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
  #ifndef _LP64
!     case T_OBJECT   : // fall through
!     case T_ARRAY    : // fall through
+     case T_INLINE_TYPE: // 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;
  #ifdef _LP64
!     case T_ARRAY    : // fall through
!     case T_OBJECT   : return T_OBJECT;
+     case T_INLINE_TYPE: return T_INLINE_TYPE;
  #endif
      default:
        ShouldNotReachHere();
        return T_ILLEGAL;
    }

*** 288,10 ***
--- 291,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 (!constructor_signature->is_void_method_signature()) {
+     assert(klass->is_inline_klass(), "inline classes must use factory methods");
+     JavaValue factory_result(T_OBJECT);
+     JavaCalls::call_static(&factory_result, klass,
+                            vmSymbols::object_initializer_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(),

*** 389,10 ***
--- 405,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 = NULL;
+   if (InlineTypeReturnedAsFields && result->get_type() == T_INLINE_TYPE) {
+     // Pre allocate a buffered inline type in case the result is returned
+     // flattened by compiled code
+     InlineKlass* vk = method->returned_inline_type(thread);
+     if (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

*** 439,10 ***
--- 467,11 ---
  
    // Restore possible oop return
    if (oop_result_flag) {
      result->set_oop(thread->vm_result());
      thread->set_vm_result(NULL);
+     JNIHandles::destroy_local(value_buffer);
    }
  }
  
  
  //--------------------------------------------------------------------------------------

*** 575,10 ***
--- 604,11 ---
      case T_LONG:
      case T_DOUBLE:
        check_double_word(); break;
      case T_ARRAY:
      case T_OBJECT:
+     case T_INLINE_TYPE:
        check_reference(); break;
      default:
        ShouldNotReachHere();
      }
    }

*** 587,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;
  
    // Check that oop information is correct
    Symbol* signature = method->signature();
  
    SignatureChekker sc(signature,
--- 617,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 (return_type == T_ARRAY) return_type = T_OBJECT;
  
    // Check that oop information is correct
    Symbol* signature = method->signature();
  
    SignatureChekker sc(signature,
< prev index next >