javaClasses.cpp revision 6412:53a41e7cbe05
14910Swollman/* 24910Swollman * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 34910Swollman * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 44910Swollman * 530300Sjoerg * This code is free software; you can redistribute it and/or modify it 625944Sjoerg * under the terms of the GNU General Public License version 2 only, as 74910Swollman * published by the Free Software Foundation. 825944Sjoerg * 988534Sjoerg * This code is distributed in the hope that it will be useful, but WITHOUT 1025944Sjoerg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 114910Swollman * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 124910Swollman * version 2 for more details (a copy is included in the LICENSE file that 134910Swollman * accompanied this code). 144910Swollman * 154910Swollman * You should have received a copy of the GNU General Public License version 164910Swollman * 2 along with this work; if not, write to the Free Software Foundation, 174910Swollman * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1830300Sjoerg * 1916288Sgpalmer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2050477Speter * or visit www.oracle.com if you need additional information or have any 214910Swollman * questions. 224910Swollman * 2340008Sjoerg */ 2440008Sjoerg 2542065Sphk#include "precompiled.hpp" 2632350Seivind#include "classfile/altHashing.hpp" 2754263Sshin#include "classfile/javaClasses.hpp" 2831742Seivind#include "classfile/symbolTable.hpp" 2940008Sjoerg#include "classfile/vmSymbols.hpp" 3031742Seivind#include "code/debugInfo.hpp" 3140008Sjoerg#include "code/pcDesc.hpp" 3240008Sjoerg#include "compiler/compilerOracle.hpp" 3340008Sjoerg#include "interpreter/interpreter.hpp" 3454263Sshin#include "memory/oopFactory.hpp" 3540008Sjoerg#include "memory/resourceArea.hpp" 3640008Sjoerg#include "memory/universe.inline.hpp" 3740008Sjoerg#include "oops/fieldStreams.hpp" 3840008Sjoerg#include "oops/instanceKlass.hpp" 394952Sbde#include "oops/instanceMirrorKlass.hpp" 404952Sbde#include "oops/klass.hpp" 4170199Sjhay#include "oops/method.hpp" 4224204Sbde#include "oops/symbol.hpp" 434910Swollman#include "oops/typeArrayOop.hpp" 4425706Sjoerg#include "runtime/fieldDescriptor.hpp" 4542104Sphk#include "runtime/handles.inline.hpp" 4659604Sobrien#include "runtime/interfaceSupport.hpp" 4742104Sphk#include "runtime/java.hpp" 4829024Sbde#include "runtime/javaCalls.hpp" 494910Swollman#include "runtime/safepoint.hpp" 5040008Sjoerg#include "runtime/thread.inline.hpp" 5140008Sjoerg#include "runtime/vframe.hpp" 5240008Sjoerg#include "utilities/preserveException.hpp" 5340008Sjoerg 5430300SjoergPRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 5540008Sjoerg 564910Swollman#define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java) \ 574910Swollman klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum); 584910Swollman 594910Swollman#define DECLARE_INJECTED_FIELD(klass, name, signature, may_be_java) \ 6042104Sphk { SystemDictionary::WK_KLASS_ENUM_NAME(klass), vmSymbols::VM_SYMBOL_ENUM_NAME(name##_name), vmSymbols::VM_SYMBOL_ENUM_NAME(signature), may_be_java }, 6188534Sjoerg 6288534SjoergInjectedField JavaClasses::_injected_fields[] = { 6388534Sjoerg ALL_INJECTED_FIELDS(DECLARE_INJECTED_FIELD) 6488534Sjoerg}; 654910Swollman 6640008Sjoergint JavaClasses::compute_injected_offset(InjectedFieldID id) { 6740008Sjoerg return _injected_fields[id].compute_offset(); 6840008Sjoerg} 6942104Sphk 7030300Sjoerg 7130300SjoergInjectedField* JavaClasses::get_injected(Symbol* class_name, int* field_count) { 724910Swollman *field_count = 0; 734910Swollman 744910Swollman vmSymbols::SID sid = vmSymbols::find_sid(class_name); 7588705Sjoerg if (sid == vmSymbols::NO_SID) { 7688705Sjoerg // Only well known classes can inject fields 774910Swollman return NULL; 784910Swollman } 794910Swollman 804910Swollman int count = 0; 8188705Sjoerg int start = -1; 8288705Sjoerg 8388705Sjoerg#define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \ 8488705Sjoerg if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) { \ 8588705Sjoerg count++; \ 8688705Sjoerg if (start == -1) start = klass##_##name##_enum; \ 8711819Sjulian } 8811819Sjulian ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD); 8911819Sjulian#undef LOOKUP_INJECTED_FIELD 9011819Sjulian 9111819Sjulian if (start != -1) { 924910Swollman *field_count = count; 934910Swollman return _injected_fields + start; 944910Swollman } 954910Swollman return NULL; 964910Swollman} 974910Swollman 984910Swollman 9942065Sphkstatic bool find_field(InstanceKlass* ik, 10042064Sphk Symbol* name_symbol, Symbol* signature_symbol, 10142064Sphk fieldDescriptor* fd, 10242104Sphk bool allow_super = false) { 10340008Sjoerg if (allow_super) 10442064Sphk return ik->find_field(name_symbol, signature_symbol, fd) != NULL; 10542064Sphk else 10642104Sphk return ik->find_local_field(name_symbol, signature_symbol, fd); 10740008Sjoerg} 10842104Sphk 1094910Swollman// Helpful routine for computing field offsets at run time rather than hardcoding them 1104910Swollmanstatic void 11125944Sjoergcompute_offset(int &dest_offset, 11225944Sjoerg Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol, 11325944Sjoerg bool allow_super = false) { 11425955Sjoerg fieldDescriptor fd; 11525944Sjoerg InstanceKlass* ik = InstanceKlass::cast(klass_oop); 11625944Sjoerg if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { 11725944Sjoerg ResourceMark rm; 11825955Sjoerg tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); 11925955Sjoerg#ifndef PRODUCT 12025955Sjoerg klass_oop->print(); 12130300Sjoerg tty->print_cr("all fields:"); 12230300Sjoerg for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) { 12330300Sjoerg tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); 12430300Sjoerg } 12530300Sjoerg#endif //PRODUCT 12630300Sjoerg fatal("Invalid layout of preloaded class"); 12730300Sjoerg } 12830300Sjoerg dest_offset = fd.offset(); 12930300Sjoerg} 13025944Sjoerg 13125944Sjoerg// Same as above but for "optional" offsets that might not be present in certain JDK versions 13225955Sjoergstatic void 13325955Sjoergcompute_optional_offset(int& dest_offset, 13445152Sphk Klass* klass_oop, Symbol* name_symbol, Symbol* signature_symbol, 13525944Sjoerg bool allow_super = false) { 13630300Sjoerg fieldDescriptor fd; 13730300Sjoerg InstanceKlass* ik = InstanceKlass::cast(klass_oop); 13830300Sjoerg if (find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { 13930300Sjoerg dest_offset = fd.offset(); 14030300Sjoerg } 14130300Sjoerg} 14288534Sjoerg 14388534Sjoerg 14478064Sumeint java_lang_String::value_offset = 0; 14530300Sjoergint java_lang_String::offset_offset = 0; 14630300Sjoergint java_lang_String::count_offset = 0; 14730300Sjoergint java_lang_String::hash_offset = 0; 14830300Sjoerg 14978064Sumebool java_lang_String::initialized = false; 1504910Swollman 15125944Sjoergvoid java_lang_String::compute_offsets() { 15225944Sjoerg assert(!initialized, "offsets should be initialized only once"); 15325944Sjoerg 15425944Sjoerg Klass* k = SystemDictionary::String_klass(); 15525944Sjoerg compute_offset(value_offset, k, vmSymbols::value_name(), vmSymbols::char_array_signature()); 15625944Sjoerg compute_optional_offset(offset_offset, k, vmSymbols::offset_name(), vmSymbols::int_signature()); 15725944Sjoerg compute_optional_offset(count_offset, k, vmSymbols::count_name(), vmSymbols::int_signature()); 15825944Sjoerg compute_optional_offset(hash_offset, k, vmSymbols::hash_name(), vmSymbols::int_signature()); 15925944Sjoerg 16025944Sjoerg initialized = true; 16125944Sjoerg} 1624910Swollman 16330300SjoergHandle java_lang_String::basic_create(int length, TRAPS) { 16430300Sjoerg assert(initialized, "Must be initialized"); 16530300Sjoerg // Create the String object first, so there's a chance that the String 16630300Sjoerg // and the char array it points to end up in the same cache line. 16730300Sjoerg oop obj; 16830300Sjoerg obj = InstanceKlass::cast(SystemDictionary::String_klass())->allocate_instance(CHECK_NH); 16930300Sjoerg 17030300Sjoerg // Create the char array. The String object must be handlized here 1714910Swollman // because GC can happen as a result of the allocation attempt. 17225944Sjoerg Handle h_obj(THREAD, obj); 17325944Sjoerg typeArrayOop buffer; 17425944Sjoerg buffer = oopFactory::new_charArray(length, CHECK_NH); 1754910Swollman 17678064Sume // Point the String at the char array 17778064Sume obj = h_obj(); 17878064Sume set_value(obj, buffer); 17988534Sjoerg // No need to zero the offset, allocation zero'ed the entire String object 18088534Sjoerg assert(offset(obj) == 0, "initial String offset should be zero"); 18130300Sjoerg//set_offset(obj, 0); 18230300Sjoerg set_count(obj, length); 18330300Sjoerg 1844910Swollman return h_obj; 18530300Sjoerg} 18630300Sjoerg 18730300SjoergHandle java_lang_String::create_from_unicode(jchar* unicode, int length, TRAPS) { 18830300Sjoerg Handle h_obj = basic_create(length, CHECK_NH); 18930300Sjoerg typeArrayOop buffer = value(h_obj()); 19030300Sjoerg for (int index = 0; index < length; index++) { 19130300Sjoerg buffer->char_at_put(index, unicode[index]); 19230300Sjoerg } 19330300Sjoerg return h_obj; 19430300Sjoerg} 19530300Sjoerg 19630300Sjoergoop java_lang_String::create_oop_from_unicode(jchar* unicode, int length, TRAPS) { 19730300Sjoerg Handle h_obj = create_from_unicode(unicode, length, CHECK_0); 19830300Sjoerg return h_obj(); 19925944Sjoerg} 20025944Sjoerg 20125944SjoergHandle java_lang_String::create_from_str(const char* utf8_str, TRAPS) { 20225944Sjoerg if (utf8_str == NULL) { 20325944Sjoerg return Handle(); 20425944Sjoerg } 20525944Sjoerg int length = UTF8::unicode_length(utf8_str); 20625944Sjoerg Handle h_obj = basic_create(length, CHECK_NH); 20725944Sjoerg if (length > 0) { 20825944Sjoerg UTF8::convert_to_unicode(utf8_str, value(h_obj())->char_at_addr(0), length); 20925944Sjoerg } 21025944Sjoerg return h_obj; 2114910Swollman} 21211189Sjkh 21311189Sjkhoop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) { 21411189Sjkh Handle h_obj = create_from_str(utf8_str, CHECK_0); 21588704Sjoerg return h_obj(); 2164910Swollman} 2174910Swollman 2184910SwollmanHandle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) { 21911189Sjkh int length = UTF8::unicode_length((char*)symbol->bytes(), symbol->utf8_length()); 22011189Sjkh Handle h_obj = basic_create(length, CHECK_NH); 22111189Sjkh if (length > 0) { 22288704Sjoerg UTF8::convert_to_unicode((char*)symbol->bytes(), value(h_obj())->char_at_addr(0), length); 2234910Swollman } 2244910Swollman return h_obj; 2254910Swollman} 22611189Sjkh 22711189Sjkh// Converts a C string to a Java String based on current encoding 22811189SjkhHandle java_lang_String::create_from_platform_dependent_str(const char* str, TRAPS) { 22911189Sjkh assert(str != NULL, "bad arguments"); 23011189Sjkh 23111189Sjkh typedef jstring (*to_java_string_fn_t)(JNIEnv*, const char *); 23288704Sjoerg static to_java_string_fn_t _to_java_string_fn = NULL; 23388704Sjoerg 2344910Swollman if (_to_java_string_fn == NULL) { 23525944Sjoerg void *lib_handle = os::native_java_library(); 23625944Sjoerg _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform")); 23725944Sjoerg if (_to_java_string_fn == NULL) { 23825944Sjoerg fatal("NewStringPlatform missing"); 23925944Sjoerg } 24025944Sjoerg } 24125944Sjoerg 24225944Sjoerg jstring js = NULL; 24325944Sjoerg { JavaThread* thread = (JavaThread*)THREAD; 24425944Sjoerg assert(thread->is_Java_thread(), "must be java thread"); 24525944Sjoerg HandleMark hm(thread); 24625944Sjoerg ThreadToNativeFromVM ttn(thread); 24725944Sjoerg js = (_to_java_string_fn)(thread->jni_environment(), str); 24825944Sjoerg } 24925944Sjoerg return Handle(THREAD, JNIHandles::resolve(js)); 25025944Sjoerg} 25125944Sjoerg 25225944Sjoerg// Converts a Java String to a native C string that can be used for 25325944Sjoerg// native OS calls. 25425944Sjoergchar* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) { 25525944Sjoerg 25625944Sjoerg typedef char* (*to_platform_string_fn_t)(JNIEnv*, jstring, bool*); 25725944Sjoerg static to_platform_string_fn_t _to_platform_string_fn = NULL; 25825944Sjoerg 25925944Sjoerg if (_to_platform_string_fn == NULL) { 26025944Sjoerg void *lib_handle = os::native_java_library(); 26125944Sjoerg _to_platform_string_fn = CAST_TO_FN_PTR(to_platform_string_fn_t, os::dll_lookup(lib_handle, "GetStringPlatformChars")); 26225944Sjoerg if (_to_platform_string_fn == NULL) { 26325944Sjoerg fatal("GetStringPlatformChars missing"); 26425944Sjoerg } 26525944Sjoerg } 26625944Sjoerg 26712820Sphk char *native_platform_string; 26842065Sphk { JavaThread* thread = (JavaThread*)THREAD; 26930300Sjoerg assert(thread->is_Java_thread(), "must be java thread"); 27040008Sjoerg JNIEnv *env = thread->jni_environment(); 2714910Swollman jstring js = (jstring) JNIHandles::make_local(env, java_string()); 27242065Sphk bool is_copy; 27340008Sjoerg HandleMark hm(thread); 27440008Sjoerg ThreadToNativeFromVM ttn(thread); 27540008Sjoerg native_platform_string = (_to_platform_string_fn)(env, js, &is_copy); 27640008Sjoerg assert(is_copy == JNI_TRUE, "is_copy value changed"); 27740008Sjoerg JNIHandles::destroy_local(js); 27840008Sjoerg } 27940008Sjoerg return native_platform_string; 28088705Sjoerg} 2814910Swollman 2824910SwollmanHandle java_lang_String::char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS) { 2834910Swollman oop obj = java_string(); 2844910Swollman // Typical usage is to convert all '/' to '.' in string. 2854910Swollman typeArrayOop value = java_lang_String::value(obj); 28630300Sjoerg int offset = java_lang_String::offset(obj); 28730300Sjoerg int length = java_lang_String::length(obj); 2884910Swollman 28911189Sjkh // First check if any from_char exist 2904910Swollman int index; // Declared outside, used later 2914910Swollman for (index = 0; index < length; index++) { 2924910Swollman if (value->char_at(index + offset) == from_char) { 2934910Swollman break; 29488705Sjoerg } 2954910Swollman } 29625944Sjoerg if (index == length) { 29725944Sjoerg // No from_char, so do not copy. 29825944Sjoerg return java_string; 29925944Sjoerg } 30011189Sjkh 30130300Sjoerg // Create new UNICODE buffer. Must handlize value because GC 30225944Sjoerg // may happen during String and char array creation. 3034910Swollman typeArrayHandle h_value(THREAD, value); 30425944Sjoerg Handle string = basic_create(length, CHECK_NH); 30525944Sjoerg 30625944Sjoerg typeArrayOop from_buffer = h_value(); 30725944Sjoerg typeArrayOop to_buffer = java_lang_String::value(string()); 30825944Sjoerg 30925944Sjoerg // Copy contents 31025944Sjoerg for (index = 0; index < length; index++) { 31142104Sphk jchar c = from_buffer->char_at(index + offset); 31225944Sjoerg if (c == from_char) { 31325944Sjoerg c = to_char; 31430300Sjoerg } 31542104Sphk to_buffer->char_at_put(index, c); 31630300Sjoerg } 31725944Sjoerg return string; 31825944Sjoerg} 31925944Sjoerg 32025944Sjoergjchar* java_lang_String::as_unicode_string(oop java_string, int& length, TRAPS) { 32125944Sjoerg typeArrayOop value = java_lang_String::value(java_string); 32225944Sjoerg int offset = java_lang_String::offset(java_string); 32325944Sjoerg length = java_lang_String::length(java_string); 32430300Sjoerg 32530300Sjoerg jchar* result = NEW_RESOURCE_ARRAY_RETURN_NULL(jchar, length); 32625944Sjoerg if (result != NULL) { 32725944Sjoerg for (int index = 0; index < length; index++) { 32825944Sjoerg result[index] = value->char_at(index + offset); 32925944Sjoerg } 33025944Sjoerg } else { 33125944Sjoerg THROW_MSG_0(vmSymbols::java_lang_OutOfMemoryError(), "could not allocate Unicode string"); 33225944Sjoerg } 33325944Sjoerg return result; 33425944Sjoerg} 33525944Sjoerg 33625944Sjoergunsigned int java_lang_String::hash_code(oop java_string) { 33725944Sjoerg int length = java_lang_String::length(java_string); 33825944Sjoerg // Zero length string will hash to zero with String.hashCode() function. 33925944Sjoerg if (length == 0) return 0; 34030300Sjoerg 34130300Sjoerg typeArrayOop value = java_lang_String::value(java_string); 34225944Sjoerg int offset = java_lang_String::offset(java_string); 34325944Sjoerg return java_lang_String::hash_code(value->char_at_addr(offset), length); 34425944Sjoerg} 34525944Sjoerg 34625944Sjoergchar* java_lang_String::as_quoted_ascii(oop java_string) { 34725944Sjoerg typeArrayOop value = java_lang_String::value(java_string); 34825944Sjoerg int offset = java_lang_String::offset(java_string); 34925944Sjoerg int length = java_lang_String::length(java_string); 35025944Sjoerg 35125944Sjoerg jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); 35225944Sjoerg if (base == NULL) return NULL; 35325944Sjoerg 35425944Sjoerg int result_length = UNICODE::quoted_ascii_length(base, length) + 1; 35525944Sjoerg char* result = NEW_RESOURCE_ARRAY(char, result_length); 35625944Sjoerg UNICODE::as_quoted_ascii(base, length, result, result_length); 35725944Sjoerg assert(result_length >= length + 1, "must not be shorter"); 35878064Sume assert(result_length == (int)strlen(result) + 1, "must match"); 35978064Sume return result; 36078064Sume} 36178064Sume 36278064Sumeunsigned int java_lang_String::hash_string(oop java_string) { 36378064Sume int length = java_lang_String::length(java_string); 36478064Sume // Zero length string doesn't hash necessarily hash to zero. 36578064Sume if (length == 0) { 36678064Sume return StringTable::hash_string(NULL, 0); 36778064Sume } 36878064Sume 36978064Sume typeArrayOop value = java_lang_String::value(java_string); 37078064Sume int offset = java_lang_String::offset(java_string); 37178064Sume return StringTable::hash_string(value->char_at_addr(offset), length); 37278064Sume} 37330300Sjoerg 37430300SjoergSymbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { 37530300Sjoerg oop obj = java_string(); 37630300Sjoerg typeArrayOop value = java_lang_String::value(obj); 37730300Sjoerg int offset = java_lang_String::offset(obj); 37830300Sjoerg int length = java_lang_String::length(obj); 37930300Sjoerg jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); 38030300Sjoerg Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD); 38130300Sjoerg return sym; 38230300Sjoerg} 38330300Sjoerg 38430300SjoergSymbol* java_lang_String::as_symbol_or_null(oop java_string) { 38530300Sjoerg typeArrayOop value = java_lang_String::value(java_string); 38630300Sjoerg int offset = java_lang_String::offset(java_string); 38730300Sjoerg int length = java_lang_String::length(java_string); 38830300Sjoerg jchar* base = (length == 0) ? NULL : value->char_at_addr(offset); 38930300Sjoerg return SymbolTable::probe_unicode(base, length); 39030300Sjoerg} 39130300Sjoerg 39230300Sjoerg 39325944Sjoergint java_lang_String::utf8_length(oop java_string) { 39430300Sjoerg typeArrayOop value = java_lang_String::value(java_string); 39530300Sjoerg int offset = java_lang_String::offset(java_string); 39678064Sume int length = java_lang_String::length(java_string); 39778064Sume jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); 39878064Sume return UNICODE::utf8_length(position, length); 39925944Sjoerg} 40025944Sjoerg 40125944Sjoergchar* java_lang_String::as_utf8_string(oop java_string) { 40230300Sjoerg typeArrayOop value = java_lang_String::value(java_string); 40338343Sbde int offset = java_lang_String::offset(java_string); 40430300Sjoerg int length = java_lang_String::length(java_string); 40530300Sjoerg jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); 40630300Sjoerg return UNICODE::as_utf8(position, length); 40725944Sjoerg} 40830300Sjoerg 40930300Sjoergchar* java_lang_String::as_utf8_string(oop java_string, char* buf, int buflen) { 41030300Sjoerg typeArrayOop value = java_lang_String::value(java_string); 41125944Sjoerg int offset = java_lang_String::offset(java_string); 41225944Sjoerg int length = java_lang_String::length(java_string); 41378064Sume jchar* position = (length == 0) ? NULL : value->char_at_addr(offset); 41478064Sume return UNICODE::as_utf8(position, length, buf, buflen); 41578064Sume} 41678064Sume 41778064Sumechar* java_lang_String::as_utf8_string(oop java_string, int start, int len) { 41878064Sume typeArrayOop value = java_lang_String::value(java_string); 41978064Sume int offset = java_lang_String::offset(java_string); 42078064Sume int length = java_lang_String::length(java_string); 42178064Sume assert(start + len <= length, "just checking"); 42225944Sjoerg jchar* position = value->char_at_addr(offset + start); 42325944Sjoerg return UNICODE::as_utf8(position, len); 42433181Seivind} 42525944Sjoerg 42625944Sjoergchar* java_lang_String::as_utf8_string(oop java_string, int start, int len, char* buf, int buflen) { 42725944Sjoerg typeArrayOop value = java_lang_String::value(java_string); 42825944Sjoerg int offset = java_lang_String::offset(java_string); 42925944Sjoerg int length = java_lang_String::length(java_string); 43025944Sjoerg assert(start + len <= length, "just checking"); 43125944Sjoerg jchar* position = value->char_at_addr(offset + start); 43233181Seivind return UNICODE::as_utf8(position, len, buf, buflen); 43388709Sjoerg} 43488709Sjoerg 43588709Sjoergbool java_lang_String::equals(oop java_string, jchar* chars, int len) { 43688709Sjoerg assert(java_string->klass() == SystemDictionary::String_klass(), 43788709Sjoerg "must be java_string"); 43888709Sjoerg typeArrayOop value = java_lang_String::value(java_string); 43988709Sjoerg int offset = java_lang_String::offset(java_string); 44025944Sjoerg int length = java_lang_String::length(java_string); 44125944Sjoerg if (length != len) { 44225944Sjoerg return false; 44325944Sjoerg } 44425944Sjoerg for (int i = 0; i < len; i++) { 44525944Sjoerg if (value->char_at(i + offset) != chars[i]) { 44678064Sume return false; 44778064Sume } 44878064Sume } 44978064Sume return true; 45078064Sume} 45178064Sume 45278064Sumebool java_lang_String::equals(oop str1, oop str2) { 45378064Sume assert(str1->klass() == SystemDictionary::String_klass(), 45478064Sume "must be java String"); 45578064Sume assert(str2->klass() == SystemDictionary::String_klass(), 45678064Sume "must be java String"); 45778064Sume typeArrayOop value1 = java_lang_String::value(str1); 45878064Sume int offset1 = java_lang_String::offset(str1); 45978064Sume int length1 = java_lang_String::length(str1); 46033181Seivind typeArrayOop value2 = java_lang_String::value(str2); 46130300Sjoerg int offset2 = java_lang_String::offset(str2); 46230300Sjoerg int length2 = java_lang_String::length(str2); 46330300Sjoerg 46430300Sjoerg if (length1 != length2) { 46530300Sjoerg return false; 46630300Sjoerg } 46730300Sjoerg for (int i = 0; i < length1; i++) { 46833181Seivind if (value1->char_at(i + offset1) != value2->char_at(i + offset2)) { 46930300Sjoerg return false; 47030300Sjoerg } 47130300Sjoerg } 47230300Sjoerg return true; 47330300Sjoerg} 47430300Sjoerg 47530300Sjoergvoid java_lang_String::print(oop java_string, outputStream* st) { 47633181Seivind assert(java_string->klass() == SystemDictionary::String_klass(), "must be java_string"); 47725944Sjoerg typeArrayOop value = java_lang_String::value(java_string); 47825944Sjoerg 47978064Sume if (value == NULL) { 48030300Sjoerg // This can happen if, e.g., printing a String 48130300Sjoerg // object before its initializer has been called 48225944Sjoerg st->print("NULL"); 48325944Sjoerg return; 48470199Sjhay } 48570199Sjhay 48670199Sjhay int offset = java_lang_String::offset(java_string); 48770199Sjhay int length = java_lang_String::length(java_string); 48870199Sjhay 48970199Sjhay st->print("\""); 49070199Sjhay for (int index = 0; index < length; index++) { 49170199Sjhay st->print("%c", value->char_at(index + offset)); 49270199Sjhay } 49370199Sjhay st->print("\""); 49470199Sjhay} 49570199Sjhay 49670199Sjhay 49770199Sjhaystatic void initialize_static_field(fieldDescriptor* fd, Handle mirror, TRAPS) { 49870199Sjhay assert(mirror.not_null() && fd->is_static(), "just checking"); 49970199Sjhay if (fd->has_initial_value()) { 50070199Sjhay BasicType t = fd->field_type(); 50170199Sjhay switch (t) { 50270199Sjhay case T_BYTE: 50370199Sjhay mirror()->byte_field_put(fd->offset(), fd->int_initial_value()); 50470199Sjhay break; 50525944Sjoerg case T_BOOLEAN: 50670199Sjhay mirror()->bool_field_put(fd->offset(), fd->int_initial_value()); 50725944Sjoerg break; 5084910Swollman case T_CHAR: 5094910Swollman mirror()->char_field_put(fd->offset(), fd->int_initial_value()); 5104910Swollman break; 5114910Swollman case T_SHORT: 5124910Swollman mirror()->short_field_put(fd->offset(), fd->int_initial_value()); 51325706Sjoerg break; 51425706Sjoerg case T_INT: 5154910Swollman mirror()->int_field_put(fd->offset(), fd->int_initial_value()); 5164910Swollman break; 5174910Swollman case T_FLOAT: 51825944Sjoerg mirror()->float_field_put(fd->offset(), fd->float_initial_value()); 51988700Sjoerg break; 52088700Sjoerg case T_DOUBLE: 52125944Sjoerg mirror()->double_field_put(fd->offset(), fd->double_initial_value()); 5224910Swollman break; 5234910Swollman case T_LONG: 5244910Swollman mirror()->long_field_put(fd->offset(), fd->long_initial_value()); 5254910Swollman break; 5264910Swollman case T_OBJECT: 5274910Swollman { 5284910Swollman #ifdef ASSERT 52925944Sjoerg TempNewSymbol sym = SymbolTable::new_symbol("Ljava/lang/String;", CHECK); 53025706Sjoerg assert(fd->signature() == sym, "just checking"); 53140008Sjoerg #endif 53240008Sjoerg oop string = fd->string_initial_value(CHECK); 53325944Sjoerg mirror()->obj_field_put(fd->offset(), string); 53488700Sjoerg } 53588700Sjoerg break; 53625944Sjoerg default: 53725944Sjoerg THROW_MSG(vmSymbols::java_lang_ClassFormatError(), 5384910Swollman "Illegal ConstantValue attribute in class file"); 5394910Swollman } 5404910Swollman } 5414910Swollman} 5424910Swollman 5434910Swollman 5444910Swollmanvoid java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) { 5454910Swollman assert(InstanceMirrorKlass::offset_of_static_fields() != 0, "must have been computed already"); 5464910Swollman 5474910Swollman // If the offset was read from the shared archive, it was fixed up already 5484910Swollman if (!k->is_shared()) { 54945152Sphk if (k->oop_is_instance()) { 55025944Sjoerg // During bootstrap, java.lang.Class wasn't loaded so static field 55125706Sjoerg // offsets were computed without the size added it. Go back and 55240008Sjoerg // update all the static field offsets to included the size. 55325706Sjoerg for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) { 55440008Sjoerg if (fs.access_flags().is_static()) { 55525706Sjoerg int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields(); 55611189Sjkh fs.set_offset(real_offset); 55711189Sjkh } 5584910Swollman } 5594910Swollman } 56025944Sjoerg } 56125706Sjoerg create_mirror(k, Handle(NULL), CHECK); 56244145Sphk} 56325706Sjoerg 56440008Sjoergvoid java_lang_Class::initialize_mirror_fields(KlassHandle k, 56525706Sjoerg Handle mirror, 56644145Sphk Handle protection_domain, 56744145Sphk TRAPS) { 56878064Sume // Allocate a simple java object for a lock. 56944145Sphk // This needs to be a java object because during class initialization 5704910Swollman // it can be held across a java call. 5714910Swollman typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK); 5724910Swollman set_init_lock(mirror(), r); 57330300Sjoerg 5744910Swollman // Set protection domain also 5754910Swollman set_protection_domain(mirror(), protection_domain()); 57630300Sjoerg 57730300Sjoerg // Initialize static fields 57830300Sjoerg InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, mirror, CHECK); 57930300Sjoerg} 58030300Sjoerg 58130300Sjoergvoid java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) { 58230300Sjoerg assert(k->java_mirror() == NULL, "should only assign mirror once"); 58330300Sjoerg // Use this moment of initialization to cache modifier_flags also, 58430300Sjoerg // to support Class.getModifiers(). Instance classes recalculate 58530300Sjoerg // the cached flags after the class file is parsed, but before the 5864910Swollman // class is put into the system dictionary. 5874910Swollman int computed_modifiers = k->compute_modifier_flags(CHECK); 58825944Sjoerg k->set_modifier_flags(computed_modifiers); 58930300Sjoerg // Class_klass has to be loaded because it is used to allocate 5904910Swollman // the mirror. 5914910Swollman if (SystemDictionary::Class_klass_loaded()) { 5924910Swollman // Allocate mirror (java.lang.Class instance) 59325944Sjoerg Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); 5944910Swollman 5954910Swollman // Setup indirection from mirror->klass 5964910Swollman if (!k.is_null()) { 59788577Sjoerg java_lang_Class::set_klass(mirror(), k()); 5984910Swollman } 59988534Sjoerg 60088534Sjoerg InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); 60188700Sjoerg assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); 60288700Sjoerg 60388700Sjoerg java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); 60488700Sjoerg 60588700Sjoerg // It might also have a component mirror. This mirror must already exist. 60688700Sjoerg if (k->oop_is_array()) { 60788700Sjoerg Handle comp_mirror; 60888700Sjoerg if (k->oop_is_typeArray()) { 60988700Sjoerg BasicType type = TypeArrayKlass::cast(k())->element_type(); 61088700Sjoerg comp_mirror = Universe::java_mirror(type); 61188534Sjoerg } else { 61288700Sjoerg assert(k->oop_is_objArray(), "Must be"); 61388700Sjoerg Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); 61488700Sjoerg assert(element_klass != NULL, "Must have an element klass"); 61588700Sjoerg comp_mirror = element_klass->java_mirror(); 61688700Sjoerg } 61788700Sjoerg assert(comp_mirror.not_null(), "must have a mirror"); 61888700Sjoerg 61988700Sjoerg // Two-way link between the array klass and its component mirror: 62088700Sjoerg ArrayKlass::cast(k())->set_component_mirror(comp_mirror()); 62188700Sjoerg set_array_klass(comp_mirror(), k()); 62288700Sjoerg } else { 62388700Sjoerg assert(k->oop_is_instance(), "Must be"); 62488700Sjoerg 62588700Sjoerg initialize_mirror_fields(k, mirror, protection_domain, THREAD); 62688534Sjoerg if (HAS_PENDING_EXCEPTION) { 62788534Sjoerg // If any of the fields throws an exception like OOM remove the klass field 62888534Sjoerg // from the mirror so GC doesn't follow it after the klass has been deallocated. 62988599Sjoerg // This mirror looks like a primitive type, which logically it is because it 63088534Sjoerg // it represents no class. 63188534Sjoerg java_lang_Class::set_klass(mirror(), NULL); 63288534Sjoerg return; 63388700Sjoerg } 63488700Sjoerg } 63588700Sjoerg 63688700Sjoerg // Setup indirection from klass->mirror last 63788700Sjoerg // after any exceptions can happen during allocations. 63888700Sjoerg if (!k.is_null()) { 63988700Sjoerg k->set_java_mirror(mirror()); 64088700Sjoerg } 64188700Sjoerg } else { 64288534Sjoerg if (fixup_mirror_list() == NULL) { 64388700Sjoerg GrowableArray<Klass*>* list = 64488534Sjoerg new (ResourceObj::C_HEAP, mtClass) GrowableArray<Klass*>(40, true); 64588534Sjoerg set_fixup_mirror_list(list); 64688534Sjoerg } 64788599Sjoerg fixup_mirror_list()->push(k()); 64888534Sjoerg } 64978064Sume} 65088599Sjoerg 65188599Sjoerg 65288599Sjoergint java_lang_Class::oop_size(oop java_class) { 65388599Sjoerg assert(_oop_size_offset != 0, "must be set"); 65488599Sjoerg return java_class->int_field(_oop_size_offset); 65588599Sjoerg} 65688599Sjoergvoid java_lang_Class::set_oop_size(oop java_class, int size) { 65788599Sjoerg assert(_oop_size_offset != 0, "must be set"); 65888599Sjoerg java_class->int_field_put(_oop_size_offset, size); 65988599Sjoerg} 66088599Sjoergint java_lang_Class::static_oop_field_count(oop java_class) { 66188599Sjoerg assert(_static_oop_field_count_offset != 0, "must be set"); 66288599Sjoerg return java_class->int_field(_static_oop_field_count_offset); 66388599Sjoerg} 66488599Sjoergvoid java_lang_Class::set_static_oop_field_count(oop java_class, int size) { 66512495Speter assert(_static_oop_field_count_offset != 0, "must be set"); 66612495Speter java_class->int_field_put(_static_oop_field_count_offset, size); 66712495Speter} 66825944Sjoerg 66912495Speteroop java_lang_Class::protection_domain(oop java_class) { 67012495Speter assert(_protection_domain_offset != 0, "must be set"); 67112495Speter return java_class->obj_field(_protection_domain_offset); 67288577Sjoerg} 67312495Spetervoid java_lang_Class::set_protection_domain(oop java_class, oop pd) { 67412495Speter assert(_protection_domain_offset != 0, "must be set"); 6754910Swollman java_class->obj_field_put(_protection_domain_offset, pd); 6764910Swollman} 6774910Swollman 67825944Sjoergoop java_lang_Class::init_lock(oop java_class) { 6794910Swollman assert(_init_lock_offset != 0, "must be set"); 6804910Swollman return java_class->obj_field(_init_lock_offset); 6814910Swollman} 68288577Sjoergvoid java_lang_Class::set_init_lock(oop java_class, oop init_lock) { 6834910Swollman assert(_init_lock_offset != 0, "must be set"); 6844910Swollman java_class->obj_field_put(_init_lock_offset, init_lock); 6854910Swollman} 6864910Swollman 6874910SwollmanobjArrayOop java_lang_Class::signers(oop java_class) { 6884910Swollman assert(_signers_offset != 0, "must be set"); 6894910Swollman return (objArrayOop)java_class->obj_field(_signers_offset); 69045152Sphk} 69125944Sjoergvoid java_lang_Class::set_signers(oop java_class, objArrayOop signers) { 69225706Sjoerg assert(_signers_offset != 0, "must be set"); 69340008Sjoerg java_class->obj_field_put(_signers_offset, (oop)signers); 69425706Sjoerg} 69540008Sjoerg 69625706Sjoerg 69711189Sjkhoop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { 69811189Sjkh // This should be improved by adding a field at the Java level or by 6994910Swollman // introducing a new VM klass (see comment in ClassFileParser) 7004910Swollman oop java_class = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(NULL, CHECK_0); 7014910Swollman if (type != T_VOID) { 7024910Swollman Klass* aklass = Universe::typeArrayKlassObj(type); 7034910Swollman assert(aklass != NULL, "correct bootstrap"); 7044910Swollman set_array_klass(java_class, aklass); 7054910Swollman } 7064910Swollman#ifdef ASSERT 7074910Swollman InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(SystemDictionary::Class_klass()); 7084910Swollman assert(java_lang_Class::static_oop_field_count(java_class) == 0, "should have been zeroed by allocation"); 7094910Swollman#endif 7104910Swollman return java_class; 71188577Sjoerg} 7124910Swollman 7134910Swollman 71454263SshinKlass* java_lang_Class::as_Klass(oop java_class) { 71554263Sshin //%note memory_2 71654263Sshin assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 71754263Sshin Klass* k = ((Klass*)java_class->metadata_field(_klass_offset)); 71888577Sjoerg assert(k == NULL || k->is_klass(), "type check"); 71954263Sshin return k; 72054263Sshin} 72112495Speter 72212495Speter 72312495Spetervoid java_lang_Class::set_klass(oop java_class, Klass* klass) { 72412495Speter assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 72588577Sjoerg java_class->metadata_field_put(_klass_offset, klass); 72612495Speter} 72712495Speter 7284910Swollman 7294910Swollmanvoid java_lang_Class::print_signature(oop java_class, outputStream* st) { 7304910Swollman assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 7314910Swollman Symbol* name = NULL; 73288577Sjoerg bool is_instance = false; 7334910Swollman if (is_primitive(java_class)) { 7344910Swollman name = vmSymbols::type_signature(primitive_type(java_class)); 7354910Swollman } else { 7364910Swollman Klass* k = as_Klass(java_class); 73725944Sjoerg is_instance = k->oop_is_instance(); 73825944Sjoerg name = k->name(); 73925944Sjoerg } 74025944Sjoerg if (name == NULL) { 74140008Sjoerg st->print("<null>"); 74225944Sjoerg return; 74340008Sjoerg } 74425944Sjoerg if (is_instance) st->print("L"); 74525944Sjoerg st->write((char*) name->base(), (int) name->utf8_length()); 7464910Swollman if (is_instance) st->print(";"); 7474910Swollman} 7484910Swollman 7494910SwollmanSymbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) { 7504910Swollman assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 7514910Swollman Symbol* name; 75269152Sjlemon if (is_primitive(java_class)) { 75325944Sjoerg name = vmSymbols::type_signature(primitive_type(java_class)); 75440008Sjoerg // Because this can create a new symbol, the caller has to decrement 75540008Sjoerg // the refcount, so make adjustment here and below for symbols returned 7564910Swollman // that are not created or incremented due to a successful lookup. 7574910Swollman name->increment_refcount(); 75888577Sjoerg } else { 75988577Sjoerg Klass* k = as_Klass(java_class); 76088577Sjoerg if (!k->oop_is_instance()) { 76188577Sjoerg name = k->name(); 76288577Sjoerg name->increment_refcount(); 76388577Sjoerg } else { 76488577Sjoerg ResourceMark rm; 7654910Swollman const char* sigstr = k->signature_name(); 7664910Swollman int siglen = (int) strlen(sigstr); 7674910Swollman if (!intern_if_not_found) { 7684910Swollman name = SymbolTable::probe(sigstr, siglen); 7694910Swollman } else { 77012820Sphk name = SymbolTable::new_symbol(sigstr, siglen, THREAD); 77125706Sjoerg } 77225706Sjoerg } 7734910Swollman } 7744910Swollman return name; 7754910Swollman} 77678064Sume 77725955Sjoerg 77888534SjoergKlass* java_lang_Class::array_klass(oop java_class) { 77942066Sphk Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset)); 7804910Swollman assert(k == NULL || k->is_klass() && k->oop_is_array(), "should be array klass"); 78125944Sjoerg return k; 78225944Sjoerg} 78325944Sjoerg 78425944Sjoerg 78588723Sjoergvoid java_lang_Class::set_array_klass(oop java_class, Klass* klass) { 78688723Sjoerg assert(klass->is_klass() && klass->oop_is_array(), "should be array klass"); 78788723Sjoerg java_class->metadata_field_put(_array_klass_offset, klass); 7884910Swollman} 7894910Swollman 7904910Swollman 7914910Swollmanbool java_lang_Class::is_primitive(oop java_class) { 7924910Swollman // should assert: 79325944Sjoerg //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 79488723Sjoerg bool is_primitive = (java_class->metadata_field(_klass_offset) == NULL); 79525944Sjoerg 79688723Sjoerg#ifdef ASSERT 79788723Sjoerg if (is_primitive) { 79888723Sjoerg Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset)); 79988723Sjoerg assert(k == NULL || is_java_primitive(ArrayKlass::cast(k)->element_type()), 80088723Sjoerg "Should be either the T_VOID primitive or a java primitive"); 80188723Sjoerg } 80288723Sjoerg#endif 80388723Sjoerg 80488723Sjoerg return is_primitive; 80588723Sjoerg} 80688723Sjoerg 80788723Sjoerg 80825944SjoergBasicType java_lang_Class::primitive_type(oop java_class) { 80925944Sjoerg assert(java_lang_Class::is_primitive(java_class), "just checking"); 81025944Sjoerg Klass* ak = ((Klass*)java_class->metadata_field(_array_klass_offset)); 81125944Sjoerg BasicType type = T_VOID; 81225944Sjoerg if (ak != NULL) { 81325944Sjoerg // Note: create_basic_type_mirror above initializes ak to a non-null value. 81425944Sjoerg type = ArrayKlass::cast(ak)->element_type(); 81525944Sjoerg } else { 81625944Sjoerg assert(java_class == Universe::void_mirror(), "only valid non-array primitive"); 81778134Sume } 8184910Swollman assert(Universe::java_mirror(type) == java_class, "must be consistent"); 81912436Speter return type; 82040008Sjoerg} 82112436Speter 82212436SpeterBasicType java_lang_Class::as_BasicType(oop java_class, Klass** reference_klass) { 8234910Swollman assert(java_lang_Class::is_instance(java_class), "must be a Class object"); 82442104Sphk if (is_primitive(java_class)) { 82542104Sphk if (reference_klass != NULL) 82642104Sphk (*reference_klass) = NULL; 82742104Sphk return primitive_type(java_class); 82842104Sphk } else { 82942104Sphk if (reference_klass != NULL) 83042104Sphk (*reference_klass) = as_Klass(java_class); 83142104Sphk return T_OBJECT; 83242104Sphk } 83370199Sjhay} 83442104Sphk 83542104Sphk 83642104Sphkoop java_lang_Class::primitive_mirror(BasicType t) { 83742104Sphk oop mirror = Universe::java_mirror(t); 83842104Sphk assert(mirror != NULL && mirror->is_a(SystemDictionary::Class_klass()), "must be a Class"); 83942104Sphk assert(java_lang_Class::is_primitive(mirror), "must be primitive"); 84042104Sphk return mirror; 84142104Sphk} 84242104Sphk 84342104Sphkbool java_lang_Class::offsets_computed = false; 84470199Sjhayint java_lang_Class::classRedefinedCount_offset = -1; 84542104Sphk 84642104Sphkvoid java_lang_Class::compute_offsets() { 84742104Sphk assert(!offsets_computed, "offsets should be initialized only once"); 84842104Sphk offsets_computed = true; 84969152Sjlemon 85041686Sphk Klass* klass_oop = SystemDictionary::Class_klass(); 85141686Sphk // The classRedefinedCount field is only present starting in 1.5, 85212436Speter // so don't go fatal. 85341686Sphk compute_optional_offset(classRedefinedCount_offset, 85441686Sphk klass_oop, vmSymbols::classRedefinedCount_name(), vmSymbols::int_signature()); 85541686Sphk 85641686Sphk CLASS_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); 85741686Sphk} 85841686Sphk 85941686Sphkint java_lang_Class::classRedefinedCount(oop the_class_mirror) { 86041686Sphk if (!JDK_Version::is_gte_jdk15x_version() 86188534Sjoerg || classRedefinedCount_offset == -1) { 86288534Sjoerg // The classRedefinedCount field is only present starting in 1.5. 86388534Sjoerg // If we don't have an offset for it then just return -1 as a marker. 86488534Sjoerg return -1; 86588534Sjoerg } 86688534Sjoerg 86788599Sjoerg return the_class_mirror->int_field(classRedefinedCount_offset); 86888534Sjoerg} 86988534Sjoerg 87088534Sjoergvoid java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) { 87188534Sjoerg if (!JDK_Version::is_gte_jdk15x_version() 87288534Sjoerg || classRedefinedCount_offset == -1) { 87388534Sjoerg // The classRedefinedCount field is only present starting in 1.5. 87488534Sjoerg // If we don't have an offset for it then nothing to set. 87588534Sjoerg return; 87688534Sjoerg } 87788534Sjoerg 87888534Sjoerg the_class_mirror->int_field_put(classRedefinedCount_offset, value); 87988534Sjoerg} 88088534Sjoerg 88188534Sjoerg 88288534Sjoerg// Note: JDK1.1 and before had a privateInfo_offset field which was used for the 8834910Swollman// platform thread structure, and a eetop offset which was used for thread 8844910Swollman// local storage (and unused by the HotSpot VM). In JDK1.2 the two structures 8854910Swollman// merged, so in the HotSpot VM we just use the eetop field for the thread 88678064Sume// instead of the privateInfo_offset. 88778064Sume// 88878064Sume// Note: The stackSize field is only present starting in 1.4. 88978064Sume 89078064Sumeint java_lang_Thread::_name_offset = 0; 89178064Sumeint java_lang_Thread::_group_offset = 0; 8924910Swollmanint java_lang_Thread::_contextClassLoader_offset = 0; 8934910Swollmanint java_lang_Thread::_inheritedAccessControlContext_offset = 0; 8944910Swollmanint java_lang_Thread::_priority_offset = 0; 8954910Swollmanint java_lang_Thread::_eetop_offset = 0; 8964910Swollmanint java_lang_Thread::_daemon_offset = 0; 89742066Sphkint java_lang_Thread::_stillborn_offset = 0; 89840008Sjoergint java_lang_Thread::_stackSize_offset = 0; 89940008Sjoergint java_lang_Thread::_tid_offset = 0; 90025944Sjoergint java_lang_Thread::_thread_status_offset = 0; 9014910Swollmanint java_lang_Thread::_park_blocker_offset = 0; 9024910Swollmanint java_lang_Thread::_park_event_offset = 0 ; 9034910Swollman 90440008Sjoerg 90540008Sjoergvoid java_lang_Thread::compute_offsets() { 90640008Sjoerg assert(_group_offset == 0, "offsets should be initialized only once"); 90740008Sjoerg 9084910Swollman Klass* k = SystemDictionary::Thread_klass(); 90945152Sphk compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::char_array_signature()); 91028088Skjc compute_offset(_group_offset, k, vmSymbols::group_name(), vmSymbols::threadgroup_signature()); 9114910Swollman compute_offset(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature()); 9124910Swollman compute_offset(_inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature()); 9134910Swollman compute_offset(_priority_offset, k, vmSymbols::priority_name(), vmSymbols::int_signature()); 9144910Swollman compute_offset(_daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); 9154910Swollman compute_offset(_eetop_offset, k, vmSymbols::eetop_name(), vmSymbols::long_signature()); 9164910Swollman compute_offset(_stillborn_offset, k, vmSymbols::stillborn_name(), vmSymbols::bool_signature()); 9174910Swollman // The stackSize field is only present starting in 1.4, so don't go fatal. 9184910Swollman compute_optional_offset(_stackSize_offset, k, vmSymbols::stackSize_name(), vmSymbols::long_signature()); 9194910Swollman // The tid and thread_status fields are only present starting in 1.5, so don't go fatal. 92045152Sphk compute_optional_offset(_tid_offset, k, vmSymbols::thread_id_name(), vmSymbols::long_signature()); 92111189Sjkh compute_optional_offset(_thread_status_offset, k, vmSymbols::thread_status_name(), vmSymbols::int_signature()); 92211189Sjkh // The parkBlocker field is only present starting in 1.6, so don't go fatal. 92325955Sjoerg compute_optional_offset(_park_blocker_offset, k, vmSymbols::park_blocker_name(), vmSymbols::object_signature()); 92425955Sjoerg compute_optional_offset(_park_event_offset, k, vmSymbols::park_event_name(), 92525955Sjoerg vmSymbols::long_signature()); 92625955Sjoerg} 92725955Sjoerg 92825955Sjoerg 92925955SjoergJavaThread* java_lang_Thread::thread(oop java_thread) { 93025955Sjoerg return (JavaThread*)java_thread->address_field(_eetop_offset); 93125955Sjoerg} 93288534Sjoerg 93325955Sjoerg 93425955Sjoergvoid java_lang_Thread::set_thread(oop java_thread, JavaThread* thread) { 93511189Sjkh java_thread->address_field_put(_eetop_offset, (address)thread); 9364910Swollman} 9374910Swollman 93854263Sshin 93954263SshintypeArrayOop java_lang_Thread::name(oop java_thread) { 94054263Sshin oop name = java_thread->obj_field(_name_offset); 94154263Sshin assert(name == NULL || (name->is_typeArray() && TypeArrayKlass::cast(name->klass())->element_type() == T_CHAR), "just checking"); 94254263Sshin return typeArrayOop(name); 94378064Sume} 94478064Sume 94578064Sume 94678064Sumevoid java_lang_Thread::set_name(oop java_thread, typeArrayOop name) { 94778064Sume assert(java_thread->obj_field(_name_offset) == NULL, "name should be NULL"); 94878064Sume java_thread->obj_field_put(_name_offset, name); 94978064Sume} 95078064Sume 95178064Sume 95278064SumeThreadPriority java_lang_Thread::priority(oop java_thread) { 95378064Sume return (ThreadPriority)java_thread->int_field(_priority_offset); 95478064Sume} 95554263Sshin 95654263Sshin 95754263Sshinvoid java_lang_Thread::set_priority(oop java_thread, ThreadPriority priority) { 9584910Swollman java_thread->int_field_put(_priority_offset, priority); 9594910Swollman} 96045152Sphk 9614910Swollman 9624910Swollmanoop java_lang_Thread::threadGroup(oop java_thread) { 9634910Swollman return java_thread->obj_field(_group_offset); 96411819Sjulian} 96512495Speter 96645152Sphk 96712495Speterbool java_lang_Thread::is_stillborn(oop java_thread) { 96811819Sjulian return java_thread->bool_field(_stillborn_offset) != 0; 96911819Sjulian} 9704910Swollman 9714910Swollman 97225944Sjoerg// We never have reason to turn the stillborn bit off 9734910Swollmanvoid java_lang_Thread::set_stillborn(oop java_thread) { 9744910Swollman java_thread->bool_field_put(_stillborn_offset, true); 9754910Swollman} 9764910Swollman 9774910Swollman 9784910Swollmanbool java_lang_Thread::is_alive(oop java_thread) { 97988577Sjoerg JavaThread* thr = java_lang_Thread::thread(java_thread); 9804910Swollman return (thr != NULL); 98169152Sjlemon} 98225944Sjoerg 98325955Sjoerg 9844910Swollmanbool java_lang_Thread::is_daemon(oop java_thread) { 98588577Sjoerg return java_thread->bool_field(_daemon_offset) != 0; 98688577Sjoerg} 98788577Sjoerg 98888577Sjoerg 98988577Sjoergvoid java_lang_Thread::set_daemon(oop java_thread) { 99088577Sjoerg java_thread->bool_field_put(_daemon_offset, true); 99188577Sjoerg} 9924910Swollman 9934910Swollmanoop java_lang_Thread::context_class_loader(oop java_thread) { 9944910Swollman return java_thread->obj_field(_contextClassLoader_offset); 99525706Sjoerg} 99625706Sjoerg 9974910Swollmanoop java_lang_Thread::inherited_access_control_context(oop java_thread) { 9984910Swollman return java_thread->obj_field(_inheritedAccessControlContext_offset); 9994910Swollman} 10004910Swollman 10014910Swollman 100242064Sphkjlong java_lang_Thread::stackSize(oop java_thread) { 10034910Swollman // The stackSize field is only present starting in 1.4 10044910Swollman if (_stackSize_offset > 0) { 10054910Swollman assert(JDK_Version::is_gte_jdk14x_version(), "sanity check"); 10064910Swollman return java_thread->long_field(_stackSize_offset); 10074910Swollman } else { 100842064Sphk return 0; 100942064Sphk } 10104910Swollman} 10114910Swollman 101242104Sphk// Write the thread status value to threadStatus field in java.lang.Thread java class. 101342064Sphkvoid java_lang_Thread::set_thread_status(oop java_thread, 101442104Sphk java_lang_Thread::ThreadStatus status) { 101570199Sjhay // The threadStatus is only present starting in 1.5 101670199Sjhay if (_thread_status_offset > 0) { 101770199Sjhay java_thread->int_field_put(_thread_status_offset, status); 10184910Swollman } 10194910Swollman} 102078064Sume 102178064Sume// Read thread status value from threadStatus field in java.lang.Thread java class. 102225944Sjoergjava_lang_Thread::ThreadStatus java_lang_Thread::get_thread_status(oop java_thread) { 102325944Sjoerg assert(Thread::current()->is_Watcher_thread() || Thread::current()->is_VM_thread() || 102425944Sjoerg JavaThread::current()->thread_state() == _thread_in_vm, 102588716Sjoerg "Java Thread is not running in vm"); 102693818Sjhb // The threadStatus is only present starting in 1.5 102788716Sjoerg if (_thread_status_offset > 0) { 102893818Sjhb return (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset); 102988599Sjoerg } else { 103088723Sjoerg // All we can easily figure out is if it is alive, but that is 103188723Sjoerg // enough info for a valid unknown status. 103288723Sjoerg // These aren't restricted to valid set ThreadStatus values, so 103388723Sjoerg // use JVMTI values and cast. 103488723Sjoerg JavaThread* thr = java_lang_Thread::thread(java_thread); 103588723Sjoerg if (thr == NULL) { 103688723Sjoerg // the thread hasn't run yet or is in the process of exiting 103788599Sjoerg return NEW; 103888599Sjoerg } 103925944Sjoerg return (java_lang_Thread::ThreadStatus)JVMTI_THREAD_STATE_ALIVE; 104025944Sjoerg } 104178064Sume} 104230300Sjoerg 104330300Sjoerg 10444910Swollmanjlong java_lang_Thread::thread_id(oop java_thread) { 10454910Swollman // The thread ID field is only present starting in 1.5 104630300Sjoerg if (_tid_offset > 0) { 104725706Sjoerg return java_thread->long_field(_tid_offset); 10484910Swollman } else { 10494910Swollman return 0; 105025944Sjoerg } 10514910Swollman} 10524910Swollman 10534910Swollmanoop java_lang_Thread::park_blocker(oop java_thread) { 10544910Swollman assert(JDK_Version::current().supports_thread_park_blocker() && 10554910Swollman _park_blocker_offset != 0, "Must support parkBlocker field"); 10564910Swollman 10574910Swollman if (_park_blocker_offset > 0) { 10584910Swollman return java_thread->obj_field(_park_blocker_offset); 10594910Swollman } 10604910Swollman 106140008Sjoerg return NULL; 106225944Sjoerg} 106325944Sjoerg 106440008Sjoergjlong java_lang_Thread::park_event(oop java_thread) { 106540008Sjoerg if (_park_event_offset > 0) { 106669152Sjlemon return java_thread->long_field(_park_event_offset); 106769152Sjlemon } 10684910Swollman return 0; 10694910Swollman} 10704910Swollman 10714910Swollmanbool java_lang_Thread::set_park_event(oop java_thread, jlong ptr) { 10724910Swollman if (_park_event_offset > 0) { 107325706Sjoerg java_thread->long_field_put(_park_event_offset, ptr); 107425706Sjoerg return true; 10754910Swollman } 10764910Swollman return false; 10774910Swollman} 107825944Sjoerg 107925944Sjoerg 108026018Sjoergconst char* java_lang_Thread::thread_status_name(oop java_thread) { 10814910Swollman assert(JDK_Version::is_gte_jdk15x_version() && _thread_status_offset != 0, "Must have thread status"); 10824910Swollman ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset); 10834910Swollman switch (status) { 108411189Sjkh case NEW : return "NEW"; 108511189Sjkh case RUNNABLE : return "RUNNABLE"; 108612820Sphk case SLEEPING : return "TIMED_WAITING (sleeping)"; 108725706Sjoerg case IN_OBJECT_WAIT : return "WAITING (on object monitor)"; 108811189Sjkh case IN_OBJECT_WAIT_TIMED : return "TIMED_WAITING (on object monitor)"; 108911189Sjkh case PARKED : return "WAITING (parking)"; 109025944Sjoerg case PARKED_TIMED : return "TIMED_WAITING (parking)"; 109111189Sjkh case BLOCKED_ON_MONITOR_ENTER : return "BLOCKED (on object monitor)"; 109225944Sjoerg case TERMINATED : return "TERMINATED"; 109326018Sjoerg default : return "UNKNOWN"; 109426018Sjoerg }; 109525944Sjoerg} 109611189Sjkhint java_lang_ThreadGroup::_parent_offset = 0; 109711189Sjkhint java_lang_ThreadGroup::_name_offset = 0; 109811189Sjkhint java_lang_ThreadGroup::_threads_offset = 0; 109911189Sjkhint java_lang_ThreadGroup::_groups_offset = 0; 11004910Swollmanint java_lang_ThreadGroup::_maxPriority_offset = 0; 11014910Swollmanint java_lang_ThreadGroup::_destroyed_offset = 0; 110225706Sjoergint java_lang_ThreadGroup::_daemon_offset = 0; 110325706Sjoergint java_lang_ThreadGroup::_vmAllowSuspension_offset = 0; 11044910Swollmanint java_lang_ThreadGroup::_nthreads_offset = 0; 11054910Swollmanint java_lang_ThreadGroup::_ngroups_offset = 0; 11064910Swollman 110725944Sjoergoop java_lang_ThreadGroup::parent(oop java_thread_group) { 11084910Swollman assert(java_thread_group->is_oop(), "thread group must be oop"); 110925944Sjoerg return java_thread_group->obj_field(_parent_offset); 111026018Sjoerg} 111130300Sjoerg 111230300Sjoerg// ("name as oop" accessor is not necessary) 111326018Sjoerg 111426018SjoergtypeArrayOop java_lang_ThreadGroup::name(oop java_thread_group) { 111526018Sjoerg oop name = java_thread_group->obj_field(_name_offset); 111626018Sjoerg // ThreadGroup.name can be null 111726018Sjoerg return name == NULL ? (typeArrayOop)NULL : java_lang_String::value(name); 111845152Sphk} 111926018Sjoerg 112026018Sjoergint java_lang_ThreadGroup::nthreads(oop java_thread_group) { 112126018Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 112226018Sjoerg return java_thread_group->int_field(_nthreads_offset); 112326018Sjoerg} 112426018Sjoerg 11254910SwollmanobjArrayOop java_lang_ThreadGroup::threads(oop java_thread_group) { 11264910Swollman oop threads = java_thread_group->obj_field(_threads_offset); 11274910Swollman assert(threads != NULL, "threadgroups should have threads"); 112830300Sjoerg assert(threads->is_objArray(), "just checking"); // Todo: Add better type checking code 112930300Sjoerg return objArrayOop(threads); 113030300Sjoerg} 113130300Sjoerg 113230300Sjoergint java_lang_ThreadGroup::ngroups(oop java_thread_group) { 113330300Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 113430300Sjoerg return java_thread_group->int_field(_ngroups_offset); 113530300Sjoerg} 113630300Sjoerg 113730300SjoergobjArrayOop java_lang_ThreadGroup::groups(oop java_thread_group) { 113830300Sjoerg oop groups = java_thread_group->obj_field(_groups_offset); 113930300Sjoerg assert(groups == NULL || groups->is_objArray(), "just checking"); // Todo: Add better type checking code 114030300Sjoerg return objArrayOop(groups); 114145152Sphk} 114230300Sjoerg 114330300SjoergThreadPriority java_lang_ThreadGroup::maxPriority(oop java_thread_group) { 114430300Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 114530300Sjoerg return (ThreadPriority) java_thread_group->int_field(_maxPriority_offset); 114630300Sjoerg} 114730300Sjoerg 114830300Sjoergbool java_lang_ThreadGroup::is_destroyed(oop java_thread_group) { 114925944Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 11504910Swollman return java_thread_group->bool_field(_destroyed_offset) != 0; 115125944Sjoerg} 115242104Sphk 11534910Swollmanbool java_lang_ThreadGroup::is_daemon(oop java_thread_group) { 115425944Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 115525944Sjoerg return java_thread_group->bool_field(_daemon_offset) != 0; 115630300Sjoerg} 11574910Swollman 115825944Sjoergbool java_lang_ThreadGroup::is_vmAllowSuspension(oop java_thread_group) { 115930300Sjoerg assert(java_thread_group->is_oop(), "thread group must be oop"); 116025944Sjoerg return java_thread_group->bool_field(_vmAllowSuspension_offset) != 0; 116125944Sjoerg} 116225944Sjoerg 116325944Sjoergvoid java_lang_ThreadGroup::compute_offsets() { 11644910Swollman assert(_parent_offset == 0, "offsets should be initialized only once"); 116525944Sjoerg 116688503Sjoerg Klass* k = SystemDictionary::ThreadGroup_klass(); 116788503Sjoerg 1168102412Scharnier compute_offset(_parent_offset, k, vmSymbols::parent_name(), vmSymbols::threadgroup_signature()); 116911189Sjkh compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); 117025944Sjoerg compute_offset(_threads_offset, k, vmSymbols::threads_name(), vmSymbols::thread_array_signature()); 117125944Sjoerg compute_offset(_groups_offset, k, vmSymbols::groups_name(), vmSymbols::threadgroup_array_signature()); 117225944Sjoerg compute_offset(_maxPriority_offset, k, vmSymbols::maxPriority_name(), vmSymbols::int_signature()); 117325944Sjoerg compute_offset(_destroyed_offset, k, vmSymbols::destroyed_name(), vmSymbols::bool_signature()); 117425944Sjoerg compute_offset(_daemon_offset, k, vmSymbols::daemon_name(), vmSymbols::bool_signature()); 117545152Sphk compute_offset(_vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature()); 117645152Sphk compute_offset(_nthreads_offset, k, vmSymbols::nthreads_name(), vmSymbols::int_signature()); 117745152Sphk compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); 117845152Sphk} 117945152Sphk 118045152Sphkoop java_lang_Throwable::unassigned_stacktrace() { 118145152Sphk InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Throwable_klass()); 118245152Sphk address addr = ik->static_field_addr(static_unassigned_stacktrace_offset); 118345152Sphk if (UseCompressedOops) { 118445152Sphk return oopDesc::load_decode_heap_oop((narrowOop *)addr); 118545152Sphk } else { 118645152Sphk return oopDesc::load_decode_heap_oop((oop*)addr); 118745152Sphk } 11884910Swollman} 11894910Swollman 119045152Sphkoop java_lang_Throwable::backtrace(oop throwable) { 119170199Sjhay return throwable->obj_field_acquire(backtrace_offset); 119245152Sphk} 119345152Sphk 119445152Sphk 119526018Sjoergvoid java_lang_Throwable::set_backtrace(oop throwable, oop value) { 119625944Sjoerg throwable->release_obj_field_put(backtrace_offset, value); 119745152Sphk} 119826018Sjoerg 11994910Swollman 120045152Sphkoop java_lang_Throwable::message(oop throwable) { 120170199Sjhay return throwable->obj_field(detailMessage_offset); 120245152Sphk} 120345152Sphk 120445152Sphk 120545152Sphkoop java_lang_Throwable::message(Handle throwable) { 120645152Sphk return throwable->obj_field(detailMessage_offset); 120745152Sphk} 120845152Sphk 120945152Sphk 121045152Sphkvoid java_lang_Throwable::set_message(oop throwable, oop value) { 121145152Sphk throwable->obj_field_put(detailMessage_offset, value); 121245152Sphk} 121345152Sphk 121445152Sphk 12154910Swollmanvoid java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) { 121611189Sjkh throwable->obj_field_put(stackTrace_offset, st_element_array); 121725944Sjoerg} 121825944Sjoerg 121925944Sjoergvoid java_lang_Throwable::clear_stacktrace(oop throwable) { 122025944Sjoerg assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4"); 122125944Sjoerg set_stacktrace(throwable, NULL); 122225944Sjoerg} 122325944Sjoerg 122425944Sjoerg 12254910Swollmanvoid java_lang_Throwable::print(oop throwable, outputStream* st) { 122625944Sjoerg ResourceMark rm; 122725944Sjoerg Klass* k = throwable->klass(); 122825944Sjoerg assert(k != NULL, "just checking"); 122925944Sjoerg st->print("%s", InstanceKlass::cast(k)->external_name()); 123025944Sjoerg oop msg = message(throwable); 123125944Sjoerg if (msg != NULL) { 12324910Swollman st->print(": %s", java_lang_String::as_utf8_string(msg)); 123325944Sjoerg } 123425944Sjoerg} 123525944Sjoerg 123625944Sjoerg 123711189Sjkhvoid java_lang_Throwable::print(Handle throwable, outputStream* st) { 123825944Sjoerg ResourceMark rm; 123925944Sjoerg Klass* k = throwable->klass(); 124025944Sjoerg assert(k != NULL, "just checking"); 124125944Sjoerg st->print("%s", InstanceKlass::cast(k)->external_name()); 12424910Swollman oop msg = message(throwable); 124325944Sjoerg if (msg != NULL) { 124425944Sjoerg st->print(": %s", java_lang_String::as_utf8_string(msg)); 124525944Sjoerg } 12464910Swollman} 124711189Sjkh 124830300Sjoerg// After this many redefines, the stack trace is unreliable. 124930300Sjoergconst int MAX_VERSION = USHRT_MAX; 125030300Sjoerg 125130300Sjoerg// Helper backtrace functions to store bci|version together. 125230300Sjoergstatic inline int merge_bci_and_version(int bci, int version) { 125325944Sjoerg // only store u2 for version, checking for overflow. 125430300Sjoerg if (version > USHRT_MAX || version < 0) version = MAX_VERSION; 12554910Swollman assert((jushort)bci == bci, "bci should be short"); 125625944Sjoerg return build_int_from_shorts(version, bci); 125730300Sjoerg} 12584910Swollman 12594910Swollmanstatic inline int bci_at(unsigned int merged) { 126070199Sjhay return extract_high_short_from_int(merged); 126125944Sjoerg} 126225944Sjoergstatic inline int version_at(unsigned int merged) { 126325944Sjoerg return extract_low_short_from_int(merged); 12644910Swollman} 12654910Swollman 12664910Swollmanstatic inline bool version_matches(Method* method, int version) { 126730300Sjoerg return (method->constants()->version() == version && version < MAX_VERSION); 126825706Sjoerg} 12694910Swollman 127025944Sjoergstatic inline int get_line_number(Method* method, int bci) { 12714910Swollman int line_number = 0; 127230300Sjoerg if (method->is_native()) { 12734910Swollman // Negative value different from -1 below, enabling Java code in 127427929Sitojun // class java.lang.StackTraceElement to distinguish "native" from 127525706Sjoerg // "no LineNumberTable". JDK tests for -2. 127625706Sjoerg line_number = -2; 127740008Sjoerg } else { 127840008Sjoerg // Returns -1 if no LineNumberTable, and otherwise actual line number 12794910Swollman line_number = method->line_number_from_bci(bci); 12804910Swollman if (line_number == -1 && ShowHiddenFrames) { 12814910Swollman line_number = bci + 1000000; 128225706Sjoerg } 128325706Sjoerg } 128440008Sjoerg return line_number; 128525706Sjoerg} 128640008Sjoerg 128740008Sjoerg// This class provides a simple wrapper over the internal structure of 128840008Sjoerg// exception backtrace to insulate users of the backtrace from needing 12894910Swollman// to know what it looks like. 12904910Swollmanclass BacktraceBuilder: public StackObj { 129125706Sjoerg private: 129269211Sphk Handle _backtrace; 129340008Sjoerg objArrayOop _head; 12944910Swollman typeArrayOop _methods; 12954910Swollman typeArrayOop _bcis; 12964910Swollman objArrayOop _mirrors; 12974910Swollman int _index; 12984910Swollman No_Safepoint_Verifier _nsv; 12994910Swollman 130078064Sume public: 130178064Sume 13024910Swollman enum { 13034910Swollman trace_methods_offset = java_lang_Throwable::trace_methods_offset, 130411189Sjkh trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, 130540008Sjoerg trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, 130640008Sjoerg trace_next_offset = java_lang_Throwable::trace_next_offset, 130711189Sjkh trace_size = java_lang_Throwable::trace_size, 130811189Sjkh trace_chunk_size = java_lang_Throwable::trace_chunk_size 130911189Sjkh }; 131026018Sjoerg 131111189Sjkh // get info out of chunks 131211189Sjkh static typeArrayOop get_methods(objArrayHandle chunk) { 13134910Swollman typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset)); 13144910Swollman assert(methods != NULL, "method array should be initialized in backtrace"); 13154910Swollman return methods; 131642065Sphk } 131778064Sume static typeArrayOop get_bcis(objArrayHandle chunk) { 131840008Sjoerg typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset)); 131978064Sume assert(bcis != NULL, "bci array should be initialized in backtrace"); 132040008Sjoerg return bcis; 132111189Sjkh } 132211189Sjkh static objArrayOop get_mirrors(objArrayHandle chunk) { 132330300Sjoerg objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); 132411189Sjkh assert(mirrors != NULL, "mirror array should be initialized in backtrace"); 132511189Sjkh return mirrors; 132630300Sjoerg } 132740008Sjoerg 132811189Sjkh // constructor for new backtrace 13294910Swollman BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) { 13304910Swollman expand(CHECK); 133130300Sjoerg _backtrace = _head; 133230300Sjoerg _index = 0; 133330300Sjoerg } 13344910Swollman 13354910Swollman BacktraceBuilder(objArrayHandle backtrace) { 13364910Swollman _methods = get_methods(backtrace); 13374910Swollman _bcis = get_bcis(backtrace); 13384910Swollman _mirrors = get_mirrors(backtrace); 133925944Sjoerg assert(_methods->length() == _bcis->length() && 13404910Swollman _methods->length() == _mirrors->length(), 134112820Sphk "method and source information arrays should match"); 134225944Sjoerg 134325944Sjoerg // head is the preallocated backtrace 134425944Sjoerg _backtrace = _head = backtrace(); 134525944Sjoerg _index = 0; 134625944Sjoerg } 134725944Sjoerg 134842065Sphk void expand(TRAPS) { 134935029Sphk objArrayHandle old_head(THREAD, _head); 135040008Sjoerg Pause_No_Safepoint_Verifier pnsv(&_nsv); 135140008Sjoerg 135240008Sjoerg objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK); 135325944Sjoerg objArrayHandle new_head(THREAD, head); 135442065Sphk 135536119Sphk typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK); 135640008Sjoerg typeArrayHandle new_methods(THREAD, methods); 135770199Sjhay 135825944Sjoerg typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK); 135925944Sjoerg typeArrayHandle new_bcis(THREAD, bcis); 136025944Sjoerg 136125944Sjoerg objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); 136225944Sjoerg objArrayHandle new_mirrors(THREAD, mirrors); 136325944Sjoerg 136425944Sjoerg if (!old_head.is_null()) { 136525944Sjoerg old_head->obj_at_put(trace_next_offset, new_head()); 136625944Sjoerg } 136725944Sjoerg new_head->obj_at_put(trace_methods_offset, new_methods()); 136825944Sjoerg new_head->obj_at_put(trace_bcis_offset, new_bcis()); 136925944Sjoerg new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); 137025944Sjoerg 137125944Sjoerg _head = new_head(); 137225944Sjoerg _methods = new_methods(); 137325944Sjoerg _bcis = new_bcis(); 137440008Sjoerg _mirrors = new_mirrors(); 137542065Sphk _index = 0; 137635029Sphk } 137735029Sphk 137840008Sjoerg oop backtrace() { 137940008Sjoerg return _backtrace(); 138040008Sjoerg } 138140008Sjoerg 138225944Sjoerg inline void push(Method* method, int bci, TRAPS) { 138325944Sjoerg // Smear the -1 bci to 0 since the array only holds unsigned 138425944Sjoerg // shorts. The later line number lookup would just smear the -1 138540008Sjoerg // to a 0 even if it could be recorded. 138640008Sjoerg if (bci == SynchronizationEntryBCI) bci = 0; 138740008Sjoerg 138825944Sjoerg if (_index >= trace_chunk_size) { 138969152Sjlemon methodHandle mhandle(THREAD, method); 139069152Sjlemon expand(CHECK); 139125944Sjoerg method = mhandle(); 139225944Sjoerg } 139370199Sjhay 139425944Sjoerg _methods->short_at_put(_index, method->method_idnum()); 139525944Sjoerg _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); 139625944Sjoerg 139725944Sjoerg // We need to save the mirrors in the backtrace to keep the class 139825944Sjoerg // from being unloaded while we still have this stack trace. 139925944Sjoerg assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); 140025944Sjoerg _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); 140125706Sjoerg _index++; 140225706Sjoerg } 14034910Swollman 140425944Sjoerg}; 14054910Swollman 14064910Swollman// Print stack trace element to resource allocated buffer 14074910Swollmanchar* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, 14084910Swollman int method_id, int version, int bci) { 14094910Swollman 14104910Swollman // Get strings and string lengths 14114910Swollman InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 14124910Swollman const char* klass_name = holder->external_name(); 14134910Swollman int buf_len = (int)strlen(klass_name); 14144910Swollman 14154910Swollman // The method id may point to an obsolete method, can't get more stack information 14164910Swollman Method* method = holder->method_with_idnum(method_id); 14174910Swollman if (method == NULL) { 14184910Swollman char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); 14194910Swollman // This is what the java code prints in this case - added Redefined 14204910Swollman sprintf(buf, "\tat %s.null (Redefined)", klass_name); 14214910Swollman return buf; 14224910Swollman } 14234910Swollman 14244910Swollman char* method_name = method->name()->as_C_string(); 14254910Swollman buf_len += (int)strlen(method_name); 14264910Swollman 14274910Swollman char* source_file_name = NULL; 14284910Swollman if (version_matches(method, version)) { 142925706Sjoerg Symbol* source = holder->source_file_name(); 143040008Sjoerg if (source != NULL) { 143140008Sjoerg source_file_name = source->as_C_string(); 143225944Sjoerg buf_len += (int)strlen(source_file_name); 143325944Sjoerg } 143425944Sjoerg } 143544145Sphk 143669211Sphk // Allocate temporary buffer with extra space for formatting and line number 14374910Swollman char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); 143869152Sjlemon 143969152Sjlemon // Print stack trace line in buffer 14404910Swollman sprintf(buf, "\tat %s.%s", klass_name, method_name); 14414910Swollman 14424910Swollman if (!version_matches(method, version)) { 144325944Sjoerg strcat(buf, "(Redefined)"); 14444910Swollman } else { 144512820Sphk int line_number = get_line_number(method, bci); 144625944Sjoerg if (line_number == -2) { 14474910Swollman strcat(buf, "(Native Method)"); 144825944Sjoerg } else { 144925944Sjoerg if (source_file_name != NULL && (line_number != -1)) { 145025944Sjoerg // Sourcename and linenumber 145125944Sjoerg sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); 145225944Sjoerg } else if (source_file_name != NULL) { 14534910Swollman // Just sourcename 145425944Sjoerg sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); 145525944Sjoerg } else { 145625944Sjoerg // Neither sourcename nor linenumber 145740008Sjoerg sprintf(buf + (int)strlen(buf), "(Unknown Source)"); 145840008Sjoerg } 14594910Swollman nmethod* nm = method->code(); 146025944Sjoerg if (WizardMode && nm != NULL) { 146125944Sjoerg sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); 146225944Sjoerg } 146325944Sjoerg } 146440008Sjoerg } 146540008Sjoerg 146625944Sjoerg return buf; 146725944Sjoerg} 146844145Sphk 146969211Sphkvoid java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, 147025944Sjoerg int method_id, int version, int bci) { 147125944Sjoerg ResourceMark rm; 147225944Sjoerg char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci); 147330300Sjoerg st->print_cr("%s", buf); 147425944Sjoerg} 147525944Sjoerg 147625944Sjoergvoid java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) { 147725944Sjoerg Handle mirror = method->method_holder()->java_mirror(); 147869211Sphk int method_id = method->method_idnum(); 147940008Sjoerg int version = method->constants()->version(); 148025944Sjoerg print_stack_element(st, mirror, method_id, version, bci); 148125944Sjoerg} 148225944Sjoerg 148325944Sjoergconst char* java_lang_Throwable::no_stack_trace_message() { 148430300Sjoerg return "\t<<no stack trace available>>"; 148530300Sjoerg} 148630300Sjoerg 148730300Sjoerg 148830300Sjoerg// Currently used only for exceptions occurring during startup 148930300Sjoergvoid java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { 149030300Sjoerg Thread *THREAD = Thread::current(); 149130300Sjoerg Handle h_throwable(THREAD, throwable); 149230300Sjoerg while (h_throwable.not_null()) { 149330300Sjoerg objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); 149425944Sjoerg if (result.is_null()) { 149525944Sjoerg st->print_cr("%s", no_stack_trace_message()); 149625944Sjoerg return; 149725944Sjoerg } 149825944Sjoerg 1499102412Scharnier while (result.not_null()) { 150025944Sjoerg 150125944Sjoerg // Get method id, bci, version and mirror from chunk 150270199Sjhay typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); 150370199Sjhay typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); 150470199Sjhay objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); 150570199Sjhay 150670199Sjhay int length = methods()->length(); 150770199Sjhay for (int index = 0; index < length; index++) { 150870199Sjhay Handle mirror(THREAD, mirrors->obj_at(index)); 150970199Sjhay // NULL mirror means end of stack trace 151070199Sjhay if (mirror.is_null()) goto handle_cause; 151170199Sjhay int method = methods->short_at(index); 151225944Sjoerg int version = version_at(bcis->int_at(index)); 151325944Sjoerg int bci = bci_at(bcis->int_at(index)); 151425944Sjoerg print_stack_element(st, mirror, method, version, bci); 151525944Sjoerg } 151625944Sjoerg result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); 151725944Sjoerg } 151825944Sjoerg handle_cause: 151925944Sjoerg { 152025944Sjoerg EXCEPTION_MARK; 152125944Sjoerg JavaValue cause(T_OBJECT); 152225944Sjoerg JavaCalls::call_virtual(&cause, 152325944Sjoerg h_throwable, 152425944Sjoerg KlassHandle(THREAD, h_throwable->klass()), 152540008Sjoerg vmSymbols::getCause_name(), 152640008Sjoerg vmSymbols::void_throwable_signature(), 152726077Sjoerg THREAD); 152825944Sjoerg // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 152925944Sjoerg if (HAS_PENDING_EXCEPTION) { 153025944Sjoerg CLEAR_PENDING_EXCEPTION; 153125944Sjoerg h_throwable = Handle(); 153225944Sjoerg } else { 153340008Sjoerg h_throwable = Handle(THREAD, (oop) cause.get_jobject()); 153440008Sjoerg if (h_throwable.not_null()) { 153525944Sjoerg st->print("Caused by: "); 153625944Sjoerg print(h_throwable, st); 153725944Sjoerg st->cr(); 153825944Sjoerg } 153925944Sjoerg } 154025944Sjoerg } 154125944Sjoerg } 154225944Sjoerg} 154369211Sphk 154440008Sjoergvoid java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { 154525944Sjoerg if (!StackTraceInThrowable) return; 154625944Sjoerg ResourceMark rm(THREAD); 154725944Sjoerg 154825944Sjoerg // Start out by clearing the backtrace for this object, in case the VM 154925944Sjoerg // runs out of memory while allocating the stack trace 155025944Sjoerg set_backtrace(throwable(), NULL); 155125944Sjoerg if (JDK_Version::is_gte_jdk14x_version()) { 155225944Sjoerg // New since 1.4, clear lazily constructed Java level stacktrace if 155325944Sjoerg // refilling occurs 155425944Sjoerg // This is unnecessary in 1.7+ but harmless 155525944Sjoerg clear_stacktrace(throwable()); 155625944Sjoerg } 155725944Sjoerg 155825944Sjoerg int max_depth = MaxJavaStackTraceDepth; 155925944Sjoerg JavaThread* thread = (JavaThread*)THREAD; 156025944Sjoerg BacktraceBuilder bt(CHECK); 156125944Sjoerg 156225944Sjoerg // If there is no Java frame just return the method that was being called 1563102412Scharnier // with bci 0 156425944Sjoerg if (!thread->has_last_Java_frame()) { 156525944Sjoerg if (max_depth >= 1 && method() != NULL) { 156625944Sjoerg bt.push(method(), 0, CHECK); 156725944Sjoerg set_backtrace(throwable(), bt.backtrace()); 156825944Sjoerg } 156925944Sjoerg return; 157025944Sjoerg } 157125944Sjoerg 157240008Sjoerg // Instead of using vframe directly, this version of fill_in_stack_trace 157340008Sjoerg // basically handles everything by hand. This significantly improved the 157425944Sjoerg // speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows. 157525944Sjoerg // See bug 6333838 for more details. 157625944Sjoerg // The "ASSERT" here is to verify this method generates the exactly same stack 157740008Sjoerg // trace as utilizing vframe. 157840008Sjoerg#ifdef ASSERT 157925944Sjoerg vframeStream st(thread); 158025944Sjoerg methodHandle st_method(THREAD, st.method()); 158125944Sjoerg#endif 158225944Sjoerg int total_count = 0; 158325944Sjoerg RegisterMap map(thread, false); 158425944Sjoerg int decode_offset = 0; 158525944Sjoerg nmethod* nm = NULL; 158625944Sjoerg bool skip_fillInStackTrace_check = false; 158725944Sjoerg bool skip_throwableInit_check = false; 158869211Sphk bool skip_hidden = !ShowHiddenFrames; 158940008Sjoerg 159025944Sjoerg for (frame fr = thread->last_frame(); max_depth != total_count;) { 159125944Sjoerg Method* method = NULL; 159225944Sjoerg int bci = 0; 159325944Sjoerg 159425944Sjoerg // Compiled java method case. 159525944Sjoerg if (decode_offset != 0) { 159625944Sjoerg DebugInfoReadStream stream(nm, decode_offset); 159725944Sjoerg decode_offset = stream.read_int(); 15984910Swollman method = (Method*)nm->metadata_at(stream.read_int()); 159925944Sjoerg bci = stream.read_bci(); 160025944Sjoerg } else { 160125944Sjoerg if (fr.is_first_frame()) break; 160225944Sjoerg address pc = fr.pc(); 160325944Sjoerg if (fr.is_interpreted_frame()) { 160425944Sjoerg intptr_t bcx = fr.interpreter_frame_bcx(); 160525944Sjoerg method = fr.interpreter_frame_method(); 160625944Sjoerg bci = fr.is_bci(bcx) ? bcx : method->bci_from((address)bcx); 160770199Sjhay fr = fr.sender(&map); 160870199Sjhay } else { 160970199Sjhay CodeBlob* cb = fr.cb(); 161070199Sjhay // HMMM QQQ might be nice to have frame return nm as NULL if cb is non-NULL 161170199Sjhay // but non nmethod 161270199Sjhay fr = fr.sender(&map); 161370199Sjhay if (cb == NULL || !cb->is_nmethod()) { 161425944Sjoerg continue; 161525944Sjoerg } 161625944Sjoerg nm = (nmethod*)cb; 161725944Sjoerg if (nm->method()->is_native()) { 1618102412Scharnier method = nm->method(); 161925944Sjoerg bci = 0; 162052633Sjoerg } else { 162125944Sjoerg PcDesc* pd = nm->pc_desc_at(pc); 162225944Sjoerg decode_offset = pd->scope_decode_offset(); 162325944Sjoerg // if decode_offset is not equal to 0, it will execute the 162425944Sjoerg // "compiled java method case" at the beginning of the loop. 162525944Sjoerg continue; 162625944Sjoerg } 162740008Sjoerg } 162840008Sjoerg } 162925944Sjoerg#ifdef ASSERT 163025944Sjoerg assert(st_method() == method && st.bci() == bci, 163125944Sjoerg "Wrong stack trace"); 163225944Sjoerg st.next(); 163325944Sjoerg // vframeStream::method isn't GC-safe so store off a copy 16344910Swollman // of the Method* in case we GC. 163525944Sjoerg if (!st.at_end()) { 163625944Sjoerg st_method = st.method(); 163725944Sjoerg } 163825944Sjoerg#endif 163925944Sjoerg 1640102412Scharnier // the format of the stacktrace will be: 164125944Sjoerg // - 1 or more fillInStackTrace frames for the exception class (skipped) 164225944Sjoerg // - 0 or more <init> methods for the exception class (skipped) 164325944Sjoerg // - rest of the stack 164425944Sjoerg 164525944Sjoerg if (!skip_fillInStackTrace_check) { 164625944Sjoerg if ((method->name() == vmSymbols::fillInStackTrace_name() || 164725944Sjoerg method->name() == vmSymbols::fillInStackTrace0_name()) && 164825944Sjoerg throwable->is_a(method->method_holder())) { 164940008Sjoerg continue; 165040008Sjoerg } 165125944Sjoerg else { 165225944Sjoerg skip_fillInStackTrace_check = true; // gone past them all 165325944Sjoerg } 165425944Sjoerg } 165525944Sjoerg if (!skip_throwableInit_check) { 165625944Sjoerg assert(skip_fillInStackTrace_check, "logic error in backtrace filtering"); 165725944Sjoerg 165825944Sjoerg // skip <init> methods of the exception class and superclasses 165925944Sjoerg // This is simlar to classic VM. 166040008Sjoerg if (method->name() == vmSymbols::object_initializer_name() && 166140008Sjoerg throwable->is_a(method->method_holder())) { 166225944Sjoerg continue; 166325944Sjoerg } else { 166425944Sjoerg // there are none or we've seen them all - either way stop checking 166525944Sjoerg skip_throwableInit_check = true; 166625944Sjoerg } 166725944Sjoerg } 166825944Sjoerg if (method->is_hidden()) { 166925944Sjoerg if (skip_hidden) continue; 167025944Sjoerg } 167125944Sjoerg bt.push(method, bci, CHECK); 167225944Sjoerg total_count++; 167325944Sjoerg } 167425944Sjoerg 167541881Sphk // Put completed stack trace into throwable object 167625944Sjoerg set_backtrace(throwable(), bt.backtrace()); 167725944Sjoerg} 167825944Sjoerg 167941881Sphkvoid java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) { 168025944Sjoerg // No-op if stack trace is disabled 168125944Sjoerg if (!StackTraceInThrowable) { 168225944Sjoerg return; 168325944Sjoerg } 168425944Sjoerg 168525944Sjoerg // Disable stack traces for some preallocated out of memory errors 168625944Sjoerg if (!Universe::should_fill_in_stack_trace(throwable)) { 168725944Sjoerg return; 168825944Sjoerg } 168925944Sjoerg 169025944Sjoerg PRESERVE_EXCEPTION_MARK; 169140008Sjoerg 169240008Sjoerg JavaThread* thread = JavaThread::active(); 169325944Sjoerg fill_in_stack_trace(throwable, method, thread); 169425944Sjoerg // ignore exceptions thrown during stack trace filling 169525944Sjoerg CLEAR_PENDING_EXCEPTION; 169625944Sjoerg} 169725944Sjoerg 169825944Sjoergvoid java_lang_Throwable::allocate_backtrace(Handle throwable, TRAPS) { 169925944Sjoerg // Allocate stack trace - backtrace is created but not filled in 170030300Sjoerg 170140008Sjoerg // No-op if stack trace is disabled 170230300Sjoerg if (!StackTraceInThrowable) return; 170340008Sjoerg BacktraceBuilder bt(CHECK); // creates a backtrace 170430300Sjoerg set_backtrace(throwable(), bt.backtrace()); 170525944Sjoerg} 170625944Sjoerg 170725944Sjoerg 170825944Sjoergvoid java_lang_Throwable::fill_in_stack_trace_of_preallocated_backtrace(Handle throwable) { 170925944Sjoerg // Fill in stack trace into preallocated backtrace (no GC) 171025944Sjoerg 171125944Sjoerg // No-op if stack trace is disabled 171225944Sjoerg if (!StackTraceInThrowable) return; 171325944Sjoerg 171425944Sjoerg assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check"); 171525944Sjoerg 171625944Sjoerg JavaThread* THREAD = JavaThread::current(); 171725944Sjoerg 171840008Sjoerg objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable())); 171940008Sjoerg assert(backtrace.not_null(), "backtrace should have been preallocated"); 172025944Sjoerg 172125944Sjoerg ResourceMark rm(THREAD); 172225944Sjoerg vframeStream st(THREAD); 172325944Sjoerg 172425944Sjoerg BacktraceBuilder bt(backtrace); 172580715Sume 172680715Sume // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init 172780715Sume // methods as preallocated errors aren't created by "java" code. 172880715Sume 172980715Sume // fill in as much stack trace as possible 173080715Sume typeArrayOop methods = BacktraceBuilder::get_methods(backtrace); 173180715Sume int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth); 173280715Sume int chunk_count = 0; 173380715Sume 173480715Sume for (;!st.at_end(); st.next()) { 173580715Sume bt.push(st.method(), st.bci(), CHECK); 173680715Sume chunk_count++; 173780715Sume 173880715Sume // Bail-out for deep stacks 173980715Sume if (chunk_count >= max_chunks) break; 174080715Sume } 174180715Sume 174280715Sume // For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support 174380715Sume // was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround 174488508Sjoerg // can be removed in a JDK using this JVM version 174588508Sjoerg if (JDK_Version::is_gte_jdk17x_version()) { 174688508Sjoerg java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); 174788508Sjoerg assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); 174888508Sjoerg } 174988508Sjoerg} 175088508Sjoerg 175180715Sume 175280715Sumeint java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) { 175380715Sume if (throwable == NULL) { 175480715Sume THROW_0(vmSymbols::java_lang_NullPointerException()); 175580715Sume } 175680715Sume objArrayOop chunk = objArrayOop(backtrace(throwable)); 175780715Sume int depth = 0; 175880715Sume if (chunk != NULL) { 175980715Sume // Iterate over chunks and count full ones 176080715Sume while (true) { 176180715Sume objArrayOop next = objArrayOop(chunk->obj_at(trace_next_offset)); 176280715Sume if (next == NULL) break; 176380715Sume depth += trace_chunk_size; 176480715Sume chunk = next; 176580715Sume } 176680715Sume assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check"); 176780715Sume // Count element in remaining partial chunk. NULL value for mirror 176880715Sume // marks the end of the stack trace elements that are saved. 176980715Sume objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); 177080715Sume assert(mirrors != NULL, "sanity check"); 177180715Sume for (int i = 0; i < mirrors->length(); i++) { 177280715Sume if (mirrors->obj_at(i) == NULL) break; 177380715Sume depth++; 177480715Sume } 177580715Sume } 177680715Sume return depth; 177780715Sume} 177880715Sume 177980715Sume 178080715Sumeoop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) { 178180715Sume if (throwable == NULL) { 178280715Sume THROW_0(vmSymbols::java_lang_NullPointerException()); 178380715Sume } 178480715Sume if (index < 0) { 178525944Sjoerg THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 178625944Sjoerg } 178725944Sjoerg // Compute how many chunks to skip and index into actual chunk 178825944Sjoerg objArrayOop chunk = objArrayOop(backtrace(throwable)); 178925944Sjoerg int skip_chunks = index / trace_chunk_size; 179025944Sjoerg int chunk_index = index % trace_chunk_size; 179125944Sjoerg while (chunk != NULL && skip_chunks > 0) { 179225944Sjoerg chunk = objArrayOop(chunk->obj_at(trace_next_offset)); 179325944Sjoerg skip_chunks--; 179425944Sjoerg } 179569211Sphk if (chunk == NULL) { 179640008Sjoerg THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 179725944Sjoerg } 179825944Sjoerg // Get method id, bci, version and mirror from chunk 179925944Sjoerg typeArrayOop methods = BacktraceBuilder::get_methods(chunk); 180025944Sjoerg typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); 180125944Sjoerg objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); 180269211Sphk 180325944Sjoerg assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); 180440008Sjoerg 180525944Sjoerg int method = methods->short_at(chunk_index); 180625944Sjoerg int version = version_at(bcis->int_at(chunk_index)); 180744145Sphk int bci = bci_at(bcis->int_at(chunk_index)); 180844145Sphk Handle mirror(THREAD, mirrors->obj_at(chunk_index)); 180925944Sjoerg 181040008Sjoerg // Chunk can be partial full 181170199Sjhay if (mirror.is_null()) { 181225944Sjoerg THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); 181326018Sjoerg } 18144910Swollman 181525944Sjoerg oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0); 181625944Sjoerg return element; 181725944Sjoerg} 181825944Sjoerg 181925944Sjoergoop java_lang_StackTraceElement::create(Handle mirror, int method_id, 182025944Sjoerg int version, int bci, TRAPS) { 182125944Sjoerg // Allocate java.lang.StackTraceElement instance 182225944Sjoerg Klass* k = SystemDictionary::StackTraceElement_klass(); 182369211Sphk assert(k != NULL, "must be loaded in 1.4+"); 182440008Sjoerg instanceKlassHandle ik (THREAD, k); 182525944Sjoerg if (ik->should_be_initialized()) { 182625944Sjoerg ik->initialize(CHECK_0); 182725944Sjoerg } 182825944Sjoerg 182925944Sjoerg Handle element = ik->allocate_instance_handle(CHECK_0); 183025944Sjoerg // Fill in class name 183125944Sjoerg ResourceMark rm(THREAD); 183225944Sjoerg InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); 183325944Sjoerg const char* str = holder->external_name(); 183425944Sjoerg oop classname = StringTable::intern((char*) str, CHECK_0); 183525944Sjoerg java_lang_StackTraceElement::set_declaringClass(element(), classname); 183669211Sphk 183725944Sjoerg Method* method = holder->method_with_idnum(method_id); 183840008Sjoerg // Method on stack may be obsolete because it was redefined so cannot be 183925944Sjoerg // found by idnum. 184025944Sjoerg if (method == NULL) { 184125944Sjoerg // leave name and fileName null 184269211Sphk java_lang_StackTraceElement::set_lineNumber(element(), -1); 184340008Sjoerg return element(); 184444145Sphk } 184544145Sphk 184625944Sjoerg // Fill in method name 184725944Sjoerg oop methodname = StringTable::intern(method->name(), CHECK_0); 184825944Sjoerg java_lang_StackTraceElement::set_methodName(element(), methodname); 184925944Sjoerg 185025944Sjoerg if (!version_matches(method, version)) { 185125944Sjoerg // The method was redefined, accurate line number information isn't available 185269211Sphk java_lang_StackTraceElement::set_fileName(element(), NULL); 185340008Sjoerg java_lang_StackTraceElement::set_lineNumber(element(), -1); 185478064Sume } else { 185578064Sume // Fill in source file name and line number. 185625944Sjoerg Symbol* source = holder->source_file_name(); 185725944Sjoerg if (ShowHiddenFrames && source == NULL) 18584910Swollman source = vmSymbols::unknown_class_name(); 18594910Swollman oop filename = StringTable::intern(source, CHECK_0); 186025944Sjoerg java_lang_StackTraceElement::set_fileName(element(), filename); 18614910Swollman 186225944Sjoerg int line_number = get_line_number(method, bci); 186325944Sjoerg java_lang_StackTraceElement::set_lineNumber(element(), line_number); 18644910Swollman } 186525944Sjoerg return element(); 186625944Sjoerg} 18674910Swollman 186825944Sjoergoop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { 18694910Swollman Handle mirror (THREAD, method->method_holder()->java_mirror()); 187025944Sjoerg int method_id = method->method_idnum(); 187140008Sjoerg return create(mirror, method_id, method->constants()->version(), bci, THREAD); 187240008Sjoerg} 187325944Sjoerg 187425944Sjoergvoid java_lang_reflect_AccessibleObject::compute_offsets() { 187525944Sjoerg Klass* k = SystemDictionary::reflect_AccessibleObject_klass(); 187625944Sjoerg compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature()); 187725944Sjoerg} 187825944Sjoerg 187925944Sjoergjboolean java_lang_reflect_AccessibleObject::override(oop reflect) { 188025944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 188125944Sjoerg return (jboolean) reflect->bool_field(override_offset); 188225944Sjoerg} 188325944Sjoerg 18844910Swollmanvoid java_lang_reflect_AccessibleObject::set_override(oop reflect, jboolean value) { 188540008Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 188640008Sjoerg reflect->bool_field_put(override_offset, (int) value); 188725944Sjoerg} 188825944Sjoerg 188925944Sjoergvoid java_lang_reflect_Method::compute_offsets() { 18904910Swollman Klass* k = SystemDictionary::reflect_Method_klass(); 189125944Sjoerg compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); 189225944Sjoerg compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); 189325944Sjoerg compute_offset(returnType_offset, k, vmSymbols::returnType_name(), vmSymbols::class_signature()); 189425944Sjoerg compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); 189525944Sjoerg compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); 189625944Sjoerg compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); 189740008Sjoerg compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); 189840008Sjoerg // The generic signature and annotations fields are only present in 1.5 189925944Sjoerg signature_offset = -1; 190025944Sjoerg annotations_offset = -1; 190125944Sjoerg parameter_annotations_offset = -1; 190225944Sjoerg annotation_default_offset = -1; 190325944Sjoerg type_annotations_offset = -1; 190425944Sjoerg compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); 19054910Swollman compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); 190625944Sjoerg compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); 190741881Sphk compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature()); 190825944Sjoerg compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); 190941881Sphk} 191025944Sjoerg 191125944SjoergHandle java_lang_reflect_Method::create(TRAPS) { 191225944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 191325944Sjoerg Klass* klass = SystemDictionary::reflect_Method_klass(); 191425944Sjoerg // This class is eagerly initialized during VM initialization, since we keep a refence 191525944Sjoerg // to one of the methods 191625944Sjoerg assert(InstanceKlass::cast(klass)->is_initialized(), "must be initialized"); 191725944Sjoerg return InstanceKlass::cast(klass)->allocate_instance_handle(CHECK_NH); 191825944Sjoerg} 191925944Sjoerg 192025944Sjoergoop java_lang_reflect_Method::clazz(oop reflect) { 192140008Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 192240008Sjoerg return reflect->obj_field(clazz_offset); 192325944Sjoerg} 192425944Sjoerg 192525944Sjoergvoid java_lang_reflect_Method::set_clazz(oop reflect, oop value) { 19264910Swollman assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 192711189Sjkh reflect->obj_field_put(clazz_offset, value); 192825944Sjoerg} 192925944Sjoerg 193025944Sjoergint java_lang_reflect_Method::slot(oop reflect) { 193125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 193225944Sjoerg return reflect->int_field(slot_offset); 193325944Sjoerg} 193440008Sjoerg 193540008Sjoergvoid java_lang_reflect_Method::set_slot(oop reflect, int value) { 193625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 193725944Sjoerg reflect->int_field_put(slot_offset, value); 193825944Sjoerg} 193925944Sjoerg 194041881Sphkoop java_lang_reflect_Method::name(oop method) { 194125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 19424910Swollman return method->obj_field(name_offset); 194325944Sjoerg} 194425944Sjoerg 194525944Sjoergvoid java_lang_reflect_Method::set_name(oop method, oop value) { 194625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 194725944Sjoerg method->obj_field_put(name_offset, value); 194825944Sjoerg} 194925944Sjoerg 195025944Sjoergoop java_lang_reflect_Method::return_type(oop method) { 195174703Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 195274703Sjoerg return method->obj_field(returnType_offset); 195374703Sjoerg} 195474703Sjoerg 195574703Sjoergvoid java_lang_reflect_Method::set_return_type(oop method, oop value) { 195674703Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 195774703Sjoerg method->obj_field_put(returnType_offset, value); 195874703Sjoerg} 195974703Sjoerg 196074703Sjoergoop java_lang_reflect_Method::parameter_types(oop method) { 196174703Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 196274703Sjoerg return method->obj_field(parameterTypes_offset); 196374703Sjoerg} 196474703Sjoerg 196525944Sjoergvoid java_lang_reflect_Method::set_parameter_types(oop method, oop value) { 196625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 196725944Sjoerg method->obj_field_put(parameterTypes_offset, value); 196825944Sjoerg} 196925944Sjoerg 197025944Sjoergoop java_lang_reflect_Method::exception_types(oop method) { 197125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 197225944Sjoerg return method->obj_field(exceptionTypes_offset); 197325944Sjoerg} 197425944Sjoerg 197525944Sjoergvoid java_lang_reflect_Method::set_exception_types(oop method, oop value) { 19764910Swollman assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 197725944Sjoerg method->obj_field_put(exceptionTypes_offset, value); 197825944Sjoerg} 197925944Sjoerg 198025944Sjoergint java_lang_reflect_Method::modifiers(oop method) { 198125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 198225944Sjoerg return method->int_field(modifiers_offset); 198325944Sjoerg} 198440008Sjoerg 198540008Sjoergvoid java_lang_reflect_Method::set_modifiers(oop method, int value) { 198625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 198725944Sjoerg method->int_field_put(modifiers_offset, value); 198825944Sjoerg} 198925944Sjoerg 199025944Sjoergbool java_lang_reflect_Method::has_signature_field() { 199125944Sjoerg return (signature_offset >= 0); 19924910Swollman} 199325944Sjoerg 199441881Sphkoop java_lang_reflect_Method::signature(oop method) { 199525944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 19964910Swollman assert(has_signature_field(), "signature field must be present"); 199725944Sjoerg return method->obj_field(signature_offset); 199825944Sjoerg} 19994910Swollman 200025944Sjoergvoid java_lang_reflect_Method::set_signature(oop method, oop value) { 200125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 20024910Swollman assert(has_signature_field(), "signature field must be present"); 200325944Sjoerg method->obj_field_put(signature_offset, value); 200425944Sjoerg} 2005102412Scharnier 200625944Sjoergbool java_lang_reflect_Method::has_annotations_field() { 200725944Sjoerg return (annotations_offset >= 0); 200825944Sjoerg} 200925944Sjoerg 201078064Sumeoop java_lang_reflect_Method::annotations(oop method) { 201178064Sume assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 201225944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 20134910Swollman return method->obj_field(annotations_offset); 20144910Swollman} 20154910Swollman 20164910Swollmanvoid java_lang_reflect_Method::set_annotations(oop method, oop value) { 201725944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 201825944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 201925944Sjoerg method->obj_field_put(annotations_offset, value); 202025944Sjoerg} 202125944Sjoerg 202225944Sjoergbool java_lang_reflect_Method::has_parameter_annotations_field() { 202325944Sjoerg return (parameter_annotations_offset >= 0); 202425944Sjoerg} 202540008Sjoerg 202640008Sjoergoop java_lang_reflect_Method::parameter_annotations(oop method) { 202725944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 202825944Sjoerg assert(has_parameter_annotations_field(), "parameter annotations field must be present"); 202925944Sjoerg return method->obj_field(parameter_annotations_offset); 203025944Sjoerg} 203125944Sjoerg 203225944Sjoergvoid java_lang_reflect_Method::set_parameter_annotations(oop method, oop value) { 203325944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 203441881Sphk assert(has_parameter_annotations_field(), "parameter annotations field must be present"); 203525944Sjoerg method->obj_field_put(parameter_annotations_offset, value); 203625944Sjoerg} 203725944Sjoerg 203841881Sphkbool java_lang_reflect_Method::has_annotation_default_field() { 203925944Sjoerg return (annotation_default_offset >= 0); 204025944Sjoerg} 204125944Sjoerg 204225944Sjoergoop java_lang_reflect_Method::annotation_default(oop method) { 204325944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 204441881Sphk assert(has_annotation_default_field(), "annotation default field must be present"); 204525944Sjoerg return method->obj_field(annotation_default_offset); 204625944Sjoerg} 204725944Sjoerg 204825944Sjoergvoid java_lang_reflect_Method::set_annotation_default(oop method, oop value) { 204925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 205025944Sjoerg assert(has_annotation_default_field(), "annotation default field must be present"); 205125944Sjoerg method->obj_field_put(annotation_default_offset, value); 205225944Sjoerg} 205378064Sume 205478064Sumebool java_lang_reflect_Method::has_type_annotations_field() { 205570199Sjhay return (type_annotations_offset >= 0); 205642064Sphk} 205725944Sjoerg 205825944Sjoergoop java_lang_reflect_Method::type_annotations(oop method) { 205925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 206025944Sjoerg assert(has_type_annotations_field(), "type_annotations field must be present"); 206125944Sjoerg return method->obj_field(type_annotations_offset); 206225944Sjoerg} 206325944Sjoerg 206425944Sjoergvoid java_lang_reflect_Method::set_type_annotations(oop method, oop value) { 206525944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 206642064Sphk assert(has_type_annotations_field(), "type_annotations field must be present"); 206742064Sphk method->obj_field_put(type_annotations_offset, value); 206825944Sjoerg} 206925944Sjoerg 207025944Sjoergvoid java_lang_reflect_Constructor::compute_offsets() { 207125944Sjoerg Klass* k = SystemDictionary::reflect_Constructor_klass(); 207225944Sjoerg compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); 207325944Sjoerg compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature()); 207411189Sjkh compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature()); 207525944Sjoerg compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); 207625944Sjoerg compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); 207711189Sjkh // The generic signature and annotations fields are only present in 1.5 207825944Sjoerg signature_offset = -1; 207925944Sjoerg annotations_offset = -1; 208025944Sjoerg parameter_annotations_offset = -1; 208125944Sjoerg type_annotations_offset = -1; 208225944Sjoerg compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); 208340008Sjoerg compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); 208425944Sjoerg compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); 208525944Sjoerg compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); 208625944Sjoerg} 208725944Sjoerg 208825944SjoergHandle java_lang_reflect_Constructor::create(TRAPS) { 208925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 209025944Sjoerg Symbol* name = vmSymbols::java_lang_reflect_Constructor(); 209125944Sjoerg Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); 209225944Sjoerg instanceKlassHandle klass (THREAD, k); 209325944Sjoerg // Ensure it is initialized 209425944Sjoerg klass->initialize(CHECK_NH); 209525944Sjoerg return klass->allocate_instance_handle(CHECK_NH); 209670199Sjhay} 209742064Sphk 209825944Sjoergoop java_lang_reflect_Constructor::clazz(oop reflect) { 209925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 210025944Sjoerg return reflect->obj_field(clazz_offset); 210170199Sjhay} 210270199Sjhay 210325944Sjoergvoid java_lang_reflect_Constructor::set_clazz(oop reflect, oop value) { 210425944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 210525944Sjoerg reflect->obj_field_put(clazz_offset, value); 210625944Sjoerg} 210725944Sjoerg 210825944Sjoergoop java_lang_reflect_Constructor::parameter_types(oop constructor) { 210925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 211025944Sjoerg return constructor->obj_field(parameterTypes_offset); 211125944Sjoerg} 211225944Sjoerg 211325944Sjoergvoid java_lang_reflect_Constructor::set_parameter_types(oop constructor, oop value) { 211425944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 211525944Sjoerg constructor->obj_field_put(parameterTypes_offset, value); 211678064Sume} 211778064Sume 211825944Sjoergoop java_lang_reflect_Constructor::exception_types(oop constructor) { 211925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 212030300Sjoerg return constructor->obj_field(exceptionTypes_offset); 212144145Sphk} 212244145Sphk 212325944Sjoergvoid java_lang_reflect_Constructor::set_exception_types(oop constructor, oop value) { 212425944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 212525944Sjoerg constructor->obj_field_put(exceptionTypes_offset, value); 212642065Sphk} 212730300Sjoerg 212840008Sjoergint java_lang_reflect_Constructor::slot(oop reflect) { 212925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 213025944Sjoerg return reflect->int_field(slot_offset); 213125944Sjoerg} 213225944Sjoerg 213325944Sjoergvoid java_lang_reflect_Constructor::set_slot(oop reflect, int value) { 213425944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 213525944Sjoerg reflect->int_field_put(slot_offset, value); 213670199Sjhay} 213770199Sjhay 213870199Sjhayint java_lang_reflect_Constructor::modifiers(oop constructor) { 213970199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 214070199Sjhay return constructor->int_field(modifiers_offset); 214125944Sjoerg} 214275321Sjoerg 214375321Sjoergvoid java_lang_reflect_Constructor::set_modifiers(oop constructor, int value) { 214475321Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 214575321Sjoerg constructor->int_field_put(modifiers_offset, value); 214675321Sjoerg} 214775321Sjoerg 214875321Sjoergbool java_lang_reflect_Constructor::has_signature_field() { 214975321Sjoerg return (signature_offset >= 0); 215030300Sjoerg} 215130300Sjoerg 215230300Sjoergoop java_lang_reflect_Constructor::signature(oop constructor) { 215325944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 215425944Sjoerg assert(has_signature_field(), "signature field must be present"); 215525944Sjoerg return constructor->obj_field(signature_offset); 215625944Sjoerg} 215740008Sjoerg 215825944Sjoergvoid java_lang_reflect_Constructor::set_signature(oop constructor, oop value) { 215930300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 216030300Sjoerg assert(has_signature_field(), "signature field must be present"); 216169211Sphk constructor->obj_field_put(signature_offset, value); 216230300Sjoerg} 216330300Sjoerg 216430300Sjoergbool java_lang_reflect_Constructor::has_annotations_field() { 216569211Sphk return (annotations_offset >= 0); 216688710Sjoerg} 216788710Sjoerg 216888710Sjoergoop java_lang_reflect_Constructor::annotations(oop constructor) { 216988710Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 217025944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 217125944Sjoerg return constructor->obj_field(annotations_offset); 217225944Sjoerg} 217325944Sjoerg 217425944Sjoergvoid java_lang_reflect_Constructor::set_annotations(oop constructor, oop value) { 217525944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 217625944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 217725944Sjoerg constructor->obj_field_put(annotations_offset, value); 217825944Sjoerg} 217925944Sjoerg 218025944Sjoergbool java_lang_reflect_Constructor::has_parameter_annotations_field() { 218125944Sjoerg return (parameter_annotations_offset >= 0); 218225944Sjoerg} 218325944Sjoerg 218425944Sjoergoop java_lang_reflect_Constructor::parameter_annotations(oop method) { 218525944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 218625944Sjoerg assert(has_parameter_annotations_field(), "parameter annotations field must be present"); 218725944Sjoerg return method->obj_field(parameter_annotations_offset); 218825944Sjoerg} 218925944Sjoerg 219025944Sjoergvoid java_lang_reflect_Constructor::set_parameter_annotations(oop method, oop value) { 219142066Sphk assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 219240008Sjoerg assert(has_parameter_annotations_field(), "parameter annotations field must be present"); 219325944Sjoerg method->obj_field_put(parameter_annotations_offset, value); 219425944Sjoerg} 219525944Sjoerg 219625944Sjoergbool java_lang_reflect_Constructor::has_type_annotations_field() { 219740008Sjoerg return (type_annotations_offset >= 0); 219840008Sjoerg} 219970199Sjhay 220070199Sjhayoop java_lang_reflect_Constructor::type_annotations(oop constructor) { 220170199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 220270199Sjhay assert(has_type_annotations_field(), "type_annotations field must be present"); 220325944Sjoerg return constructor->obj_field(type_annotations_offset); 220425944Sjoerg} 220525944Sjoerg 220625944Sjoergvoid java_lang_reflect_Constructor::set_type_annotations(oop constructor, oop value) { 220725944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 220825944Sjoerg assert(has_type_annotations_field(), "type_annotations field must be present"); 220925944Sjoerg constructor->obj_field_put(type_annotations_offset, value); 221025944Sjoerg} 221125944Sjoerg 221225944Sjoergvoid java_lang_reflect_Field::compute_offsets() { 221325944Sjoerg Klass* k = SystemDictionary::reflect_Field_klass(); 221425944Sjoerg compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); 221525944Sjoerg compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); 221625944Sjoerg compute_offset(type_offset, k, vmSymbols::type_name(), vmSymbols::class_signature()); 221725944Sjoerg compute_offset(slot_offset, k, vmSymbols::slot_name(), vmSymbols::int_signature()); 221825944Sjoerg compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); 221925944Sjoerg // The generic signature and annotations fields are only present in 1.5 222025944Sjoerg signature_offset = -1; 222125944Sjoerg annotations_offset = -1; 222225944Sjoerg type_annotations_offset = -1; 222325944Sjoerg compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); 222425944Sjoerg compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); 222525944Sjoerg compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); 222625944Sjoerg} 222725944Sjoerg 222825944SjoergHandle java_lang_reflect_Field::create(TRAPS) { 222925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 223012820Sphk Symbol* name = vmSymbols::java_lang_reflect_Field(); 223125944Sjoerg Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); 22324910Swollman instanceKlassHandle klass (THREAD, k); 223325944Sjoerg // Ensure it is initialized 223411189Sjkh klass->initialize(CHECK_NH); 223525944Sjoerg return klass->allocate_instance_handle(CHECK_NH); 223625944Sjoerg} 223730300Sjoerg 22384910Swollmanoop java_lang_reflect_Field::clazz(oop reflect) { 223911189Sjkh assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 224025944Sjoerg return reflect->obj_field(clazz_offset); 224111189Sjkh} 224211189Sjkh 224311189Sjkhvoid java_lang_reflect_Field::set_clazz(oop reflect, oop value) { 22444910Swollman assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 224525706Sjoerg reflect->obj_field_put(clazz_offset, value); 224640008Sjoerg} 224740008Sjoerg 224825706Sjoergoop java_lang_reflect_Field::name(oop field) { 224925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 225011189Sjkh return field->obj_field(name_offset); 225111189Sjkh} 225225944Sjoerg 225369211Sphkvoid java_lang_reflect_Field::set_name(oop field, oop value) { 225411189Sjkh assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 225511189Sjkh field->obj_field_put(name_offset, value); 225625944Sjoerg} 225770199Sjhay 225870199Sjhayoop java_lang_reflect_Field::type(oop field) { 225970199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 226070199Sjhay return field->obj_field(type_offset); 226170199Sjhay} 226225944Sjoerg 226325944Sjoergvoid java_lang_reflect_Field::set_type(oop field, oop value) { 226470199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 226525944Sjoerg field->obj_field_put(type_offset, value); 226625944Sjoerg} 226769211Sphk 226825944Sjoergint java_lang_reflect_Field::slot(oop reflect) { 226925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 227025944Sjoerg return reflect->int_field(slot_offset); 227125944Sjoerg} 227225944Sjoerg 227325944Sjoergvoid java_lang_reflect_Field::set_slot(oop reflect, int value) { 227469211Sphk assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 227525944Sjoerg reflect->int_field_put(slot_offset, value); 227630300Sjoerg} 227730300Sjoerg 227830300Sjoergint java_lang_reflect_Field::modifiers(oop field) { 227969211Sphk assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 228030300Sjoerg return field->int_field(modifiers_offset); 228130300Sjoerg} 228230300Sjoerg 228330300Sjoergvoid java_lang_reflect_Field::set_modifiers(oop field, int value) { 228430300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 228569211Sphk field->int_field_put(modifiers_offset, value); 228630300Sjoerg} 228730300Sjoerg 228830300Sjoergbool java_lang_reflect_Field::has_signature_field() { 228930300Sjoerg return (signature_offset >= 0); 229030300Sjoerg} 229169211Sphk 229230300Sjoergoop java_lang_reflect_Field::signature(oop field) { 229330300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 229430300Sjoerg assert(has_signature_field(), "signature field must be present"); 229530300Sjoerg return field->obj_field(signature_offset); 229630300Sjoerg} 229730300Sjoerg 229830300Sjoergvoid java_lang_reflect_Field::set_signature(oop field, oop value) { 229930300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 230030300Sjoerg assert(has_signature_field(), "signature field must be present"); 230125944Sjoerg field->obj_field_put(signature_offset, value); 230225944Sjoerg} 230325944Sjoerg 230469211Sphkbool java_lang_reflect_Field::has_annotations_field() { 230525944Sjoerg return (annotations_offset >= 0); 230625944Sjoerg} 230725944Sjoerg 230825944Sjoergoop java_lang_reflect_Field::annotations(oop field) { 230925944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 231025944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 231125944Sjoerg return field->obj_field(annotations_offset); 231225944Sjoerg} 231325944Sjoerg 231469211Sphkvoid java_lang_reflect_Field::set_annotations(oop field, oop value) { 231525944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 231625944Sjoerg assert(has_annotations_field(), "annotations field must be present"); 231725944Sjoerg field->obj_field_put(annotations_offset, value); 231869211Sphk} 231925944Sjoerg 232025944Sjoergbool java_lang_reflect_Field::has_type_annotations_field() { 232125944Sjoerg return (type_annotations_offset >= 0); 232225944Sjoerg} 232325944Sjoerg 232425944Sjoergoop java_lang_reflect_Field::type_annotations(oop field) { 232540008Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 232640008Sjoerg assert(has_type_annotations_field(), "type_annotations field must be present"); 232725944Sjoerg return field->obj_field(type_annotations_offset); 232825944Sjoerg} 232925944Sjoerg 233025944Sjoergvoid java_lang_reflect_Field::set_type_annotations(oop field, oop value) { 233125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 233269211Sphk assert(has_type_annotations_field(), "type_annotations field must be present"); 233325944Sjoerg field->obj_field_put(type_annotations_offset, value); 233425944Sjoerg} 233511189Sjkh 233625944Sjoergvoid sun_reflect_ConstantPool::compute_offsets() { 233725944Sjoerg Klass* k = SystemDictionary::reflect_ConstantPool_klass(); 233825944Sjoerg // This null test can be removed post beta 233970199Sjhay if (k != NULL) { 234025706Sjoerg // The field is called ConstantPool* in the sun.reflect.ConstantPool class. 234169211Sphk compute_offset(_oop_offset, k, vmSymbols::ConstantPool_name(), vmSymbols::object_signature()); 234211189Sjkh } 234311189Sjkh} 234470199Sjhay 234569211Sphkvoid java_lang_reflect_Parameter::compute_offsets() { 234625944Sjoerg Klass* k = SystemDictionary::reflect_Parameter_klass(); 234725944Sjoerg if(NULL != k) { 234825944Sjoerg compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); 234925944Sjoerg compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); 235025944Sjoerg compute_offset(index_offset, k, vmSymbols::index_name(), vmSymbols::int_signature()); 235125944Sjoerg compute_offset(executable_offset, k, vmSymbols::executable_name(), vmSymbols::executable_signature()); 235225944Sjoerg } 235325944Sjoerg} 235425944Sjoerg 235525944SjoergHandle java_lang_reflect_Parameter::create(TRAPS) { 235625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 235725944Sjoerg Symbol* name = vmSymbols::java_lang_reflect_Parameter(); 235811189Sjkh Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); 235925944Sjoerg instanceKlassHandle klass (THREAD, k); 236011189Sjkh // Ensure it is initialized 236188506Sjoerg klass->initialize(CHECK_NH); 236288506Sjoerg return klass->allocate_instance_handle(CHECK_NH); 236388506Sjoerg} 236488506Sjoerg 236588506Sjoergoop java_lang_reflect_Parameter::name(oop param) { 236688506Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 236788506Sjoerg return param->obj_field(name_offset); 236888506Sjoerg} 236988506Sjoerg 237088506Sjoergvoid java_lang_reflect_Parameter::set_name(oop param, oop value) { 237188506Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 237288506Sjoerg param->obj_field_put(name_offset, value); 237388506Sjoerg} 237488506Sjoerg 237588506Sjoergint java_lang_reflect_Parameter::modifiers(oop param) { 237625944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 237711189Sjkh return param->int_field(modifiers_offset); 237825944Sjoerg} 237925944Sjoerg 238025944Sjoergvoid java_lang_reflect_Parameter::set_modifiers(oop param, int value) { 238125944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 238225944Sjoerg param->int_field_put(modifiers_offset, value); 238325706Sjoerg} 238469211Sphk 238511189Sjkhint java_lang_reflect_Parameter::index(oop param) { 238630300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 238730300Sjoerg return param->int_field(index_offset); 238830300Sjoerg} 238930300Sjoerg 239030300Sjoergvoid java_lang_reflect_Parameter::set_index(oop param, int value) { 239130300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 239269211Sphk param->int_field_put(index_offset, value); 239330300Sjoerg} 239430300Sjoerg 239530300Sjoergoop java_lang_reflect_Parameter::executable(oop param) { 239630300Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 239730300Sjoerg return param->obj_field(executable_offset); 239830300Sjoerg} 239930300Sjoerg 240030300Sjoergvoid java_lang_reflect_Parameter::set_executable(oop param, oop value) { 240169211Sphk assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 240239981Sjoerg param->obj_field_put(executable_offset, value); 240330300Sjoerg} 240430300Sjoerg 240530300Sjoerg 240611189SjkhHandle sun_reflect_ConstantPool::create(TRAPS) { 240725944Sjoerg assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 240825706Sjoerg Klass* k = SystemDictionary::reflect_ConstantPool_klass(); 240925706Sjoerg instanceKlassHandle klass (THREAD, k); 241011189Sjkh // Ensure it is initialized 241112436Speter klass->initialize(CHECK_NH); 241225706Sjoerg return klass->allocate_instance_handle(CHECK_NH); 241370199Sjhay} 241470199Sjhay 241570199Sjhay 241670199Sjhayvoid sun_reflect_ConstantPool::set_cp(oop reflect, ConstantPool* value) { 241770199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 241870199Sjhay oop mirror = value->pool_holder()->java_mirror(); 241970199Sjhay // Save the mirror to get back the constant pool. 242070199Sjhay reflect->obj_field_put(_oop_offset, mirror); 242170199Sjhay} 242270199Sjhay 242370199SjhayConstantPool* sun_reflect_ConstantPool::get_cp(oop reflect) { 242470199Sjhay assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); 242570199Sjhay 242670199Sjhay oop mirror = reflect->obj_field(_oop_offset); 242770199Sjhay Klass* k = java_lang_Class::as_Klass(mirror); 242828036Sjoerg assert(k->oop_is_instance(), "Must be"); 242969211Sphk 243028036Sjoerg // Get the constant pool back from the klass. Since class redefinition 243128036Sjoerg // merges the new constant pool into the old, this is essentially the 243228036Sjoerg // same constant pool as the original. If constant pool merging is 243328036Sjoerg // no longer done in the future, this will have to change to save 243428036Sjoerg // the original. 243569211Sphk return InstanceKlass::cast(k)->constants(); 243628036Sjoerg} 243728036Sjoerg 243825944Sjoergvoid sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets() { 243925944Sjoerg Klass* k = SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(); 244069211Sphk // This null test can be removed post beta 244128036Sjoerg if (k != NULL) { 244225944Sjoerg compute_offset(_base_offset, k, 244325944Sjoerg vmSymbols::base_name(), vmSymbols::object_signature()); 244425944Sjoerg } 244525944Sjoerg} 244625944Sjoerg 244711189Sjkhoop java_lang_boxing_object::initialize_and_allocate(BasicType type, TRAPS) { 244811189Sjkh Klass* k = SystemDictionary::box_klass(type); 24494910Swollman if (k == NULL) return NULL; 24504910Swollman instanceKlassHandle h (THREAD, k); 245125944Sjoerg if (!h->is_initialized()) h->initialize(CHECK_0); 245225944Sjoerg return h->allocate_instance(THREAD); 245325944Sjoerg} 245425944Sjoerg 245512820Sphk 245625944Sjoergoop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) { 24574910Swollman oop box = initialize_and_allocate(type, CHECK_0); 245825944Sjoerg if (box == NULL) return NULL; 245925944Sjoerg switch (type) { 24604910Swollman case T_BOOLEAN: 246125944Sjoerg box->bool_field_put(value_offset, value->z); 246225944Sjoerg break; 246325944Sjoerg case T_CHAR: 24644910Swollman box->char_field_put(value_offset, value->c); 246525944Sjoerg break; 246625944Sjoerg case T_FLOAT: 246740008Sjoerg box->float_field_put(value_offset, value->f); 246840008Sjoerg break; 246925944Sjoerg case T_DOUBLE: 247025944Sjoerg box->double_field_put(long_value_offset, value->d); 247125944Sjoerg break; 247225944Sjoerg case T_BYTE: 247369211Sphk box->byte_field_put(value_offset, value->b); 247425944Sjoerg break; 247525944Sjoerg case T_SHORT: 247625944Sjoerg box->short_field_put(value_offset, value->s); 247725944Sjoerg break; 247825944Sjoerg case T_INT: 247925944Sjoerg box->int_field_put(value_offset, value->i); 248025944Sjoerg break; 248125944Sjoerg case T_LONG: 248225944Sjoerg box->long_field_put(long_value_offset, value->j); 248325944Sjoerg break; 248425944Sjoerg default: 248525944Sjoerg return NULL; 248625944Sjoerg } 248725944Sjoerg return box; 248830300Sjoerg} 248930300Sjoerg 249030300Sjoerg 249130300SjoergBasicType java_lang_boxing_object::basic_type(oop box) { 249230300Sjoerg if (box == NULL) return T_ILLEGAL; 249330300Sjoerg BasicType type = SystemDictionary::box_klass_type(box->klass()); 249430300Sjoerg if (type == T_OBJECT) // 'unknown' value returned by SD::bkt 249530300Sjoerg return T_ILLEGAL; 249630300Sjoerg return type; 249769211Sphk} 249830300Sjoerg 249930300Sjoerg 250030300SjoergBasicType java_lang_boxing_object::get_value(oop box, jvalue* value) { 250130300Sjoerg BasicType type = SystemDictionary::box_klass_type(box->klass()); 250230300Sjoerg switch (type) { 250369211Sphk case T_BOOLEAN: 250430300Sjoerg value->z = box->bool_field(value_offset); 250530300Sjoerg break; 250625944Sjoerg case T_CHAR: 25074910Swollman value->c = box->char_field(value_offset); 250825944Sjoerg break; 250969211Sphk case T_FLOAT: 251025944Sjoerg value->f = box->float_field(value_offset); 251125944Sjoerg break; 251225944Sjoerg case T_DOUBLE: 251325944Sjoerg value->d = box->double_field(long_value_offset); 251425944Sjoerg break; 251525944Sjoerg case T_BYTE: 251625944Sjoerg value->b = box->byte_field(value_offset); 251725944Sjoerg break; 251825944Sjoerg case T_SHORT: 251925944Sjoerg value->s = box->short_field(value_offset); 252025944Sjoerg break; 252125944Sjoerg case T_INT: 252225944Sjoerg value->i = box->int_field(value_offset); 252325944Sjoerg break; 252425944Sjoerg case T_LONG: 252525944Sjoerg value->j = box->long_field(long_value_offset); 252625944Sjoerg break; 252725944Sjoerg default: 252825944Sjoerg return T_ILLEGAL; 252925944Sjoerg } // end switch 253025944Sjoerg return type; 253140008Sjoerg} 253240008Sjoerg 253325944Sjoerg 253425944SjoergBasicType java_lang_boxing_object::set_value(oop box, jvalue* value) { 253525944Sjoerg BasicType type = SystemDictionary::box_klass_type(box->klass()); 253625706Sjoerg switch (type) { 253769211Sphk case T_BOOLEAN: 253825944Sjoerg box->bool_field_put(value_offset, value->z); 253925944Sjoerg break; 254025944Sjoerg case T_CHAR: 254125944Sjoerg box->char_field_put(value_offset, value->c); 254225944Sjoerg break; 254325944Sjoerg case T_FLOAT: 254425944Sjoerg box->float_field_put(value_offset, value->f); 254525944Sjoerg break; 254625944Sjoerg case T_DOUBLE: 254725944Sjoerg box->double_field_put(long_value_offset, value->d); 254825944Sjoerg break; 254925944Sjoerg case T_BYTE: 255025944Sjoerg box->byte_field_put(value_offset, value->b); 255125944Sjoerg break; 255269211Sphk case T_SHORT: 255342065Sphk box->short_field_put(value_offset, value->s); 255435064Sphk break; 255540008Sjoerg case T_INT: 255640008Sjoerg box->int_field_put(value_offset, value->i); 255740008Sjoerg break; 255825944Sjoerg case T_LONG: 255925944Sjoerg box->long_field_put(long_value_offset, value->j); 256025944Sjoerg break; 256169211Sphk default: 256225944Sjoerg return T_ILLEGAL; 256325944Sjoerg } // end switch 256425944Sjoerg return type; 256525944Sjoerg} 256625944Sjoerg 256725944Sjoerg 256825944Sjoergvoid java_lang_boxing_object::print(BasicType type, jvalue* value, outputStream* st) { 256925944Sjoerg switch (type) { 257025944Sjoerg case T_BOOLEAN: st->print("%s", value->z ? "true" : "false"); break; 257125944Sjoerg case T_CHAR: st->print("%d", value->c); break; 257225944Sjoerg case T_BYTE: st->print("%d", value->b); break; 257325944Sjoerg case T_SHORT: st->print("%d", value->s); break; 257469211Sphk case T_INT: st->print("%d", value->i); break; 257525944Sjoerg case T_LONG: st->print(INT64_FORMAT, value->j); break; 257625944Sjoerg case T_FLOAT: st->print("%f", value->f); break; 257725944Sjoerg case T_DOUBLE: st->print("%lf", value->d); break; 257825944Sjoerg default: st->print("type %d?", type); break; 257925944Sjoerg } 258025944Sjoerg} 258130300Sjoerg 258230300Sjoerg 258330300Sjoerg// Support for java_lang_ref_Reference 258430300SjoergHeapWord *java_lang_ref_Reference::pending_list_lock_addr() { 258530300Sjoerg InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass()); 258630300Sjoerg address addr = ik->static_field_addr(static_lock_offset); 258769211Sphk return (HeapWord*) addr; 258830300Sjoerg} 258930300Sjoerg 25904910Swollmanoop java_lang_ref_Reference::pending_list_lock() { 259125944Sjoerg InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass()); 259225944Sjoerg address addr = ik->static_field_addr(static_lock_offset); 259369211Sphk if (UseCompressedOops) { 259425944Sjoerg return oopDesc::load_decode_heap_oop((narrowOop *)addr); 259525944Sjoerg } else { 259625944Sjoerg return oopDesc::load_decode_heap_oop((oop*)addr); 259711189Sjkh } 259825944Sjoerg} 259925944Sjoerg 260025944SjoergHeapWord *java_lang_ref_Reference::pending_list_addr() { 260142066Sphk InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::Reference_klass()); 260225944Sjoerg address addr = ik->static_field_addr(static_pending_offset); 260325944Sjoerg // XXX This might not be HeapWord aligned, almost rather be char *. 260425944Sjoerg return (HeapWord*)addr; 260525944Sjoerg} 260625944Sjoerg 260725944Sjoergoop java_lang_ref_Reference::pending_list() { 260825944Sjoerg char *addr = (char *)pending_list_addr(); 260925944Sjoerg if (UseCompressedOops) { 261040008Sjoerg return oopDesc::load_decode_heap_oop((narrowOop *)addr); 261125944Sjoerg } else { 261225944Sjoerg return oopDesc::load_decode_heap_oop((oop*)addr); 261325944Sjoerg } 261425944Sjoerg} 261525944Sjoerg 261625944Sjoerg 261730300Sjoerg// Support for java_lang_ref_SoftReference 261830300Sjoerg 261925944Sjoergjlong java_lang_ref_SoftReference::timestamp(oop ref) { 262025944Sjoerg return ref->long_field(timestamp_offset); 262125944Sjoerg} 262225944Sjoerg 262342066Sphkjlong java_lang_ref_SoftReference::clock() { 262442066Sphk InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass()); 262542066Sphk jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); 262625944Sjoerg return *offset; 262730300Sjoerg} 262830300Sjoerg 262930300Sjoergvoid java_lang_ref_SoftReference::set_clock(jlong value) { 263030300Sjoerg InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::SoftReference_klass()); 263130300Sjoerg jlong* offset = (jlong*)ik->static_field_addr(static_clock_offset); 263230300Sjoerg *offset = value; 263330300Sjoerg} 263430300Sjoerg 263530300Sjoerg// Support for java_lang_invoke_DirectMethodHandle 263630300Sjoerg 263730300Sjoergint java_lang_invoke_DirectMethodHandle::_member_offset; 263830300Sjoerg 263925944Sjoergoop java_lang_invoke_DirectMethodHandle::member(oop dmh) { 264025944Sjoerg oop member_name = NULL; 264188723Sjoerg bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh); 264288723Sjoerg assert(is_dmh, "a DirectMethodHandle oop is expected"); 264388723Sjoerg if (is_dmh) { 264488723Sjoerg member_name = dmh->obj_field(member_offset_in_bytes()); 264588723Sjoerg } 264688723Sjoerg return member_name; 264788723Sjoerg} 264888723Sjoerg 264988723Sjoergvoid java_lang_invoke_DirectMethodHandle::compute_offsets() { 265088723Sjoerg Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass(); 265125944Sjoerg if (klass_oop != NULL) { 265225944Sjoerg compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature()); 265325944Sjoerg } 265425944Sjoerg} 265525944Sjoerg 265688706Sjoerg// Support for java_lang_invoke_MethodHandle 265725944Sjoerg 265825944Sjoergint java_lang_invoke_MethodHandle::_type_offset; 265942104Sphkint java_lang_invoke_MethodHandle::_form_offset; 266042104Sphk 266142104Sphkint java_lang_invoke_MemberName::_clazz_offset; 266242104Sphkint java_lang_invoke_MemberName::_name_offset; 266325944Sjoergint java_lang_invoke_MemberName::_type_offset; 266425944Sjoergint java_lang_invoke_MemberName::_flags_offset; 266530300Sjoergint java_lang_invoke_MemberName::_vmtarget_offset; 266625944Sjoergint java_lang_invoke_MemberName::_vmloader_offset; 266725944Sjoergint java_lang_invoke_MemberName::_vmindex_offset; 266825944Sjoerg 266925944Sjoergint java_lang_invoke_LambdaForm::_vmentry_offset; 267025944Sjoerg 267142066Sphkvoid java_lang_invoke_MethodHandle::compute_offsets() { 267225944Sjoerg Klass* klass_oop = SystemDictionary::MethodHandle_klass(); 267325944Sjoerg if (klass_oop != NULL) { 267425944Sjoerg compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature()); 267525944Sjoerg compute_offset(_form_offset, klass_oop, vmSymbols::form_name(), vmSymbols::java_lang_invoke_LambdaForm_signature()); 267625944Sjoerg } 267742066Sphk} 267842066Sphk 267942066Sphkvoid java_lang_invoke_MemberName::compute_offsets() { 268025944Sjoerg Klass* klass_oop = SystemDictionary::MemberName_klass(); 268125944Sjoerg if (klass_oop != NULL) { 268225944Sjoerg compute_offset(_clazz_offset, klass_oop, vmSymbols::clazz_name(), vmSymbols::class_signature()); 268325944Sjoerg compute_offset(_name_offset, klass_oop, vmSymbols::name_name(), vmSymbols::string_signature()); 268425944Sjoerg compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::object_signature()); 268525944Sjoerg compute_offset(_flags_offset, klass_oop, vmSymbols::flags_name(), vmSymbols::int_signature()); 268625944Sjoerg MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); 268725944Sjoerg } 268888706Sjoerg} 268925944Sjoerg 269025944Sjoergvoid java_lang_invoke_LambdaForm::compute_offsets() { 269125944Sjoerg Klass* klass_oop = SystemDictionary::LambdaForm_klass(); 269225944Sjoerg if (klass_oop != NULL) { 269325944Sjoerg compute_offset(_vmentry_offset, klass_oop, vmSymbols::vmentry_name(), vmSymbols::java_lang_invoke_MemberName_signature()); 269425944Sjoerg } 269525944Sjoerg} 269625944Sjoerg 269742066Sphkoop java_lang_invoke_MethodHandle::type(oop mh) { 269825944Sjoerg return mh->obj_field(_type_offset); 269925944Sjoerg} 270025944Sjoerg 270142066Sphkvoid java_lang_invoke_MethodHandle::set_type(oop mh, oop mtype) { 270242066Sphk mh->obj_field_put(_type_offset, mtype); 270342066Sphk} 270425944Sjoerg 270525944Sjoergoop java_lang_invoke_MethodHandle::form(oop mh) { 270625944Sjoerg assert(_form_offset != 0, ""); 270725944Sjoerg return mh->obj_field(_form_offset); 270841881Sphk} 270941881Sphk 271025944Sjoergvoid java_lang_invoke_MethodHandle::set_form(oop mh, oop lform) { 271125944Sjoerg assert(_form_offset != 0, ""); 271225944Sjoerg mh->obj_field_put(_form_offset, lform); 271325944Sjoerg} 271425944Sjoerg 271542066Sphk/// MemberName accessors 271625944Sjoerg 271725944Sjoergoop java_lang_invoke_MemberName::clazz(oop mname) { 271842066Sphk assert(is_instance(mname), "wrong type"); 271942066Sphk return mname->obj_field(_clazz_offset); 272042066Sphk} 272125944Sjoerg 272225944Sjoergvoid java_lang_invoke_MemberName::set_clazz(oop mname, oop clazz) { 272325944Sjoerg assert(is_instance(mname), "wrong type"); 272425944Sjoerg mname->obj_field_put(_clazz_offset, clazz); 272541881Sphk} 272641881Sphk 272725944Sjoergoop java_lang_invoke_MemberName::name(oop mname) { 272825944Sjoerg assert(is_instance(mname), "wrong type"); 272925944Sjoerg return mname->obj_field(_name_offset); 273025944Sjoerg} 273125944Sjoerg 273230300Sjoergvoid java_lang_invoke_MemberName::set_name(oop mname, oop name) { 273325944Sjoerg assert(is_instance(mname), "wrong type"); 273430300Sjoerg mname->obj_field_put(_name_offset, name); 273525944Sjoerg} 273625944Sjoerg 273725944Sjoergoop java_lang_invoke_MemberName::type(oop mname) { 273842065Sphk assert(is_instance(mname), "wrong type"); 273935064Sphk return mname->obj_field(_type_offset); 274040008Sjoerg} 274140008Sjoerg 274240008Sjoergvoid java_lang_invoke_MemberName::set_type(oop mname, oop type) { 274325944Sjoerg assert(is_instance(mname), "wrong type"); 274425944Sjoerg mname->obj_field_put(_type_offset, type); 274525944Sjoerg} 274625944Sjoerg 274725944Sjoergint java_lang_invoke_MemberName::flags(oop mname) { 274825944Sjoerg assert(is_instance(mname), "wrong type"); 274925944Sjoerg return mname->int_field(_flags_offset); 275025944Sjoerg} 275125944Sjoerg 275225944Sjoergvoid java_lang_invoke_MemberName::set_flags(oop mname, int flags) { 275325944Sjoerg assert(is_instance(mname), "wrong type"); 275425944Sjoerg mname->int_field_put(_flags_offset, flags); 275525944Sjoerg} 275625944Sjoerg 275725944SjoergMetadata* java_lang_invoke_MemberName::vmtarget(oop mname) { 275830300Sjoerg assert(is_instance(mname), "wrong type"); 275930300Sjoerg return (Metadata*)mname->address_field(_vmtarget_offset); 276030300Sjoerg} 276130300Sjoerg 276230300Sjoerg#if INCLUDE_JVMTI 276330300Sjoerg// Can be executed on VM thread only 276430300Sjoergvoid java_lang_invoke_MemberName::adjust_vmtarget(oop mname, Metadata* ref) { 276530300Sjoerg assert((is_instance(mname) && (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0), "wrong type"); 276630300Sjoerg assert(Thread::current()->is_VM_thread(), "not VM thread"); 276730300Sjoerg mname->address_field_put(_vmtarget_offset, (address)ref); 276878064Sume} 276925944Sjoerg#endif // INCLUDE_JVMTI 277025944Sjoerg 277125944Sjoergvoid java_lang_invoke_MemberName::set_vmtarget(oop mname, Metadata* ref) { 277225944Sjoerg assert(is_instance(mname), "wrong type"); 277330300Sjoerg // check the type of the vmtarget 277430300Sjoerg oop dependency = NULL; 277530300Sjoerg if (ref != NULL) { 277630300Sjoerg switch (flags(mname) & (MN_IS_METHOD | 277730300Sjoerg MN_IS_CONSTRUCTOR | 277830300Sjoerg MN_IS_FIELD)) { 277930300Sjoerg case MN_IS_METHOD: 278030300Sjoerg case MN_IS_CONSTRUCTOR: 278188706Sjoerg assert(ref->is_method(), "should be a method"); 278230300Sjoerg dependency = ((Method*)ref)->method_holder()->java_mirror(); 278330300Sjoerg break; 278430300Sjoerg case MN_IS_FIELD: 278530300Sjoerg assert(ref->is_klass(), "should be a class"); 278630300Sjoerg dependency = ((Klass*)ref)->java_mirror(); 278725944Sjoerg break; 278825944Sjoerg default: 278925944Sjoerg ShouldNotReachHere(); 279025944Sjoerg } 279130300Sjoerg } 279225944Sjoerg mname->address_field_put(_vmtarget_offset, (address)ref); 279325944Sjoerg // Add a reference to the loader (actually mirror because anonymous classes will not have 279430300Sjoerg // distinct loaders) to ensure the metadata is kept alive 279530300Sjoerg // This mirror may be different than the one in clazz field. 279630300Sjoerg mname->obj_field_put(_vmloader_offset, dependency); 279730300Sjoerg} 279830300Sjoerg 279930300Sjoergintptr_t java_lang_invoke_MemberName::vmindex(oop mname) { 280030300Sjoerg assert(is_instance(mname), "wrong type"); 280125944Sjoerg return (intptr_t) mname->address_field(_vmindex_offset); 280225944Sjoerg} 280370199Sjhay 280470199Sjhayvoid java_lang_invoke_MemberName::set_vmindex(oop mname, intptr_t index) { 280525944Sjoerg assert(is_instance(mname), "wrong type"); 280625944Sjoerg mname->address_field_put(_vmindex_offset, (address) index); 280725944Sjoerg} 280825944Sjoerg 280925944Sjoergoop java_lang_invoke_LambdaForm::vmentry(oop lform) { 281025944Sjoerg assert(is_instance(lform), "wrong type"); 281125944Sjoerg return lform->obj_field(_vmentry_offset); 281225944Sjoerg} 281325944Sjoerg 281425944Sjoerg 281525944Sjoerg// Support for java_lang_invoke_MethodType 281625944Sjoerg 281725944Sjoergint java_lang_invoke_MethodType::_rtype_offset; 281825944Sjoergint java_lang_invoke_MethodType::_ptypes_offset; 281978064Sume 282078064Sumevoid java_lang_invoke_MethodType::compute_offsets() { 282142065Sphk Klass* k = SystemDictionary::MethodType_klass(); 282229681Sgibbs if (k != NULL) { 282340008Sjoerg compute_offset(_rtype_offset, k, vmSymbols::rtype_name(), vmSymbols::class_signature()); 282425944Sjoerg compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature()); 282525944Sjoerg } 282625944Sjoerg} 282725944Sjoerg 282825944Sjoergvoid java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) { 282925944Sjoerg st->print("("); 283025944Sjoerg objArrayOop pts = ptypes(mt); 283125944Sjoerg for (int i = 0, limit = pts->length(); i < limit; i++) { 283225944Sjoerg java_lang_Class::print_signature(pts->obj_at(i), st); 283325944Sjoerg } 283425944Sjoerg st->print(")"); 283525944Sjoerg java_lang_Class::print_signature(rtype(mt), st); 283625944Sjoerg} 283725944Sjoerg 283825944SjoergSymbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) { 283925944Sjoerg ResourceMark rm; 284025944Sjoerg stringStream buffer(128); 284125944Sjoerg print_signature(mt, &buffer); 284225944Sjoerg const char* sigstr = buffer.base(); 284325944Sjoerg int siglen = (int) buffer.size(); 284488534Sjoerg Symbol *name; 284588534Sjoerg if (!intern_if_not_found) { 284688700Sjoerg name = SymbolTable::probe(sigstr, siglen); 284742104Sphk } else { 284830300Sjoerg name = SymbolTable::new_symbol(sigstr, siglen, THREAD); 284925944Sjoerg } 285025944Sjoerg return name; 285125944Sjoerg} 285225944Sjoerg 285325944Sjoergbool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) { 285425944Sjoerg if (mt1 == mt2) 285525944Sjoerg return true; 285625944Sjoerg if (rtype(mt1) != rtype(mt2)) 285725944Sjoerg return false; 285840008Sjoerg if (ptype_count(mt1) != ptype_count(mt2)) 285940008Sjoerg return false; 286025944Sjoerg for (int i = ptype_count(mt1) - 1; i >= 0; i--) { 286125944Sjoerg if (ptype(mt1, i) != ptype(mt2, i)) 286225944Sjoerg return false; 286325944Sjoerg } 286425944Sjoerg return true; 286525944Sjoerg} 286625944Sjoerg 286725944Sjoergoop java_lang_invoke_MethodType::rtype(oop mt) { 286825944Sjoerg assert(is_instance(mt), "must be a MethodType"); 286942104Sphk return mt->obj_field(_rtype_offset); 287042104Sphk} 287188723Sjoerg 287288534SjoergobjArrayOop java_lang_invoke_MethodType::ptypes(oop mt) { 287388534Sjoerg assert(is_instance(mt), "must be a MethodType"); 287488534Sjoerg return (objArrayOop) mt->obj_field(_ptypes_offset); 287588534Sjoerg} 287625944Sjoerg 287725944Sjoergoop java_lang_invoke_MethodType::ptype(oop mt, int idx) { 287825944Sjoerg return ptypes(mt)->obj_at(idx); 287925944Sjoerg} 288025944Sjoerg 288125944Sjoergint java_lang_invoke_MethodType::ptype_count(oop mt) { 288225944Sjoerg return ptypes(mt)->length(); 288325944Sjoerg} 288425944Sjoerg 288525944Sjoergint java_lang_invoke_MethodType::ptype_slot_count(oop mt) { 288625944Sjoerg objArrayOop pts = ptypes(mt); 288725944Sjoerg int count = pts->length(); 288825944Sjoerg int slots = 0; 288925944Sjoerg for (int i = 0; i < count; i++) { 289025944Sjoerg BasicType bt = java_lang_Class::as_BasicType(pts->obj_at(i)); 289125944Sjoerg slots += type2size[bt]; 289225944Sjoerg } 289325944Sjoerg return slots; 289425944Sjoerg} 289525944Sjoerg 289625944Sjoergint java_lang_invoke_MethodType::rtype_slot_count(oop mt) { 289725944Sjoerg BasicType bt = java_lang_Class::as_BasicType(rtype(mt)); 289825944Sjoerg return type2size[bt]; 289925944Sjoerg} 290025944Sjoerg 290125944Sjoerg 290225944Sjoerg// Support for java_lang_invoke_CallSite 290325944Sjoerg 290425944Sjoergint java_lang_invoke_CallSite::_target_offset; 290525944Sjoerg 290625944Sjoergvoid java_lang_invoke_CallSite::compute_offsets() { 290725944Sjoerg Klass* k = SystemDictionary::CallSite_klass(); 290825944Sjoerg if (k != NULL) { 290942104Sphk compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature()); 291088534Sjoerg } 291125944Sjoerg} 291225944Sjoerg 291325944Sjoerg 291425944Sjoerg// Support for java_security_AccessControlContext 291525944Sjoerg 291625944Sjoergint java_security_AccessControlContext::_context_offset = 0; 291725944Sjoergint java_security_AccessControlContext::_privilegedContext_offset = 0; 291825944Sjoergint java_security_AccessControlContext::_isPrivileged_offset = 0; 291925944Sjoergint java_security_AccessControlContext::_isAuthorized_offset = -1; 292025944Sjoerg 292125944Sjoergvoid java_security_AccessControlContext::compute_offsets() { 292225944Sjoerg assert(_isPrivileged_offset == 0, "offsets should be initialized only once"); 292325944Sjoerg fieldDescriptor fd; 292440008Sjoerg InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass()); 292540008Sjoerg 292625944Sjoerg if (!ik->find_local_field(vmSymbols::context_name(), vmSymbols::protectiondomain_signature(), &fd)) { 292725944Sjoerg fatal("Invalid layout of java.security.AccessControlContext"); 292825944Sjoerg } 292969211Sphk _context_offset = fd.offset(); 293025944Sjoerg 293188534Sjoerg if (!ik->find_local_field(vmSymbols::privilegedContext_name(), vmSymbols::accesscontrolcontext_signature(), &fd)) { 293288723Sjoerg fatal("Invalid layout of java.security.AccessControlContext"); 293388534Sjoerg } 293488534Sjoerg _privilegedContext_offset = fd.offset(); 293588534Sjoerg 293688534Sjoerg if (!ik->find_local_field(vmSymbols::isPrivileged_name(), vmSymbols::bool_signature(), &fd)) { 293788534Sjoerg fatal("Invalid layout of java.security.AccessControlContext"); 293888534Sjoerg } 293988534Sjoerg _isPrivileged_offset = fd.offset(); 294088534Sjoerg 294188534Sjoerg // The offset may not be present for bootstrapping with older JDK. 294288534Sjoerg if (ik->find_local_field(vmSymbols::isAuthorized_name(), vmSymbols::bool_signature(), &fd)) { 294388534Sjoerg _isAuthorized_offset = fd.offset(); 294488534Sjoerg } 294588534Sjoerg} 294688534Sjoerg 294788534Sjoerg 294888534Sjoergbool java_security_AccessControlContext::is_authorized(Handle context) { 294988534Sjoerg assert(context.not_null() && context->klass() == SystemDictionary::AccessControlContext_klass(), "Invalid type"); 295088534Sjoerg assert(_isAuthorized_offset != -1, "should be set"); 295188534Sjoerg return context->bool_field(_isAuthorized_offset) != 0; 295288534Sjoerg} 295388534Sjoerg 295488534Sjoergoop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) { 295588534Sjoerg assert(_isPrivileged_offset != 0, "offsets should have been initialized"); 295688534Sjoerg // Ensure klass is initialized 295788534Sjoerg InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->initialize(CHECK_0); 295888534Sjoerg // Allocate result 295988534Sjoerg oop result = InstanceKlass::cast(SystemDictionary::AccessControlContext_klass())->allocate_instance(CHECK_0); 296088534Sjoerg // Fill in values 296188534Sjoerg result->obj_field_put(_context_offset, context()); 296225944Sjoerg result->obj_field_put(_privilegedContext_offset, privileged_context()); 296325944Sjoerg result->bool_field_put(_isPrivileged_offset, isPrivileged); 296425944Sjoerg // whitelist AccessControlContexts created by the JVM if present 296525944Sjoerg if (_isAuthorized_offset != -1) { 296625944Sjoerg result->bool_field_put(_isAuthorized_offset, true); 296725706Sjoerg } 296869211Sphk return result; 296911189Sjkh} 297025944Sjoerg 297125944Sjoerg 297225944Sjoerg// Support for java_lang_ClassLoader 297369211Sphk 29744910Swollmanbool java_lang_ClassLoader::offsets_computed = false; 29754910Swollmanint java_lang_ClassLoader::_loader_data_offset = -1; 297625944Sjoergint java_lang_ClassLoader::parallelCapable_offset = -1; 297725944Sjoerg 297825944SjoergClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) { 297925944Sjoerg assert(loader != NULL && loader->is_oop(), "loader must be oop"); 298025944Sjoerg return (ClassLoaderData**) loader->address_field_addr(_loader_data_offset); 298125944Sjoerg} 298225944Sjoerg 298369211SphkClassLoaderData* java_lang_ClassLoader::loader_data(oop loader) { 298425944Sjoerg return *java_lang_ClassLoader::loader_data_addr(loader); 298525944Sjoerg} 298625944Sjoerg 298769211Sphkvoid java_lang_ClassLoader::compute_offsets() { 298825944Sjoerg assert(!offsets_computed, "offsets should be initialized only once"); 298925944Sjoerg offsets_computed = true; 299030300Sjoerg 299125944Sjoerg // The field indicating parallelCapable (parallelLockMap) is only present starting in 7, 299240008Sjoerg Klass* k1 = SystemDictionary::ClassLoader_klass(); 299340008Sjoerg compute_optional_offset(parallelCapable_offset, 299425944Sjoerg k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); 299525944Sjoerg 299625944Sjoerg CLASSLOADER_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); 299725944Sjoerg} 299869211Sphk 299925944Sjoergoop java_lang_ClassLoader::parent(oop loader) { 300088534Sjoerg assert(is_instance(loader), "loader must be oop"); 300188534Sjoerg return loader->obj_field(parent_offset); 300288534Sjoerg} 300388534Sjoerg 300488534Sjoergbool java_lang_ClassLoader::isAncestor(oop loader, oop cl) { 300588534Sjoerg assert(is_instance(loader), "loader must be oop"); 300688534Sjoerg assert(cl == NULL || is_instance(cl), "cl argument must be oop"); 300788599Sjoerg oop acl = loader; 300888534Sjoerg debug_only(jint loop_count = 0); 300988534Sjoerg // This loop taken verbatim from ClassLoader.java: 301088534Sjoerg do { 301188534Sjoerg acl = parent(acl); 301288534Sjoerg if (cl == acl) { 301388534Sjoerg return true; 301488534Sjoerg } 301588534Sjoerg assert(++loop_count > 0, "loop_count overflow"); 301688534Sjoerg } while (acl != NULL); 301788534Sjoerg return false; 301888534Sjoerg} 301988534Sjoerg 302088534Sjoerg 302125944Sjoerg// For class loader classes, parallelCapable defined 302242104Sphk// based on non-null field 302325944Sjoerg// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it 302425944Sjoergbool java_lang_ClassLoader::parallelCapable(oop class_loader) { 302533928Sphk if (!JDK_Version::is_gte_jdk17x_version() 302688702Sjoerg || parallelCapable_offset == -1) { 302725944Sjoerg // Default for backward compatibility is false 302825944Sjoerg return false; 302988702Sjoerg } 303033928Sphk return (class_loader->obj_field(parallelCapable_offset) != NULL); 303125944Sjoerg} 303225944Sjoerg 303325944Sjoergbool java_lang_ClassLoader::is_trusted_loader(oop loader) { 303425944Sjoerg // Fix for 4474172; see evaluation for more details 303569211Sphk loader = non_reflection_class_loader(loader); 303642104Sphk 303725944Sjoerg oop cl = SystemDictionary::java_system_loader(); 303825944Sjoerg while(cl != NULL) { 303925944Sjoerg if (cl == loader) return true; 304025944Sjoerg cl = parent(cl); 304125944Sjoerg } 304225944Sjoerg return false; 304325944Sjoerg} 304425944Sjoerg 304525944Sjoergoop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { 304625944Sjoerg if (loader != NULL) { 304742104Sphk // See whether this is one of the class loaders associated with 304825944Sjoerg // the generated bytecodes for reflection, and if so, "magically" 304925944Sjoerg // delegate to its parent to prevent class loading from occurring 305025944Sjoerg // in places where applications using reflection didn't expect it. 305169211Sphk Klass* delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass(); 305225944Sjoerg // This might be null in non-1.4 JDKs 305369211Sphk if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) { 305442104Sphk return parent(loader); 305525944Sjoerg } 305625944Sjoerg } 305744235Sphk return loader; 305844235Sphk} 305944235Sphk 306044235Sphk 306111189Sjkh// Support for java_lang_System 306225706Sjoergint java_lang_System::in_offset_in_bytes() { 306325944Sjoerg return (InstanceMirrorKlass::offset_of_static_fields() + static_in_offset); 306425944Sjoerg} 306525944Sjoerg 306625944Sjoerg 306725944Sjoergint java_lang_System::out_offset_in_bytes() { 306825944Sjoerg return (InstanceMirrorKlass::offset_of_static_fields() + static_out_offset); 306925944Sjoerg} 307025944Sjoerg 307125944Sjoerg 307225944Sjoergint java_lang_System::err_offset_in_bytes() { 307325944Sjoerg return (InstanceMirrorKlass::offset_of_static_fields() + static_err_offset); 307425944Sjoerg} 307525944Sjoerg 307625944Sjoerg 307725944Sjoergbool java_lang_System::has_security_manager() { 307825944Sjoerg InstanceKlass* ik = InstanceKlass::cast(SystemDictionary::System_klass()); 307942104Sphk address addr = ik->static_field_addr(static_security_offset); 308025944Sjoerg if (UseCompressedOops) { 308125944Sjoerg return oopDesc::load_decode_heap_oop((narrowOop *)addr) != NULL; 308225944Sjoerg } else { 308325944Sjoerg return oopDesc::load_decode_heap_oop((oop*)addr) != NULL; 308425944Sjoerg } 308525944Sjoerg} 308625944Sjoerg 308725706Sjoergint java_lang_Class::_klass_offset; 308869211Sphkint java_lang_Class::_array_klass_offset; 308925944Sjoergint java_lang_Class::_oop_size_offset; 309025944Sjoergint java_lang_Class::_static_oop_field_count_offset; 309125944Sjoergint java_lang_Class::_protection_domain_offset; 309225706Sjoergint java_lang_Class::_init_lock_offset; 309369211Sphkint java_lang_Class::_signers_offset; 309425944SjoergGrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL; 309525944Sjoergint java_lang_Throwable::backtrace_offset; 309625706Sjoergint java_lang_Throwable::detailMessage_offset; 309769211Sphkint java_lang_Throwable::cause_offset; 309825944Sjoergint java_lang_Throwable::stackTrace_offset; 309925944Sjoergint java_lang_Throwable::static_unassigned_stacktrace_offset; 310025944Sjoergint java_lang_reflect_AccessibleObject::override_offset; 310125944Sjoergint java_lang_reflect_Method::clazz_offset; 310225944Sjoergint java_lang_reflect_Method::name_offset; 310325944Sjoergint java_lang_reflect_Method::returnType_offset; 310425944Sjoergint java_lang_reflect_Method::parameterTypes_offset; 310525944Sjoergint java_lang_reflect_Method::exceptionTypes_offset; 310625944Sjoergint java_lang_reflect_Method::slot_offset; 310725944Sjoergint java_lang_reflect_Method::modifiers_offset; 310825944Sjoergint java_lang_reflect_Method::signature_offset; 310925944Sjoergint java_lang_reflect_Method::annotations_offset; 311025944Sjoergint java_lang_reflect_Method::parameter_annotations_offset; 311125944Sjoergint java_lang_reflect_Method::annotation_default_offset; 311225944Sjoergint java_lang_reflect_Method::type_annotations_offset; 311325944Sjoergint java_lang_reflect_Constructor::clazz_offset; 311425944Sjoergint java_lang_reflect_Constructor::parameterTypes_offset; 311525944Sjoergint java_lang_reflect_Constructor::exceptionTypes_offset; 311625944Sjoergint java_lang_reflect_Constructor::slot_offset; 311725944Sjoergint java_lang_reflect_Constructor::modifiers_offset; 311825944Sjoergint java_lang_reflect_Constructor::signature_offset; 311925944Sjoergint java_lang_reflect_Constructor::annotations_offset; 312025944Sjoergint java_lang_reflect_Constructor::parameter_annotations_offset; 312125944Sjoergint java_lang_reflect_Constructor::type_annotations_offset; 312225944Sjoergint java_lang_reflect_Field::clazz_offset; 312340008Sjoergint java_lang_reflect_Field::name_offset; 312440008Sjoergint java_lang_reflect_Field::type_offset; 312525944Sjoergint java_lang_reflect_Field::slot_offset; 312625944Sjoergint java_lang_reflect_Field::modifiers_offset; 312725944Sjoergint java_lang_reflect_Field::signature_offset; 312825706Sjoergint java_lang_reflect_Field::annotations_offset; 312969211Sphkint java_lang_reflect_Field::type_annotations_offset; 313025944Sjoergint java_lang_reflect_Parameter::name_offset; 313188534Sjoergint java_lang_reflect_Parameter::modifiers_offset; 313288534Sjoergint java_lang_reflect_Parameter::index_offset; 313388534Sjoergint java_lang_reflect_Parameter::executable_offset; 313425944Sjoergint java_lang_boxing_object::value_offset; 313525944Sjoergint java_lang_boxing_object::long_value_offset; 313625944Sjoergint java_lang_ref_Reference::referent_offset; 313725944Sjoergint java_lang_ref_Reference::queue_offset; 313842104Sphkint java_lang_ref_Reference::next_offset; 313925944Sjoergint java_lang_ref_Reference::discovered_offset; 314025944Sjoergint java_lang_ref_Reference::static_lock_offset; 314125944Sjoergint java_lang_ref_Reference::static_pending_offset; 314225944Sjoergint java_lang_ref_Reference::number_of_fake_oop_fields; 31434910Swollmanint java_lang_ref_SoftReference::timestamp_offset; 314425944Sjoergint java_lang_ref_SoftReference::static_clock_offset; 314569211Sphkint java_lang_ClassLoader::parent_offset; 314625944Sjoergint java_lang_System::static_in_offset; 314725944Sjoergint java_lang_System::static_out_offset; 31484910Swollmanint java_lang_System::static_err_offset; 31494910Swollmanint java_lang_System::static_security_offset; 315025944Sjoergint java_lang_StackTraceElement::declaringClass_offset; 315125944Sjoergint java_lang_StackTraceElement::methodName_offset; 315225944Sjoergint java_lang_StackTraceElement::fileName_offset; 315325944Sjoergint java_lang_StackTraceElement::lineNumber_offset; 315412820Sphkint java_lang_AssertionStatusDirectives::classes_offset; 315525944Sjoergint java_lang_AssertionStatusDirectives::classEnabled_offset; 31564910Swollmanint java_lang_AssertionStatusDirectives::packages_offset; 315725944Sjoergint java_lang_AssertionStatusDirectives::packageEnabled_offset; 315825944Sjoergint java_lang_AssertionStatusDirectives::deflt_offset; 315925944Sjoergint java_nio_Buffer::_limit_offset; 316088534Sjoergint java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0; 316125944Sjoergint sun_reflect_ConstantPool::_oop_offset; 31624910Swollmanint sun_reflect_UnsafeStaticFieldAccessorImpl::_base_offset; 316325944Sjoerg 316425944Sjoerg 316525944Sjoerg// Support for java_lang_StackTraceElement 316625944Sjoerg 316725944Sjoergvoid java_lang_StackTraceElement::set_fileName(oop element, oop value) { 316825944Sjoerg element->obj_field_put(fileName_offset, value); 316940008Sjoerg} 317040008Sjoerg 317125944Sjoergvoid java_lang_StackTraceElement::set_declaringClass(oop element, oop value) { 317225944Sjoerg element->obj_field_put(declaringClass_offset, value); 317325944Sjoerg} 317425944Sjoerg 317569211Sphkvoid java_lang_StackTraceElement::set_methodName(oop element, oop value) { 317625944Sjoerg element->obj_field_put(methodName_offset, value); 317788534Sjoerg} 317888534Sjoerg 317988534Sjoergvoid java_lang_StackTraceElement::set_lineNumber(oop element, int value) { 318088534Sjoerg element->int_field_put(lineNumber_offset, value); 318188534Sjoerg} 318288534Sjoerg 318388534Sjoerg 318488599Sjoerg// Support for java Assertions - java_lang_AssertionStatusDirectives. 318588534Sjoerg 318688534Sjoergvoid java_lang_AssertionStatusDirectives::set_classes(oop o, oop val) { 318788534Sjoerg o->obj_field_put(classes_offset, val); 318888534Sjoerg} 318988534Sjoerg 319088534Sjoergvoid java_lang_AssertionStatusDirectives::set_classEnabled(oop o, oop val) { 319188534Sjoerg o->obj_field_put(classEnabled_offset, val); 319288534Sjoerg} 319388534Sjoerg 319425944Sjoergvoid java_lang_AssertionStatusDirectives::set_packages(oop o, oop val) { 319525944Sjoerg o->obj_field_put(packages_offset, val); 319625944Sjoerg} 319725944Sjoerg 319825944Sjoergvoid java_lang_AssertionStatusDirectives::set_packageEnabled(oop o, oop val) { 319925944Sjoerg o->obj_field_put(packageEnabled_offset, val); 320025944Sjoerg} 320125944Sjoerg 320225944Sjoergvoid java_lang_AssertionStatusDirectives::set_deflt(oop o, bool val) { 320325944Sjoerg o->bool_field_put(deflt_offset, val); 320425944Sjoerg} 320569211Sphk 320630300Sjoerg 320725944Sjoerg// Support for intrinsification of java.nio.Buffer.checkIndex 320825944Sjoergint java_nio_Buffer::limit_offset() { 320925944Sjoerg return _limit_offset; 321025944Sjoerg} 321125944Sjoerg 321242104Sphk 321342104Sphkvoid java_nio_Buffer::compute_offsets() { 321425944Sjoerg Klass* k = SystemDictionary::nio_Buffer_klass(); 321525944Sjoerg assert(k != NULL, "must be loaded in 1.4+"); 321625944Sjoerg compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature()); 321725944Sjoerg} 321869211Sphk 321942104Sphkvoid java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) { 322025944Sjoerg if (_owner_offset != 0) return; 322125944Sjoerg 322225944Sjoerg assert(JDK_Version::is_gte_jdk16x_version(), "Must be JDK 1.6 or later"); 322325944Sjoerg SystemDictionary::load_abstract_ownable_synchronizer_klass(CHECK); 322425944Sjoerg Klass* k = SystemDictionary::abstract_ownable_synchronizer_klass(); 322525944Sjoerg compute_offset(_owner_offset, k, 322669211Sphk vmSymbols::exclusive_owner_thread_name(), vmSymbols::thread_signature()); 322725944Sjoerg} 322825944Sjoerg 32294910Swollmanoop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(oop obj) { 32304910Swollman assert(_owner_offset != 0, "Must be initialized"); 323112820Sphk return obj->obj_field(_owner_offset); 323225944Sjoerg} 32334910Swollman 323442104Sphk// Compute hard-coded offsets 323542104Sphk// Invoked before SystemDictionary::initialize, so pre-loaded classes 323642104Sphk// are not available to determine the offset_of_static_fields. 32374910Swollmanvoid JavaClasses::compute_hard_coded_offsets() { 32384910Swollman const int x = heapOopSize; 323925944Sjoerg const int header = instanceOopDesc::base_offset_in_bytes(); 324025944Sjoerg 324125944Sjoerg // Throwable Class 324225944Sjoerg java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; 324325944Sjoerg java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; 324425944Sjoerg java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; 324525944Sjoerg java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; 324625944Sjoerg java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x; 324725944Sjoerg 324825944Sjoerg // java_lang_boxing_object 324925944Sjoerg java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header; 325025944Sjoerg java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong); 325125944Sjoerg 325225944Sjoerg // java_lang_ref_Reference: 325325944Sjoerg java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header; 325425944Sjoerg java_lang_ref_Reference::queue_offset = java_lang_ref_Reference::hc_queue_offset * x + header; 325525944Sjoerg java_lang_ref_Reference::next_offset = java_lang_ref_Reference::hc_next_offset * x + header; 325630300Sjoerg java_lang_ref_Reference::discovered_offset = java_lang_ref_Reference::hc_discovered_offset * x + header; 325725944Sjoerg java_lang_ref_Reference::static_lock_offset = java_lang_ref_Reference::hc_static_lock_offset * x; 325825944Sjoerg java_lang_ref_Reference::static_pending_offset = java_lang_ref_Reference::hc_static_pending_offset * x; 325925944Sjoerg // Artificial fields for java_lang_ref_Reference 326025944Sjoerg // The first field is for the discovered field added in 1.4 326125944Sjoerg java_lang_ref_Reference::number_of_fake_oop_fields = 1; 326225944Sjoerg 326325944Sjoerg // java_lang_ref_SoftReference Class 326425944Sjoerg java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong); 326525944Sjoerg // Don't multiply static fields because they are always in wordSize units 326688534Sjoerg java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x; 326788534Sjoerg 326888534Sjoerg // java_lang_ClassLoader 326988534Sjoerg java_lang_ClassLoader::parent_offset = java_lang_ClassLoader::hc_parent_offset * x + header; 327088534Sjoerg 327188534Sjoerg // java_lang_System 327288534Sjoerg java_lang_System::static_in_offset = java_lang_System::hc_static_in_offset * x; 327388534Sjoerg java_lang_System::static_out_offset = java_lang_System::hc_static_out_offset * x; 327425944Sjoerg java_lang_System::static_err_offset = java_lang_System::hc_static_err_offset * x; 327530300Sjoerg java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x; 327625944Sjoerg 327725944Sjoerg // java_lang_StackTraceElement 327825944Sjoerg java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header; 327925944Sjoerg java_lang_StackTraceElement::methodName_offset = java_lang_StackTraceElement::hc_methodName_offset * x + header; 328025944Sjoerg java_lang_StackTraceElement::fileName_offset = java_lang_StackTraceElement::hc_fileName_offset * x + header; 328125944Sjoerg java_lang_StackTraceElement::lineNumber_offset = java_lang_StackTraceElement::hc_lineNumber_offset * x + header; 328225944Sjoerg java_lang_AssertionStatusDirectives::classes_offset = java_lang_AssertionStatusDirectives::hc_classes_offset * x + header; 328325944Sjoerg java_lang_AssertionStatusDirectives::classEnabled_offset = java_lang_AssertionStatusDirectives::hc_classEnabled_offset * x + header; 328478064Sume java_lang_AssertionStatusDirectives::packages_offset = java_lang_AssertionStatusDirectives::hc_packages_offset * x + header; 328525944Sjoerg java_lang_AssertionStatusDirectives::packageEnabled_offset = java_lang_AssertionStatusDirectives::hc_packageEnabled_offset * x + header; 328625944Sjoerg java_lang_AssertionStatusDirectives::deflt_offset = java_lang_AssertionStatusDirectives::hc_deflt_offset * x + header; 328725944Sjoerg 328870199Sjhay} 328930300Sjoerg 329030300Sjoerg 329178064Sume// Compute non-hard-coded field offsets of all the classes in this file 329278064Sumevoid JavaClasses::compute_offsets() { 329378064Sume // java_lang_Class::compute_offsets was called earlier in bootstrap 329478064Sume java_lang_ClassLoader::compute_offsets(); 329578064Sume java_lang_Thread::compute_offsets(); 329678064Sume java_lang_ThreadGroup::compute_offsets(); 329778064Sume java_lang_invoke_MethodHandle::compute_offsets(); 329878064Sume java_lang_invoke_DirectMethodHandle::compute_offsets(); 329978064Sume java_lang_invoke_MemberName::compute_offsets(); 330078064Sume java_lang_invoke_LambdaForm::compute_offsets(); 330178064Sume java_lang_invoke_MethodType::compute_offsets(); 330278064Sume java_lang_invoke_CallSite::compute_offsets(); 330378064Sume java_security_AccessControlContext::compute_offsets(); 330478064Sume // Initialize reflection classes. The layouts of these classes 330578064Sume // changed with the new reflection implementation in JDK 1.4, and 330678064Sume // since the Universe doesn't know what JDK version it is until this 330778064Sume // point we defer computation of these offsets until now. 330878064Sume java_lang_reflect_AccessibleObject::compute_offsets(); 330978064Sume java_lang_reflect_Method::compute_offsets(); 331078064Sume java_lang_reflect_Constructor::compute_offsets(); 331178064Sume java_lang_reflect_Field::compute_offsets(); 331278064Sume if (JDK_Version::is_gte_jdk14x_version()) { 331378064Sume java_nio_Buffer::compute_offsets(); 331478064Sume } 331578064Sume if (JDK_Version::is_gte_jdk15x_version()) { 331678064Sume sun_reflect_ConstantPool::compute_offsets(); 331778064Sume sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); 331878064Sume } 331978064Sume if (JDK_Version::is_gte_jdk18x_version()) 332078064Sume java_lang_reflect_Parameter::compute_offsets(); 332178064Sume 332278064Sume // generated interpreter code wants to know about the offsets we just computed: 332378064Sume AbstractAssembler::update_delayed_values(); 332478064Sume} 332578064Sume 332678064Sume#ifndef PRODUCT 332778064Sume 332878064Sume// These functions exist to assert the validity of hard-coded field offsets to guard 332978064Sume// against changes in the class files 333078064Sume 333178064Sumebool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { 333278064Sume EXCEPTION_MARK; 333378064Sume fieldDescriptor fd; 333478064Sume TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); 333578064Sume Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 333678064Sume instanceKlassHandle h_klass (THREAD, k); 333778064Sume TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); 333878064Sume TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); 333978064Sume if (!h_klass->find_local_field(f_name, f_sig, &fd)) { 334078064Sume tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name); 334178064Sume return false; 334278064Sume } 334378064Sume if (fd.is_static()) { 334478064Sume tty->print_cr("Nonstatic field %s.%s appears to be static", klass_name, field_name); 334578064Sume return false; 334678064Sume } 334778064Sume if (fd.offset() == hardcoded_offset ) { 334878064Sume return true; 334978064Sume } else { 335078064Sume tty->print_cr("Offset of nonstatic field %s.%s is hardcoded as %d but should really be %d.", 335178064Sume klass_name, field_name, hardcoded_offset, fd.offset()); 335278064Sume return false; 335378064Sume } 335478064Sume} 335578064Sume 335678064Sume 335778064Sumebool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) { 335878064Sume EXCEPTION_MARK; 335978064Sume fieldDescriptor fd; 336078064Sume TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); 336178064Sume Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 336278064Sume instanceKlassHandle h_klass (THREAD, k); 336378064Sume TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); 336478064Sume TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); 336578064Sume if (!h_klass->find_local_field(f_name, f_sig, &fd)) { 336678064Sume tty->print_cr("Static field %s.%s not found", klass_name, field_name); 336778064Sume return false; 336878064Sume } 336978064Sume if (!fd.is_static()) { 337078064Sume tty->print_cr("Static field %s.%s appears to be nonstatic", klass_name, field_name); 337178064Sume return false; 337278064Sume } 337378064Sume if (fd.offset() == hardcoded_offset + InstanceMirrorKlass::offset_of_static_fields()) { 337478064Sume return true; 337578064Sume } else { 337678064Sume tty->print_cr("Offset of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_offset, fd.offset() - InstanceMirrorKlass::offset_of_static_fields()); 337778064Sume return false; 337878064Sume } 337978064Sume} 338078064Sume 338178064Sume 338278064Sumebool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) { 338378064Sume EXCEPTION_MARK; 338478064Sume fieldDescriptor fd; 338578064Sume TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH); 338678064Sume Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH); 338778064Sume instanceKlassHandle h_klass (THREAD, k); 338878064Sume TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH); 338978064Sume TempNewSymbol f_sig = SymbolTable::new_symbol(field_sig, CATCH); 339078064Sume if (!h_klass->find_local_field(f_name, f_sig, &fd)) { 339178064Sume tty->print_cr("Static field %s.%s not found", klass_name, field_name); 339278064Sume return false; 339378064Sume } 339478064Sume if (!fd.is_static() || !fd.has_initial_value()) { 339578064Sume tty->print_cr("Static field %s.%s appears to be non-constant", klass_name, field_name); 339678064Sume return false; 339778064Sume } 339878064Sume if (!fd.initial_value_tag().is_int()) { 339978064Sume tty->print_cr("Static field %s.%s is not an int", klass_name, field_name); 340078064Sume return false; 340178064Sume } 340278064Sume jint field_value = fd.int_initial_value(); 340378064Sume if (field_value == hardcoded_constant) { 340478064Sume return true; 340578176Sume } else { 340678064Sume tty->print_cr("Constant value of static field %s.%s is hardcoded as %d but should really be %d.", klass_name, field_name, hardcoded_constant, field_value); 340778064Sume return false; 340878064Sume } 340978064Sume} 341078064Sume 341178064Sume 341278064Sume// Check the hard-coded field offsets of all the classes in this file 341378064Sume 341478176Sumevoid JavaClasses::check_offsets() { 341578064Sume bool valid = true; 341678064Sume HandleMark hm; 341778064Sume 341878064Sume#define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ 341978064Sume valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig) 342078064Sume 342178064Sume#define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ 342278064Sume valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig) 342378176Sume 342478064Sume#define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ 342578064Sume valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig) 342678064Sume 342778064Sume#define CHECK_CONSTANT(klass_name, cpp_klass_name, field_name, field_sig) \ 342878064Sume valid &= check_constant(klass_name, cpp_klass_name :: field_name, #field_name, field_sig) 342978176Sume 343078064Sume // java.lang.String 343178064Sume 343278064Sume CHECK_OFFSET("java/lang/String", java_lang_String, value, "[C"); 343378064Sume if (java_lang_String::has_offset_field()) { 343478064Sume CHECK_OFFSET("java/lang/String", java_lang_String, offset, "I"); 343578064Sume CHECK_OFFSET("java/lang/String", java_lang_String, count, "I"); 343678064Sume } 343778064Sume if (java_lang_String::has_hash_field()) { 343878064Sume CHECK_OFFSET("java/lang/String", java_lang_String, hash, "I"); 343978176Sume } 344078064Sume 344178064Sume // java.lang.Class 344278064Sume 344378176Sume // Fake fields 344478064Sume // CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked 344578064Sume // CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked 344678064Sume 344778064Sume // java.lang.Throwable 344878064Sume 344978064Sume CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, backtrace, "Ljava/lang/Object;"); 345078064Sume CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, detailMessage, "Ljava/lang/String;"); 345178064Sume CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, cause, "Ljava/lang/Throwable;"); 345278064Sume CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;"); 345378064Sume 345478064Sume // Boxed primitive objects (java_lang_boxing_object) 345578176Sume 345678064Sume CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z"); 345778064Sume CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C"); 345878064Sume CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F"); 345978064Sume CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D"); 346078064Sume CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B"); 346178064Sume CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S"); 346278064Sume CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I"); 346378064Sume CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J"); 346478064Sume 346578064Sume // java.lang.ClassLoader 346678064Sume 346778064Sume CHECK_OFFSET("java/lang/ClassLoader", java_lang_ClassLoader, parent, "Ljava/lang/ClassLoader;"); 346878064Sume 346978064Sume // java.lang.System 347078064Sume 347178064Sume CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, in, "Ljava/io/InputStream;"); 347278064Sume CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, out, "Ljava/io/PrintStream;"); 347378064Sume CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, err, "Ljava/io/PrintStream;"); 347478064Sume CHECK_STATIC_OFFSET("java/lang/System", java_lang_System, security, "Ljava/lang/SecurityManager;"); 347578064Sume 347678176Sume // java.lang.StackTraceElement 347778064Sume 347878064Sume CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;"); 347978064Sume CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;"); 348078064Sume CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;"); 348178064Sume CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, lineNumber, "I"); 348278064Sume 348378064Sume // java.lang.ref.Reference 348478064Sume 348578064Sume CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, referent, "Ljava/lang/Object;"); 348678064Sume CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, queue, "Ljava/lang/ref/ReferenceQueue;"); 348778064Sume CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;"); 348878064Sume // Fake field 348978064Sume //CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, discovered, "Ljava/lang/ref/Reference;"); 349078064Sume CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, lock, "Ljava/lang/ref/Reference$Lock;"); 349178064Sume CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, pending, "Ljava/lang/ref/Reference;"); 349278064Sume 349378064Sume // java.lang.ref.SoftReference 349478064Sume 349578064Sume CHECK_OFFSET("java/lang/ref/SoftReference", java_lang_ref_SoftReference, timestamp, "J"); 349678064Sume CHECK_STATIC_OFFSET("java/lang/ref/SoftReference", java_lang_ref_SoftReference, clock, "J"); 349778064Sume 349878064Sume // java.lang.AssertionStatusDirectives 349978176Sume // 350078064Sume // The CheckAssertionStatusDirectives boolean can be removed from here and 350178064Sume // globals.hpp after the AssertionStatusDirectives class has been integrated 350278064Sume // into merlin "for some time." Without it, the vm will fail with early 350378064Sume // merlin builds. 350478064Sume 350578064Sume if (CheckAssertionStatusDirectives && JDK_Version::is_gte_jdk14x_version()) { 350678064Sume const char* nm = "java/lang/AssertionStatusDirectives"; 350778064Sume const char* sig = "[Ljava/lang/String;"; 350878064Sume CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classes, sig); 350978064Sume CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, classEnabled, "[Z"); 351078064Sume CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, packages, sig); 351178176Sume CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, packageEnabled, "[Z"); 351278064Sume CHECK_OFFSET(nm, java_lang_AssertionStatusDirectives, deflt, "Z"); 351378064Sume } 351478064Sume 351578064Sume if (!valid) vm_exit_during_initialization("Hard-coded field offset verification failed"); 351678064Sume} 351778064Sume 351878064Sume#endif // PRODUCT 351978064Sume 352078176Sumeint InjectedField::compute_offset() { 352178064Sume Klass* klass_oop = klass(); 352278064Sume for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) { 352378064Sume if (!may_be_java && !fs.access_flags().is_internal()) { 352478064Sume // Only look at injected fields 352578064Sume continue; 352678064Sume } 352778064Sume if (fs.name() == name() && fs.signature() == signature()) { 352878064Sume return fs.offset(); 352978064Sume } 353078064Sume } 353178064Sume ResourceMark rm; 353278064Sume tty->print_cr("Invalid layout of %s at %s/%s%s", InstanceKlass::cast(klass_oop)->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : ""); 353378064Sume#ifndef PRODUCT 353478064Sume klass_oop->print(); 353578064Sume tty->print_cr("all fields:"); 353678064Sume for (AllFieldStream fs(InstanceKlass::cast(klass_oop)); !fs.done(); fs.next()) { 353778064Sume tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int()); 353878064Sume } 353978064Sume#endif //PRODUCT 354078064Sume fatal("Invalid layout of preloaded class"); 354178064Sume return -1; 354278064Sume} 354378064Sume 354478064Sumevoid javaClasses_init() { 354578064Sume JavaClasses::compute_offsets(); 354678064Sume JavaClasses::check_offsets(); 354778064Sume FilteredFieldsMap::initialize(); // must be done after computing offsets. 354878064Sume} 354978064Sume