< prev index next >

src/hotspot/share/runtime/reflection.cpp

Print this page

        

@@ -38,10 +38,11 @@
 #include "memory/universe.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "oops/valueKlass.hpp"
 #include "oops/typeArrayOop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/handles.inline.hpp"

@@ -49,10 +50,11 @@
 #include "runtime/reflection.hpp"
 #include "runtime/reflectionUtils.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/vframe.inline.hpp"
+#include "utilities/globalDefinitions.hpp"
 
 static void trace_class_resolution(const Klass* to_class) {
   ResourceMark rm;
   int line_number = -1;
   const char * source_file = NULL;

@@ -90,11 +92,11 @@
 
 oop Reflection::box(jvalue* value, BasicType type, TRAPS) {
   if (type == T_VOID) {
     return NULL;
   }
-  if (type == T_OBJECT || type == T_ARRAY) {
+  if (type == T_OBJECT || type == T_ARRAY || type == T_VALUETYPE) {
     // regular objects are not boxed
     return (oop) value->l;
   }
   oop result = java_lang_boxing_object::create(type, value, CHECK_NULL);
   if (result == NULL) {

@@ -340,11 +342,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());
     }
-    return oopFactory::new_objArray(k, length, THREAD);
+    if (java_lang_Class::is_indirect_type(element_mirror)) {
+      return oopFactory::new_objArray(k, length, THREAD);
+    } else {
+      return oopFactory::new_valueArray(k, length, THREAD);
+    }
   }
 }
 
 
 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) {

@@ -381,11 +387,12 @@
         THROW_0(vmSymbols::java_lang_IllegalArgumentException());
       }
       dim += k_dim;
     }
   }
-  klass = klass->array_klass(dim, CHECK_NULL);
+  ArrayStorageProperties storage_props = FieldType::get_array_storage_properties(klass->name());
+  klass = klass->array_klass(storage_props, dim, CHECK_NULL);
   oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, CHECK_NULL);
   assert(obj->is_array(), "just checking");
   return arrayOop(obj);
 }
 

@@ -748,17 +755,28 @@
     outer->external_name(),
     inner->external_name()
   );
 }
 
+// Returns Q-mirror if qtype_if_value is true and k is a ValueKlass;
+// otherwise returns java_mirror or L-mirror for ValueKlass
+static oop java_mirror(Klass* k, jboolean qtype_if_value) {
+  if (k->is_value()) {
+    ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(k));
+    return qtype_if_value ? vk->value_mirror() : vk->indirect_mirror();
+  } else {
+    return k->java_mirror();
+  }
+}
+
 // Utility method converting a single SignatureStream element into java.lang.Class instance
 static oop get_mirror_from_signature(const methodHandle& method,
                                      SignatureStream* ss,
                                      TRAPS) {
 
-
-  if (T_OBJECT == ss->type() || T_ARRAY == ss->type()) {
+  BasicType bt = ss->type();
+  if (T_OBJECT == bt || T_ARRAY == bt || T_VALUETYPE == bt) {
     Symbol* name = ss->as_symbol();
     oop loader = method->method_holder()->class_loader();
     oop protection_domain = method->method_holder()->protection_domain();
     const Klass* k = SystemDictionary::resolve_or_fail(name,
                                                        Handle(THREAD, loader),

@@ -766,17 +784,17 @@
                                                        true,
                                                        CHECK_NULL);
     if (log_is_enabled(Debug, class, resolve)) {
       trace_class_resolution(k);
     }
-    return k->java_mirror();
+    return java_mirror((Klass*)k, bt == T_VALUETYPE);
   }
 
-  assert(ss->type() != T_VOID || ss->at_return_type(),
+  assert(bt != T_VOID || ss->at_return_type(),
     "T_VOID should only appear as return type");
 
-  return java_lang_Class::primitive_mirror(ss->type());
+  return java_lang_Class::primitive_mirror(bt);
 }
 
 static objArrayHandle get_parameter_types(const methodHandle& method,
                                           int parameter_count,
                                           oop* return_type,

@@ -808,11 +826,11 @@
 }
 
 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
   // Basic types
   BasicType type = vmSymbols::signature_type(signature);
-  if (type != T_OBJECT) {
+  if (type != T_OBJECT && type != T_VALUETYPE) {
     return Handle(THREAD, Universe::java_mirror(type));
   }
 
   Klass* result =
     SystemDictionary::resolve_or_fail(signature,

@@ -821,20 +839,18 @@
                                       true, CHECK_(Handle()));
 
   if (log_is_enabled(Debug, class, resolve)) {
     trace_class_resolution(result);
   }
-
-  oop nt = result->java_mirror();
+  oop nt = java_mirror(result, type == T_VALUETYPE);
   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()),
+  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();

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

@@ -930,11 +948,20 @@
   java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror());
   java_lang_reflect_Field::set_slot(rh(), fd->index());
   java_lang_reflect_Field::set_name(rh(), name());
   java_lang_reflect_Field::set_type(rh(), type());
   // 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);
+  int modifiers = fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS;
+  if (fd->is_flattenable()) {
+    modifiers |= JVM_ACC_FIELD_FLATTENABLE;
+    // JVM_ACC_FLATTENABLE should not be set in LWorld.  set_is_flattenable should be re-examined.
+    modifiers &= ~JVM_ACC_FLATTENABLE;
+  }
+  if (fd->is_flattened()) {
+    modifiers |= JVM_ACC_FIELD_FLATTENED;
+  }
+  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());

@@ -1205,10 +1232,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, CHECK_NULL);
+  } else if (java_lang_Class::inline_type_mirror(return_type_mirror) == return_type_mirror) {
+    rtype = T_VALUETYPE;
   } else {
     rtype = T_OBJECT;
   }
 
   InstanceKlass* klass = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));

@@ -1239,10 +1268,20 @@
   // 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_value(), "inline classes must use factory methods");
+    Handle no_receiver; // null instead of receiver
+    return invoke(klass, method, no_receiver, override, ptypes, T_VALUETYPE, args, false, CHECK_NULL);
+  }
+
+  // main branch of code creates a non-inline object:
+  assert(!klass->is_value(), "classic constructors are only for non-inline classes");
   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 >