Search code examples
javajvmjvm-hotspot

How do String oops and mirror oops generate by Hotspot VM?


In openjdk8 source code, I find that some java.lang.String oop do not go through bytecode engine and allocate by jvm itself. As hotspot/src/share/vm/classfile/javaClasses.cpp:185 says:

Handle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) {
  Handle h_obj = basic_create(length, CHECK_NH); // alloc size of java.lang.String oop
  typeArrayOop buffer = value(h_obj());
  for (int index = 0; index < length; index++) {
    buffer->char_at_put(index, unicode[index]);  // put a char[] into this oop...
  }
  return h_obj;
}

As above, a fake String is created... however, java.lang.String has five member variables (fields), how do they initialize? In other words, how does these fake String oop become the real java.lang.String object?

Same as java.lang.String, java.lang.Class also does this things. At hotspot/src/share/vm/classfile/javaClasses.cpp:553 says:

oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
    ...
    Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
    ...
    // if `k` holds a InstanceKlass, it will initialize the static fields by constant value attribute. else do nothing...
}

I was very confused by this. Only alloc memory, if it is java.lang.String's object, put a char[] into it; but when do the other fields in java.lang.String and java.lang.Class fills in to the oop? Thank you.


Solution

  • java_lang_String::basic_create() allocates String object and initializes its value field:

        obj = InstanceKlass::cast(SystemDictionary::String_klass())->allocate_instance(CHECK_NH);
    
        // Create the char array.  The String object must be handlized here
        // because GC can happen as a result of the allocation attempt.
        Handle h_obj(THREAD, obj);
        typeArrayOop buffer;
          buffer = oopFactory::new_charArray(length, CHECK_NH);
    
        // Point the String at the char array
        obj = h_obj();
        set_value(obj, buffer);   <<<--- char[] value is set here
      // No need to zero the offset, allocation zero'ed the entire String object
      assert(offset(obj) == 0, "initial String offset should be zero");
    //set_offset(obj, 0);
      set_count(obj, length);
    

    hash field is computed lazily. At allocation time it has the default value 0 since allocate_instance clears the entire object. There are no other String instance fields in JDK 8.

    As to java.lang.Class, it has no fields to initialize at allocation time, because all its fields are kind of caches. They are set in Java code when needed. Again, the entire Class instance is zeroed by allocation routine.