< prev index next >

src/hotspot/share/runtime/reflection.cpp

Print this page
*** 34,10 ***
--- 34,11 ---
  #include "jvm.h"
  #include "logging/log.hpp"
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "oops/instanceKlass.inline.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"

*** 50,10 ***
--- 51,11 ---
  #include "runtime/reflection.hpp"
  #include "runtime/reflectionUtils.hpp"
  #include "runtime/signature.hpp"
  #include "runtime/vframe.inline.hpp"
  #include "utilities/formatBuffer.hpp"
+ #include "utilities/globalDefinitions.hpp"
  
  static void trace_class_resolution(oop mirror) {
    if (mirror == nullptr || java_lang_Class::is_primitive(mirror)) {
      return;
    }

*** 345,11 ***
    } else {
      Klass* k = java_lang_Class::as_Klass(element_mirror);
      if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
      }
!     return oopFactory::new_objArray(k, length, THREAD);
    }
  }
  
  
  arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {
--- 347,15 ---
    } else {
      Klass* k = java_lang_Class::as_Klass(element_mirror);
      if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
        THROW_0(vmSymbols::java_lang_IllegalArgumentException());
      }
!     if (k->is_inline_klass() && java_lang_Class::is_secondary_mirror(element_mirror)) {
+       return oopFactory::new_valueArray(k, length, THREAD);
+     } else {
+       return oopFactory::new_objArray(k, length, THREAD);
+     }
    }
  }
  
  
  arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {

*** 386,11 ***
          THROW_0(vmSymbols::java_lang_IllegalArgumentException());
        }
        dim += k_dim;
      }
    }
!   klass = klass->array_klass(dim, CHECK_NULL);
    oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
    assert(obj->is_array(), "just checking");
    return arrayOop(obj);
  }
  
--- 392,15 ---
          THROW_0(vmSymbols::java_lang_IllegalArgumentException());
        }
        dim += k_dim;
      }
    }
!   if (klass->is_inline_klass() && java_lang_Class::is_secondary_mirror(element_mirror)) {
+     klass = InlineKlass::cast(klass)->value_array_klass(dim, CHECK_NULL);
+   } else {
+     klass = klass->array_klass(dim, CHECK_NULL);
+   }
    oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
    assert(obj->is_array(), "just checking");
    return arrayOop(obj);
  }
  

*** 763,20 ***
  }
  
  static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
    ResolvingSignatureStream ss(signature, k, false);
    oop nt = ss.as_java_mirror(SignatureStream::NCDFError, CHECK_NH);
-   if (log_is_enabled(Debug, class, resolve)) {
-     trace_class_resolution(nt);
-   }
    return Handle(THREAD, nt);
  }
  
  oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
    // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
!   assert(!method()->is_initializer() ||
-          (for_constant_pool_access && method()->is_static()),
           "should call new_constructor instead");
    InstanceKlass* holder = method->method_holder();
    int slot = method->method_idnum();
  
    Symbol*  signature  = method->signature();
--- 773,16 ---
  }
  
  static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
    ResolvingSignatureStream ss(signature, k, false);
    oop nt = ss.as_java_mirror(SignatureStream::NCDFError, CHECK_NH);
    return Handle(THREAD, nt);
  }
  
  oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
    // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
!   assert(!method()->name()->starts_with('<') || for_constant_pool_access,
           "should call new_constructor instead");
    InstanceKlass* holder = method->method_holder();
    int slot = method->method_idnum();
  
    Symbol*  signature  = method->signature();

*** 821,11 ***
    return mh();
  }
  
  
  oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
!   assert(method()->is_initializer(), "should call new_method instead");
  
    InstanceKlass* holder = method->method_holder();
    int slot = method->method_idnum();
  
    Symbol*  signature  = method->signature();
--- 827,13 ---
    return mh();
  }
  
  
  oop Reflection::new_constructor(const methodHandle& method, TRAPS) {
!   assert(method()->is_object_constructor() ||
+          method()->is_static_vnew_factory(),
+          "should call new_method instead");
  
    InstanceKlass* holder = method->method_holder();
    int slot = method->method_idnum();
  
    Symbol*  signature  = method->signature();

*** 874,11 ***
    java_lang_reflect_Field::set_type(rh(), type());
    if (fd->is_trusted_final()) {
      java_lang_reflect_Field::set_trusted_final(rh());
    }
    // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
!   java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
    java_lang_reflect_Field::set_override(rh(), false);
    if (fd->has_generic_signature()) {
      Symbol*  gs = fd->generic_signature();
      Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
      java_lang_reflect_Field::set_signature(rh(), sig());
--- 882,12 ---
    java_lang_reflect_Field::set_type(rh(), type());
    if (fd->is_trusted_final()) {
      java_lang_reflect_Field::set_trusted_final(rh());
    }
    // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
!   int modifiers = fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS;
+   java_lang_reflect_Field::set_modifiers(rh(), modifiers);
    java_lang_reflect_Field::set_override(rh(), false);
    if (fd->has_generic_signature()) {
      Symbol*  gs = fd->generic_signature();
      Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
      java_lang_reflect_Field::set_signature(rh(), sig());

*** 989,12 ***
      if (!receiver->is_a(klass)) {
        THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
      }
      // target klass is receiver's klass
      target_klass = receiver->klass();
!     // no need to resolve if method is private or <init>
!     if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) {
        method = reflected_method;
      } else {
        // resolve based on the receiver
        if (reflected_method->method_holder()->is_interface()) {
          // resolve interface call
--- 998,14 ---
      if (!receiver->is_a(klass)) {
        THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class");
      }
      // target klass is receiver's klass
      target_klass = receiver->klass();
!     // no need to resolve if method is private, <init> or <vnew>
!     if (reflected_method->is_private() ||
+         reflected_method->name() == vmSymbols::object_initializer_name() ||
+         reflected_method->name() == vmSymbols::inline_factory_name()) {
        method = reflected_method;
      } else {
        // resolve based on the receiver
        if (reflected_method->method_holder()->is_interface()) {
          // resolve interface call

*** 1145,10 ***
--- 1156,12 ---
  
    oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror);
    BasicType rtype;
    if (java_lang_Class::is_primitive(return_type_mirror)) {
      rtype = basic_type_mirror_to_basic_type(return_type_mirror);
+   } else if (java_lang_Class::as_Klass(return_type_mirror)->is_inline_klass()) {
+     rtype = java_lang_Class::is_primary_mirror(return_type_mirror) ? T_OBJECT : T_PRIMITIVE_OBJECT;
    } else {
      rtype = T_OBJECT;
    }
  
    InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));

*** 1172,17 ***
    Method* m = klass->method_with_idnum(slot);
    if (m == nullptr) {
      THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
    }
    methodHandle method(THREAD, m);
-   assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor");
  
    // Make sure klass gets initialize
    klass->initialize(CHECK_NULL);
  
    // Create new instance (the receiver)
    klass->check_valid_for_instantiation(false, CHECK_NULL);
    Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
  
    // Ignore result from call and return receiver
    invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
    return receiver();
--- 1185,34 ---
    Method* m = klass->method_with_idnum(slot);
    if (m == nullptr) {
      THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke");
    }
    methodHandle method(THREAD, m);
  
    // Make sure klass gets initialize
    klass->initialize(CHECK_NULL);
  
    // Create new instance (the receiver)
    klass->check_valid_for_instantiation(false, CHECK_NULL);
+ 
+   // Special case for factory methods
+   if (!method->signature()->is_void_method_signature()) {
+     assert(klass->is_inline_klass(), "inline classes must use factory methods");
+     assert(method->name() == vmSymbols::inline_factory_name(), "wrong factory method name");
+     Handle no_receiver; // null instead of receiver
+     BasicType rtype;
+     if (klass->is_hidden()) {
+       rtype = T_OBJECT;
+     } else {
+       rtype = T_PRIMITIVE_OBJECT;
+     }
+     return invoke(klass, method, no_receiver, override, ptypes, rtype, args, false, CHECK_NULL);
+   }
+ 
+   // main branch of code creates a non-inline object:
+   assert(!klass->is_inline_klass(), "classic constructors are only for non-inline classes");
+   assert(method->name() == vmSymbols::object_initializer_name(), "wrong constructor name");
    Handle receiver = klass->allocate_instance_handle(CHECK_NULL);
  
    // Ignore result from call and return receiver
    invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL);
    return receiver();
< prev index next >