/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// Helpful routine for computing field offsets at run time rather than hardcoding them // Finds local fields only, including static fields. Static field offsets are from the // beginning of the mirror. void JavaClasses::compute_offset(int &dest_offset,
InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol, bool is_static) {
fieldDescriptor fd; if (ik == NULL) {
ResourceMark rm;
log_error(class)("Mismatch JDK version for field: %s type: %s", name_symbol->as_C_string(), signature_symbol->as_C_string());
vm_exit_during_initialization("Invalid layout of well-known class");
}
if (!ik->find_local_field(name_symbol, signature_symbol, &fd) || fd.is_static() != is_static) {
ResourceMark rm;
log_error(class)("Invalid layout of %s field: %s type: %s", ik->external_name(),
name_symbol->as_C_string(), signature_symbol->as_C_string()); #ifndef PRODUCT // Prints all fields and offsets
Log(class) lt;
LogStream ls(lt.error());
ik->print_on(&ls); #endif//PRODUCT
vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
}
dest_offset = fd.offset();
}
// Overloading to pass name as a string. void JavaClasses::compute_offset(int& dest_offset, InstanceKlass* ik, constchar* name_string, Symbol* signature_symbol, bool is_static) {
TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string)); if (name == NULL) {
ResourceMark rm;
log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
}
compute_offset(dest_offset, ik, name, signature_symbol, is_static);
}
// java_lang_String
int java_lang_String::_value_offset; int java_lang_String::_hash_offset; int java_lang_String::_hashIsZero_offset; int java_lang_String::_coder_offset; int java_lang_String::_flags_offset;
bool java_lang_String::_initialized;
bool java_lang_String::test_and_set_flag(oop java_string, uint8_t flag_mask) {
uint8_t* addr = flags_addr(java_string);
uint8_t value = Atomic::load(addr); while ((value & flag_mask) == 0) {
uint8_t old_value = value;
value |= flag_mask;
value = Atomic::cmpxchg(addr, old_value, value); if (value == old_value) returnfalse; // Flag bit changed from 0 to 1.
} returntrue; // Flag bit is already 1.
}
Handle java_lang_String::basic_create(int length, bool is_latin1, TRAPS) {
assert(_initialized, "Must be initialized");
assert(CompactStrings || !is_latin1, "Must be UTF16 without CompactStrings");
// Create the String object first, so there's a chance that the String // and the char array it points to end up in the same cache line.
oop obj;
obj = vmClasses::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); int arr_length = is_latin1 ? length : length << 1; // 2 bytes per UTF16.
typeArrayOop buffer = oopFactory::new_byteArray(arr_length, CHECK_NH);;
// Point the String at the char array
obj = h_obj();
set_value(obj, buffer); // No need to zero the offset, allocation zero'ed the entire String object
set_coder(obj, is_latin1 ? CODER_LATIN1 : CODER_UTF16); return h_obj;
}
Handle java_lang_String::create_from_unicode(const jchar* unicode, int length, TRAPS) { bool is_latin1 = CompactStrings && UNICODE::is_latin1(unicode, length);
Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
typeArrayOop buffer = value(h_obj());
assert(TypeArrayKlass::cast(buffer->klass())->element_type() == T_BYTE, "only byte[]"); if (is_latin1) { for (int index = 0; index < length; index++) {
buffer->byte_at_put(index, (jbyte)unicode[index]);
}
} else { for (int index = 0; index < length; index++) {
buffer->char_at_put(index, unicode[index]);
}
}
#ifdef ASSERT // This check is too strict when the input string is not a valid UTF8. // For example, it may be created with arbitrary content via jni_NewStringUTF. if (UTF8::is_legal_utf8((constunsignedchar*)utf8_str, (int)strlen(utf8_str), false)) {
ResourceMark rm; constchar* expected = utf8_str; char* actual = as_utf8_string(h_obj()); if (strcmp(expected, actual) != 0) {
fatal("String conversion failure: %s --> %s", expected, actual);
}
} #endif
// Converts a C string to a Java String based on current encoding
Handle java_lang_String::create_from_platform_dependent_str(constchar* str, TRAPS) {
assert(str != NULL, "bad arguments");
// Converts a Java String to a native C string that can be used for // native OS calls. char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) { typedefchar* (*to_platform_string_fn_t)(JNIEnv*, jstring, bool*); static to_platform_string_fn_t _to_platform_string_fn = NULL;
jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length); if (result != NULL) { if (!is_latin1) { for (int index = 0; index < length; index++) {
result[index] = value->char_at(index);
}
} else { for (int index = 0; index < length; index++) {
result[index] = ((jchar) value->byte_at(index)) & 0xff;
}
}
} return result;
}
inlineunsignedint java_lang_String::hash_code_impl(oop java_string, bool update) { // The hash and hashIsZero fields are subject to a benign data race, // making it crucial to ensure that any observable result of the // calculation in this method stays correct under any possible read of // these fields. Necessary restrictions to allow this to be correct // without explicit memory fences or similar concurrency primitives is // that we can ever only write to one of these two fields for a given // String instance, and that the computation is idempotent and derived // from immutable state
assert(_initialized && (_hash_offset > 0) && (_hashIsZero_offset > 0), "Must be initialized"); if (java_lang_String::hash_is_set(java_string)) { return java_string->int_field(_hash_offset);
}
typeArrayOop value = java_lang_String::value(java_string); int length = java_lang_String::length(java_string, value); bool is_latin1 = java_lang_String::is_latin1(java_string);
if (is_latin1 != is_latin2) { // Strings with different coders are never equal. returnfalse;
} return value_equals(value1, value2);
}
void java_lang_String::print(oop java_string, outputStream* st) {
assert(java_string->klass() == vmClasses::String_klass(), "must be java_string");
typeArrayOop value = java_lang_String::value_no_keepalive(java_string);
if (value == NULL) { // This can happen if, e.g., printing a String // object before its initializer has been called
st->print("NULL"); return;
}
int length = java_lang_String::length(java_string, value); bool is_latin1 = java_lang_String::is_latin1(java_string);
st->print("\""); for (int index = 0; index < length; index++) {
st->print("%c", (!is_latin1) ? value->char_at(index) :
((jchar) value->byte_at(index)) & 0xff );
}
st->print("\"");
}
// java_lang_Class
int java_lang_Class::_klass_offset; int java_lang_Class::_array_klass_offset; int java_lang_Class::_oop_size_offset; 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::_signers_offset; int java_lang_Class::_name_offset; int java_lang_Class::_source_file_offset; int java_lang_Class::_classData_offset; int java_lang_Class::_classRedefinedCount_offset;
#ifdef ASSERT inlinestaticvoid assert_valid_static_string_field(fieldDescriptor* fd) {
assert(fd->has_initial_value(), "caller should have checked this");
assert(fd->field_type() == T_OBJECT, "caller should have checked this"); // Can't use vmSymbols::string_signature() as fd->signature() may have been relocated // during DumpSharedSpaces
assert(fd->signature()->equals("Ljava/lang/String;"), "just checking");
} #endif
#if INCLUDE_CDS_JAVA_HEAP staticvoid initialize_static_string_field_for_dump(fieldDescriptor* fd, Handle mirror) {
DEBUG_ONLY(assert_valid_static_string_field(fd);)
assert(DumpSharedSpaces, "must be");
assert(HeapShared::is_archived_object_during_dumptime(mirror()), "must be"); // Archive the String field and update the pointer.
oop s = mirror()->obj_field(fd->offset());
oop archived_s = StringTable::create_archived_string(s);
mirror()->obj_field_put(fd->offset(), archived_s);
} #endif
staticvoid initialize_static_primitive_field(fieldDescriptor* fd, Handle mirror) {
assert(fd->has_initial_value(), "caller should have checked this");
BasicType t = fd->field_type(); switch (t) { case T_BYTE:
mirror()->byte_field_put(fd->offset(), fd->int_initial_value()); break; case T_BOOLEAN:
mirror()->bool_field_put(fd->offset(), fd->int_initial_value()); break; case T_CHAR:
mirror()->char_field_put(fd->offset(), fd->int_initial_value()); break; case T_SHORT:
mirror()->short_field_put(fd->offset(), fd->int_initial_value()); break; case T_INT:
mirror()->int_field_put(fd->offset(), fd->int_initial_value()); break; case T_FLOAT:
mirror()->float_field_put(fd->offset(), fd->float_initial_value()); break; case T_DOUBLE:
mirror()->double_field_put(fd->offset(), fd->double_initial_value()); break; case T_LONG:
mirror()->long_field_put(fd->offset(), fd->long_initial_value()); break; default: // Illegal ConstantValue attribute in class file should have been // caught during classfile parsing.
ShouldNotReachHere();
}
}
void java_lang_Class::fixup_mirror(Klass* k, TRAPS) {
assert(InstanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already");
// If the offset was read from the shared archive, it was fixed up already if (!k->is_shared()) { if (k->is_instance_klass()) { // During bootstrap, java.lang.Class wasn't loaded so static field // offsets were computed without the size added it. Go back and // update all the static field offsets to included the size. for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) { if (fs.access_flags().is_static()) { int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
fs.set_offset(real_offset);
}
}
}
}
// Set classData
set_class_data(mirror(), classData());
}
// Set the java.lang.Module module field in the java_lang_Class mirror void java_lang_Class::set_mirror_module_field(JavaThread* current, Klass* k, Handle mirror, Handle module) { if (module.is_null()) { // During startup, the module may be NULL only if java.base has not been defined yet. // Put the class on the fixup_module_list to patch later when the java.lang.Module // for java.base is known. But note that since we captured the NULL module another // thread may have completed that initialization.
bool javabase_was_defined = false;
{
MutexLocker m1(current, Module_lock); // Keep list of classes needing java.base module fixup if (!ModuleEntryTable::javabase_defined()) {
assert(k->java_mirror() != NULL, "Class's mirror is null");
k->class_loader_data()->inc_keep_alive();
assert(fixup_module_field_list() != NULL, "fixup_module_field_list not initialized");
fixup_module_field_list()->push(k);
} else {
javabase_was_defined = true;
}
}
// If java.base was already defined then patch this particular class with java.base. if (javabase_was_defined) {
ModuleEntry *javabase_entry = ModuleEntryTable::javabase_moduleEntry();
assert(javabase_entry != NULL && javabase_entry->module() != NULL, "Setting class module field, " JAVA_BASE_NAME " should be defined");
Handle javabase_handle(current, javabase_entry->module());
set_module(mirror(), javabase_handle());
}
} else {
assert(Universe::is_module_initialized() ||
(ModuleEntryTable::javabase_defined() &&
(module() == ModuleEntryTable::javabase_moduleEntry()->module())), "Incorrect java.lang.Module specification while creating mirror");
set_module(mirror(), module());
}
}
// Statically allocate fixup lists because they always get created. void java_lang_Class::allocate_fixup_lists() {
GrowableArray<Klass*>* mirror_list = new (mtClass) GrowableArray<Klass*>(40, mtClass);
set_fixup_mirror_list(mirror_list);
GrowableArray<Klass*>* module_list = new (mtModule) GrowableArray<Klass*>(500, mtModule);
set_fixup_module_field_list(module_list);
}
// Use this moment of initialization to cache modifier_flags also, // to support Class.getModifiers(). Instance classes recalculate // the cached flags after the class file is parsed, but before the // class is put into the system dictionary. int computed_modifiers = k->compute_modifier_flags();
k->set_modifier_flags(computed_modifiers); // Class_klass has to be loaded because it is used to allocate // the mirror. if (vmClasses::Class_klass_loaded()) { // Allocate mirror (java.lang.Class instance)
oop mirror_oop = InstanceMirrorKlass::cast(vmClasses::Class_klass())->allocate_instance(k, CHECK);
Handle mirror(THREAD, mirror_oop);
Handle comp_mirror;
// Setup indirection from mirror->klass
set_klass(mirror(), k);
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
assert(oop_size(mirror()) == mk->instance_size(k), "should have been set");
// It might also have a component mirror. This mirror must already exist. if (k->is_array_klass()) { 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());
}
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
set_component_mirror(mirror(), comp_mirror()); // See below for ordering dependencies between field array_klass in component mirror // and java_mirror in this klass.
} else {
assert(k->is_instance_klass(), "Must be");
initialize_mirror_fields(k, mirror, protection_domain, classData, THREAD); if (HAS_PENDING_EXCEPTION) { // If any of the fields throws an exception like OOM remove the klass field // from the mirror so GC doesn't follow it after the klass has been deallocated. // This mirror looks like a primitive type, which logically it is because it // it represents no class.
set_klass(mirror(), NULL); return;
}
}
// set the classLoader field in the java_lang_Class instance
assert(class_loader() == k->class_loader(), "should be same");
set_class_loader(mirror(), class_loader());
// Setup indirection from klass->mirror // after any exceptions can happen during allocations.
k->set_java_mirror(mirror);
// Set the module field in the java_lang_Class instance. This must be done // after the mirror is set.
set_mirror_module_field(THREAD, k, mirror, module);
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);
}
} else {
assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
fixup_mirror_list()->push(k);
}
}
#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 { private:
Handle _m;
void do_field(fieldDescriptor* fd) {
assert(DumpSharedSpaces, "dump time only");
assert(_m.not_null(), "Mirror cannot be NULL");
if (fd->is_static() && fd->has_initial_value()) {
initialize_static_field_for_dump(fd, _m); return;
}
BasicType ft = fd->field_type(); switch (ft) { case T_BYTE:
_m()->byte_field_put(fd->offset(), 0); break; case T_CHAR:
_m()->char_field_put(fd->offset(), 0); break; case T_DOUBLE:
_m()->double_field_put(fd->offset(), 0); break; case T_FLOAT:
_m()->float_field_put(fd->offset(), 0); break; case T_INT:
_m()->int_field_put(fd->offset(), 0); break; case T_LONG:
_m()->long_field_put(fd->offset(), 0); break; case T_SHORT:
_m()->short_field_put(fd->offset(), 0); break; case T_BOOLEAN:
_m()->bool_field_put(fd->offset(), false); break; case T_ARRAY: case T_OBJECT: { // It might be useful to cache the String field, but // for now just clear out any reference field
oop o = _m()->obj_field(fd->offset());
_m()->obj_field_put(fd->offset(), NULL); break;
} default:
ShouldNotReachHere(); break;
}
}
};
for (int t = T_BOOLEAN; t < T_VOID+1; t++) {
BasicType bt = (BasicType)t; if (!is_reference_type(bt)) {
oop m = Universe::java_mirror(bt);
assert(m != NULL, "sanity"); // Update the field at _array_klass_offset to point to the relocated array klass.
oop archived_m = HeapShared::archive_object(m);
assert(archived_m != NULL, "sanity");
// Clear the fields. Just to be safe
Klass *k = m->klass();
Handle archived_mirror_h(Thread::current(), archived_m);
ResetMirrorField reset(archived_mirror_h);
InstanceKlass::cast(k)->do_nonstatic_fields(&reset);
Universe::set_archived_basic_type_mirror_index(bt, HeapShared::append_root(archived_m));
}
}
} // // After the mirror object is successfully archived, the archived // klass is set with _has_archived_raw_mirror flag. // // The _has_archived_raw_mirror flag is cleared at runtime when the // archived mirror is restored. If archived java heap data cannot // be used at runtime, new mirror object is created for the shared // class. The _has_archived_raw_mirror is cleared also during the process.
oop java_lang_Class::archive_mirror(Klass* k) {
assert(HeapShared::can_write(), "must be");
// Mirror is already archived if (k->has_archived_mirror_index()) {
assert(k->archived_java_mirror() != NULL, "no archived mirror"); return k->archived_java_mirror();
}
// No mirror
oop mirror = k->java_mirror(); if (mirror == NULL) { return NULL;
}
if (k->is_instance_klass()) {
InstanceKlass *ik = InstanceKlass::cast(k);
assert(ik->signers() == NULL, "class with signer should have been excluded");
if (!(ik->is_shared_boot_class() || ik->is_shared_platform_class() ||
ik->is_shared_app_class())) { // Archiving mirror for classes from non-builtin loaders is not // supported. return NULL;
}
}
// Now start archiving the mirror object
oop archived_mirror = HeapShared::archive_object(mirror); if (archived_mirror == NULL) { return NULL;
}
// The process is based on create_mirror().
oop java_lang_Class::process_archived_mirror(Klass* k, oop mirror,
oop archived_mirror) { // Clear nonstatic fields in archived mirror. Some of the fields will be set // to archived metadata and objects below.
Klass *c = archived_mirror->klass();
Handle archived_mirror_h(Thread::current(), archived_mirror);
ResetMirrorField reset(archived_mirror_h);
InstanceKlass::cast(c)->do_nonstatic_fields(&reset);
if (k->is_array_klass()) {
oop archived_comp_mirror; if (k->is_typeArray_klass()) { // The primitive type mirrors are already archived. Get the archived mirror.
oop comp_mirror = component_mirror(mirror);
archived_comp_mirror = HeapShared::find_archived_heap_object(comp_mirror);
assert(archived_comp_mirror != NULL, "Must be");
} 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");
archived_comp_mirror = archive_mirror(element_klass); if (archived_comp_mirror == NULL) { return NULL;
}
}
set_component_mirror(archived_mirror, archived_comp_mirror);
} else {
assert(k->is_instance_klass(), "Must be");
// Reset local static fields in the mirror
InstanceKlass::cast(k)->do_local_static_fields(&reset);
// clear class loader and mirror_module_field
set_class_loader(archived_mirror, NULL);
set_module(archived_mirror, NULL);
return archived_mirror;
}
// Returns true if the mirror is updated, false if no archived mirror // data is present. After the archived mirror object is restored, the // shared klass' _has_raw_archived_mirror flag is cleared. bool java_lang_Class::restore_archived_mirror(Klass *k,
Handle class_loader, Handle module,
Handle protection_domain, TRAPS) { // Postpone restoring archived mirror until java.lang.Class is loaded. Please // see more details in vmClasses::resolve_all(). if (!vmClasses::Class_klass_loaded()) {
assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
fixup_mirror_list()->push(k); returntrue;
}
oop m = k->archived_java_mirror();
assert(m != NULL, "must have stored non-null archived mirror");
// Sanity: clear it now to prevent re-initialization if any of the following fails
k->clear_archived_mirror_index();
// mirror is archived, restore
log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m)); if (ArchiveHeapLoader::is_mapped()) {
assert(Universe::heap()->is_archived_object(m), "must be archived mirror object");
}
assert(as_Klass(m) == k, "must be");
Handle mirror(THREAD, m);
if (!k->is_array_klass()) { // - local static final fields with initial values were initialized at dump time
if (protection_domain.not_null()) {
set_protection_domain(mirror(), protection_domain());
}
}
assert(class_loader() == k->class_loader(), "should be same"); if (class_loader.not_null()) {
set_class_loader(mirror(), class_loader());
}
oop java_lang_Class::create_basic_type_mirror(constchar* 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(vmClasses::Class_klass())->allocate_instance(NULL, CHECK_NULL); if (type != T_VOID) {
Klass* aklass = Universe::typeArrayKlassObj(type);
assert(aklass != NULL, "correct bootstrap");
release_set_array_klass(java_class, aklass);
} #ifdef ASSERT
InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(vmClasses::Class_klass());
assert(static_oop_field_count(java_class) == 0, "should have been zeroed by allocation"); #endif return java_class;
}
void java_lang_Class::set_klass(oop java_class, Klass* klass) {
assert(is_instance(java_class), "must be a Class object");
java_class->metadata_field_put(_klass_offset, klass);
}
void java_lang_Class::print_signature(oop java_class, outputStream* st) {
assert(is_instance(java_class), "must be a Class object");
Symbol* name = NULL; bool is_instance = 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();
name = k->name();
} if (name == NULL) {
st->print(""); return;
} if (is_instance) 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) {
assert(is_instance(java_class), "must be a Class object");
Symbol* name; if (is_primitive(java_class)) {
name = vmSymbols::type_signature(primitive_type(java_class)); // Because this can create a new symbol, the caller has to decrement // the refcount, so make adjustment here and below for symbols returned // that are not created or incremented due to a successful lookup.
name->increment_refcount();
} else {
Klass* k = as_Klass(java_class); if (!k->is_instance_klass()) {
name = k->name();
name->increment_refcount();
} else {
ResourceMark rm; constchar* 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);
}
}
} return name;
}
// Returns the Java name for this Java mirror (Resource allocated) // See Klass::external_name(). // For primitive type Java mirrors, its type name is returned. constchar* java_lang_Class::as_external_name(oop java_class) {
assert(is_instance(java_class), "must be a Class object"); constchar* name = NULL; if (is_primitive(java_class)) {
name = type2name(primitive_type(java_class));
} else {
name = as_Klass(java_class)->external_name();
} if (name == NULL) {
name = "";
} return name;
}
int java_lang_Class::classRedefinedCount(oop the_class_mirror) {
assert(_classRedefinedCount_offset != 0, "offsets should have been initialized"); return the_class_mirror->int_field(_classRedefinedCount_offset);
}
void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) {
assert(_classRedefinedCount_offset != 0, "offsets should have been initialized");
the_class_mirror->int_field_put(_classRedefinedCount_offset, value);
}
// Note: JDK1.1 and before had a privateInfo_offset field which was used for the // platform thread structure, and a eetop offset which was used for thread // local storage (and unused by the HotSpot VM). In JDK1.2 the two structures // merged, so in the HotSpot VM we just use the eetop field for the thread // instead of the privateInfo_offset. // // Note: The stackSize field is only present starting in 1.4.
int java_lang_Thread_FieldHolder::_group_offset; int java_lang_Thread_FieldHolder::_priority_offset; int java_lang_Thread_FieldHolder::_stackSize_offset; int java_lang_Thread_FieldHolder::_daemon_offset; int java_lang_Thread_FieldHolder::_thread_status_offset;
oop java_lang_Thread_Constants::get_VTHREAD_GROUP() {
InstanceKlass* k = vmClasses::Thread_Constants_klass();
oop base = k->static_field_base_raw(); return base->obj_field(_static_VTHREAD_GROUP_offset);
}
oop java_lang_Thread_Constants::get_NOT_SUPPORTED_CLASSLOADER() {
InstanceKlass* k = vmClasses::Thread_Constants_klass();
oop base = k->static_field_base_raw(); return base->obj_field(_static_NOT_SUPPORTED_CLASSLOADER_offset);
}
int java_lang_Thread::_holder_offset; int java_lang_Thread::_name_offset; int java_lang_Thread::_contextClassLoader_offset; int java_lang_Thread::_inheritedAccessControlContext_offset; int java_lang_Thread::_eetop_offset; int java_lang_Thread::_jvmti_thread_state_offset; int java_lang_Thread::_interrupted_offset; int java_lang_Thread::_tid_offset; int java_lang_Thread::_continuation_offset; int java_lang_Thread::_park_blocker_offset; int java_lang_Thread::_scopedValueBindings_offset;
JFR_ONLY(int java_lang_Thread::_jfr_epoch_offset;)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.