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.
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.