< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page

        

@@ -49,10 +49,11 @@
 #include "oops/method.inline.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "oops/typeArrayOop.inline.hpp"
+#include "oops/valueArrayKlass.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"

@@ -921,18 +922,31 @@
 
     java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
 
     // It might also have a component mirror.  This mirror must already exist.
     if (k->is_array_klass()) {
-      if (k->is_typeArray_klass()) {
+      if (k->is_valueArray_klass()) {
+        Klass* element_klass = (Klass*) ValueArrayKlass::cast(k)->element_klass();
+        assert(element_klass->is_value(), "Must be value type component");
+        ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
+        comp_mirror = Handle(THREAD, vk->value_mirror());
+      } else if (k->is_typeArray_klass()) {
         BasicType type = TypeArrayKlass::cast(k)->element_type();
         comp_mirror = Handle(THREAD, Universe::java_mirror(type));
       } else {
         assert(k->is_objArray_klass(), "Must be");
         Klass* element_klass = ObjArrayKlass::cast(k)->element_klass();
         assert(element_klass != NULL, "Must have an element klass");
-        comp_mirror = Handle(THREAD, element_klass->java_mirror());
+        if (element_klass->is_value()) {
+          ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
+          assert(vk->java_mirror() == vk->value_mirror(), "primary mirror is the value mirror");
+          assert(vk->indirect_mirror() != NULL, "must have an indirect class mirror");
+          comp_mirror = k->name()->is_Q_array_signature() ? Handle(THREAD, vk->value_mirror())
+                                                          : Handle(THREAD, vk->indirect_mirror());
+        } else {
+          comp_mirror = Handle(THREAD, element_klass->java_mirror());
+        }
       }
       assert(comp_mirror() != NULL, "must have a mirror");
 
       // Two-way link between the array klass and its component mirror:
       // (array_klass) k -> mirror -> component_mirror -> array_klass -> k

@@ -968,16 +982,45 @@
     if (comp_mirror() != NULL) {
       // Set after k->java_mirror() is published, because compiled code running
       // concurrently doesn't expect a k to have a null java_mirror.
       release_set_array_klass(comp_mirror(), k);
     }
+
+    if (k->is_value()) {
+      // create the secondary mirror for an inline class
+      oop indirect_mirror_oop = create_indirect_type_mirror(k, mirror, CHECK);
+      set_inline_type_mirror(mirror(), mirror());
+      set_indirect_type_mirror(mirror(), indirect_mirror_oop);
+    }
   } else {
     assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
     fixup_mirror_list()->push(k);
   }
 }
 
+// Create the secondary mirror for inline class. Sets all the fields of this java.lang.Class
+// instance with the same value as the primary mirror
+oop java_lang_Class::create_indirect_type_mirror(Klass* k, Handle mirror, TRAPS) {
+  assert(k->is_value(), "inline class");
+  // Allocate mirror (java.lang.Class instance)
+  oop mirror_oop = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
+  Handle indirect_mirror(THREAD, mirror_oop);
+
+  java_lang_Class::set_klass(indirect_mirror(), k);
+  java_lang_Class::set_static_oop_field_count(indirect_mirror(), static_oop_field_count(mirror()));
+  // ## do we need to set init lock?
+  java_lang_Class::set_init_lock(indirect_mirror(), init_lock(mirror()));
+
+  set_protection_domain(indirect_mirror(), protection_domain(mirror()));
+  set_class_loader(indirect_mirror(), class_loader(mirror()));
+  // ## handle if java.base is not yet defined
+  set_module(indirect_mirror(), module(mirror()));
+  set_inline_type_mirror(indirect_mirror(), mirror());
+  set_indirect_type_mirror(indirect_mirror(), indirect_mirror());
+  return indirect_mirror();
+}
+
 #if INCLUDE_CDS_JAVA_HEAP
 // Clears mirror fields. Static final fields with initial values are reloaded
 // from constant pool. The object identity hash is in the object header and is
 // not affected.
 class ResetMirrorField: public FieldClosure {

@@ -1381,10 +1424,30 @@
 void java_lang_Class::set_source_file(oop java_class, oop source_file) {
   assert(_source_file_offset != 0, "must be set");
   java_class->obj_field_put(_source_file_offset, source_file);
 }
 
+oop java_lang_Class::inline_type_mirror(oop java_class) {
+  assert(_inline_mirror_offset != 0, "must be set");
+  return java_class->obj_field(_inline_mirror_offset);
+}
+
+void java_lang_Class::set_inline_type_mirror(oop java_class, oop mirror) {
+  assert(_inline_mirror_offset != 0, "must be set");
+  java_class->obj_field_put(_inline_mirror_offset, mirror);
+}
+
+oop java_lang_Class::indirect_type_mirror(oop java_class) {
+  assert(_indirect_mirror_offset != 0, "must be set");
+  return java_class->obj_field(_indirect_mirror_offset);
+}
+
+void java_lang_Class::set_indirect_type_mirror(oop java_class, oop mirror) {
+  assert(_indirect_mirror_offset != 0, "must be set");
+  java_class->obj_field_put(_indirect_mirror_offset, mirror);
+}
+
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
   // This should be improved by adding a field at the Java level or by
   // introducing a new VM klass (see comment in ClassFileParser)
   oop java_class = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(NULL, CHECK_0);
   if (type != T_VOID) {

@@ -1425,22 +1488,30 @@
 
 void java_lang_Class::print_signature(oop java_class, outputStream* st) {
   assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   Symbol* name = NULL;
   bool is_instance = false;
+  bool is_value = false;
   if (is_primitive(java_class)) {
     name = vmSymbols::type_signature(primitive_type(java_class));
   } else {
     Klass* k = as_Klass(java_class);
     is_instance = k->is_instance_klass();
+    is_value = k->is_value();
     name = k->name();
   }
   if (name == NULL) {
     st->print("<null>");
     return;
   }
-  if (is_instance)  st->print("L");
+  if (is_instance)  {
+    if (is_value && (java_class == inline_type_mirror(java_class))) {
+      st->print("Q");
+    } else {
+      st->print("L");
+    }
+  }
   st->write((char*) name->base(), (int) name->utf8_length());
   if (is_instance)  st->print(";");
 }
 
 Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found) {

@@ -1457,12 +1528,18 @@
     if (!k->is_instance_klass()) {
       name = k->name();
       name->increment_refcount();
     } else {
       ResourceMark rm;
-      const char* sigstr = k->signature_name();
-      int         siglen = (int) strlen(sigstr);
+      const char* sigstr;
+      if (k->is_value()) {
+        char c = (java_class == inline_type_mirror(java_class)) ? 'Q' : 'L';
+        sigstr = InstanceKlass::cast(k)->signature_name_of(c);
+      } else {
+        sigstr = k->signature_name();
+      }
+      int siglen = (int) strlen(sigstr);
       if (!intern_if_not_found) {
         name = SymbolTable::probe(sigstr, siglen);
       } else {
         name = SymbolTable::new_symbol(sigstr, siglen);
       }

@@ -1543,10 +1620,12 @@
   macro(classRedefinedCount_offset, k, "classRedefinedCount", int_signature,         false) ; \
   macro(_class_loader_offset,       k, "classLoader",         classloader_signature, false); \
   macro(_component_mirror_offset,   k, "componentType",       class_signature,       false); \
   macro(_module_offset,             k, "module",              module_signature,      false); \
   macro(_name_offset,               k, "name",                string_signature,      false); \
+  macro(_inline_mirror_offset,      k, "inlineType",          class_signature,       false); \
+  macro(_indirect_mirror_offset,    k, "indirectType",        class_signature,       false); \
 
 void java_lang_Class::compute_offsets() {
   if (offsets_computed) {
     return;
   }

@@ -2389,12 +2468,12 @@
     }
     if (!skip_throwableInit_check) {
       assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
 
       // skip <init> methods of the exception class and superclasses
-      // This is simlar to classic VM.
-      if (method->name() == vmSymbols::object_initializer_name() &&
+      // This is similar to classic VM (before HotSpot).
+      if (method->is_object_constructor() &&
           throwable->is_a(method->method_holder())) {
         continue;
       } else {
         // there are none or we've seen them all - either way stop checking
         skip_throwableInit_check = true;

@@ -3589,11 +3668,11 @@
   return method == NULL ? NULL : java_lang_invoke_ResolvedMethodName::vmtarget(method);
 }
 
 bool java_lang_invoke_MemberName::is_method(oop mname) {
   assert(is_instance(mname), "must be MemberName");
-  return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
+  return (flags(mname) & (MN_IS_METHOD | MN_IS_OBJECT_CONSTRUCTOR)) > 0;
 }
 
 void java_lang_invoke_MemberName::set_method(oop mname, oop resolved_method) {
   assert(is_instance(mname), "wrong type");
   mname->obj_field_put(_method_offset, resolved_method);

@@ -4074,10 +4153,12 @@
 int java_lang_Class::_static_oop_field_count_offset;
 int java_lang_Class::_class_loader_offset;
 int java_lang_Class::_module_offset;
 int java_lang_Class::_protection_domain_offset;
 int java_lang_Class::_component_mirror_offset;
+int java_lang_Class::_inline_mirror_offset;
+int java_lang_Class::_indirect_mirror_offset;
 int java_lang_Class::_init_lock_offset;
 int java_lang_Class::_signers_offset;
 int java_lang_Class::_name_offset;
 int java_lang_Class::_source_file_offset;
 GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
< prev index next >