/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "classfile/altHashing.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/debugInfo.hpp"
#include "code/pcDesc.hpp"
#include "compiler/compilerOracle.hpp"
#include "interpreter/interpreter.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.inline.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klassOop.hpp"
#include "oops/methodOop.hpp"
#include "oops/symbol.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/vframe.hpp"
#include "utilities/preserveException.hpp"
#ifdef TARGET_OS_FAMILY_linux
# include "thread_linux.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_solaris
# include "thread_solaris.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_windows
# include "thread_windows.inline.hpp"
#endif
#ifdef TARGET_OS_FAMILY_bsd
# include "thread_bsd.inline.hpp"
#endif
{ SystemDictionary::WK_KLASS_ENUM_NAME(klass), vmSymbols::VM_SYMBOL_ENUM_NAME(name##_name), vmSymbols::VM_SYMBOL_ENUM_NAME(signature), may_be_java },
};
}
*field_count = 0;
// Only well known classes can inject fields
return NULL;
}
int count = 0;
count++; \
}
if (start != -1) {
*field_count = count;
return _injected_fields + start;
}
return NULL;
}
bool allow_super = false) {
if (allow_super)
else
}
// Helpful routine for computing field offsets at run time rather than hardcoding them
static void
bool allow_super = false) {
#ifndef PRODUCT
tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
}
#endif //PRODUCT
fatal("Invalid layout of preloaded class");
}
}
// Same as above but for "optional" offsets that might not be present in certain JDK versions
static void
bool allow_super = false) {
}
}
initialized = true;
}
// Create the String object first, so there's a chance that the String
// and the char array it points to end up in the same cache line.
if (tenured) {
} else {
}
// Create the char array. The String object must be handlized here
// because GC can happen as a result of the allocation attempt.
if (tenured) {
} else {
}
// Point the String at the char array
// No need to zero the offset, allocation zero'ed the entire String object
//set_offset(obj, 0);
return h_obj;
}
Handle java_lang_String::basic_create_from_unicode(jchar* unicode, int length, bool tenured, TRAPS) {
}
return h_obj;
}
}
}
return h_obj();
}
return Handle();
}
if (length > 0) {
}
return h_obj;
}
return h_obj();
}
if (length > 0) {
}
return h_obj;
}
// Converts a C string to a Java String based on current encoding
if (_to_java_string_fn == NULL) {
_to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform"));
if (_to_java_string_fn == NULL) {
fatal("NewStringPlatform missing");
}
}
}
}
// Converts a Java String to a native C string that can be used for
// native OS calls.
if (_to_platform_string_fn == NULL) {
_to_platform_string_fn = CAST_TO_FN_PTR(to_platform_string_fn_t, os::dll_lookup(lib_handle, "GetStringPlatformChars"));
if (_to_platform_string_fn == NULL) {
fatal("GetStringPlatformChars missing");
}
}
char *native_platform_string;
bool is_copy;
}
return native_platform_string;
}
Handle java_lang_String::char_converter(Handle java_string, jchar from_char, jchar to_char, TRAPS) {
// Typical usage is to convert all '/' to '.' in string.
// First check if any from_char exist
break;
}
}
// No from_char, so do not copy.
return java_string;
}
// Create new UNICODE buffer. Must handlize value because GC
// may happen during String and char array creation.
// Copy contents
if (c == from_char) {
c = to_char;
}
}
return string;
}
}
return result;
}
// Zero length string will hash to zero with String.toHash() function.
if (length == 0) return 0;
}
// Zero length string doesn't hash necessarily hash to zero.
if (length == 0) {
}
}
return sym;
}
}
}
}
}
}
"must be java_string");
return false;
}
for (int i = 0; i < len; i++) {
return false;
}
}
return true;
}
// This can happen if, e.g., printing a String
// object before its initializer has been called
} else {
}
}
}
if (fd->has_initial_value()) {
switch (t) {
case T_BYTE:
break;
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_LONG:
break;
case T_OBJECT:
{
#ifdef ASSERT
#endif
}
break;
default:
"Illegal ConstantValue attribute in class file");
}
}
}
if (k->oop_is_instance()) {
// During bootstrap, java.lang.Class wasn't loaded so static field
// offsets were computed without the size added it. Go back and
// update all the static field offsets to included the size.
}
}
}
create_mirror(k, CHECK);
}
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
// the cached flags after the class file is parsed, but before the
// class is put into the system dictionary.
// Allocate mirror (java.lang.Class instance)
Handle mirror = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
// It might also have a component mirror. This mirror must already exist.
if (k->oop_is_javaArray()) {
if (k->oop_is_typeArray()) {
} else if (k->oop_is_objArray()) {
if (element_klass != NULL
}
// else some object array internal to the VM, like systemObjArrayKlassObj
}
if (comp_mirror.not_null()) {
// Two-way link between the array klass and its component mirror:
}
} else if (k->oop_is_instance()) {
// Initialize static fields
}
return mirror();
} else {
return NULL;
}
}
}
}
}
}
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
oop java_class = instanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance((oop)NULL, CHECK_0);
}
#ifdef ASSERT
assert(java_lang_Class::static_oop_field_count(java_class) == 0, "should have been zeroed by allocation");
#endif
return java_class;
}
//%note memory_2
return k;
}
}
bool is_instance = false;
if (is_primitive(java_class)) {
} else {
}
return;
}
}
if (is_primitive(java_class)) {
// Because this can create a new symbol, the caller has to decrement
// the refcount, so make adjustment here and below for symbols returned
// that are not created or incremented due to a successful lookup.
} else {
} else {
if (!intern_if_not_found) {
} else {
}
}
}
return name;
}
return k;
}
}
return methodOop(constructor);
}
}
// should assert:
//assert(java_lang_Class::is_instance(java_class), "must be a Class object");
return k == NULL;
}
// Note: create_basic_type_mirror above initializes ak to a non-null value.
} else {
}
return type;
}
if (is_primitive(java_class)) {
if (reference_klass != NULL)
(*reference_klass) = NULL;
return primitive_type(java_class);
} else {
if (reference_klass != NULL)
return T_OBJECT;
}
}
return mirror;
}
offsets_computed = true;
// The classRedefinedCount field is only present starting in 1.5,
// so don't go fatal.
}
if (!JDK_Version::is_gte_jdk15x_version()
|| classRedefinedCount_offset == -1) {
// The classRedefinedCount field is only present starting in 1.5.
// If we don't have an offset for it then just return -1 as a marker.
return -1;
}
}
if (!JDK_Version::is_gte_jdk15x_version()
|| classRedefinedCount_offset == -1) {
// The classRedefinedCount field is only present starting in 1.5.
// If we don't have an offset for it then nothing to set.
return;
}
}
// Note: JDK1.1 and before had a privateInfo_offset field which was used for the
// platform thread structure, and a eetop offset which was used for thread
// local storage (and unused by the HotSpot VM). In JDK1.2 the two structures
// merged, so in the HotSpot VM we just use the eetop field for the thread
// instead of the privateInfo_offset.
//
// Note: The stackSize field is only present starting in 1.4.
compute_offset(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), vmSymbols::classloader_signature());
compute_offset(_inheritedAccessControlContext_offset, k, vmSymbols::inheritedAccessControlContext_name(), vmSymbols::accesscontrolcontext_signature());
// The stackSize field is only present starting in 1.4, so don't go fatal.
compute_optional_offset(_stackSize_offset, k, vmSymbols::stackSize_name(), vmSymbols::long_signature());
// The tid and thread_status fields are only present starting in 1.5, so don't go fatal.
compute_optional_offset(_thread_status_offset, k, vmSymbols::thread_status_name(), vmSymbols::int_signature());
// The parkBlocker field is only present starting in 1.6, so don't go fatal.
compute_optional_offset(_park_blocker_offset, k, vmSymbols::park_blocker_name(), vmSymbols::object_signature());
vmSymbols::long_signature());
}
}
}
assert(name == NULL || (name->is_typeArray() && typeArrayKlass::cast(name->klass())->element_type() == T_CHAR), "just checking");
return typeArrayOop(name);
}
}
}
}
}
}
// We never have reason to turn the stillborn bit off
}
}
}
}
}
}
// The stackSize field is only present starting in 1.4
if (_stackSize_offset > 0) {
} else {
return 0;
}
}
// Write the thread status value to threadStatus field in java.lang.Thread java class.
// The threadStatus is only present starting in 1.5
if (_thread_status_offset > 0) {
}
}
// Read thread status value from threadStatus field in java.lang.Thread java class.
"Java Thread is not running in vm");
// The threadStatus is only present starting in 1.5
if (_thread_status_offset > 0) {
} else {
// All we can easily figure out is if it is alive, but that is
// enough info for a valid unknown status.
// These aren't restricted to valid set ThreadStatus values, so
// use JVMTI values and cast.
// the thread hasn't run yet or is in the process of exiting
return NEW;
}
}
}
// The thread ID field is only present starting in 1.5
if (_tid_offset > 0) {
} else {
return 0;
}
}
_park_blocker_offset != 0, "Must support parkBlocker field");
if (_park_blocker_offset > 0) {
}
return NULL;
}
if (_park_event_offset > 0) {
}
return 0;
}
if (_park_event_offset > 0) {
return true;
}
return false;
}
assert(JDK_Version::is_gte_jdk15x_version() && _thread_status_offset != 0, "Must have thread status");
ThreadStatus status = (java_lang_Thread::ThreadStatus)java_thread->int_field(_thread_status_offset);
switch (status) {
case NEW : return "NEW";
case RUNNABLE : return "RUNNABLE";
case SLEEPING : return "TIMED_WAITING (sleeping)";
case IN_OBJECT_WAIT : return "WAITING (on object monitor)";
case IN_OBJECT_WAIT_TIMED : return "TIMED_WAITING (on object monitor)";
case PARKED : return "WAITING (parking)";
case PARKED_TIMED : return "TIMED_WAITING (parking)";
case BLOCKED_ON_MONITOR_ENTER : return "BLOCKED (on object monitor)";
case TERMINATED : return "TERMINATED";
default : return "UNKNOWN";
};
}
}
// ("name as oop" accessor is not necessary)
// ThreadGroup.name can be null
}
}
return objArrayOop(threads);
}
}
assert(groups == NULL || groups->is_objArray(), "just checking"); // Todo: Add better type checking code
return objArrayOop(groups);
}
}
}
}
}
compute_offset(_groups_offset, k, vmSymbols::groups_name(), vmSymbols::threadgroup_array_signature());
compute_offset(_vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature());
}
if (UseCompressedOops) {
} else {
}
}
}
}
}
}
}
}
}
}
}
}
}
// Print stack trace element to resource allocated buffer
// Get strings and string lengths
char* source_file_name;
} else {
}
// Allocate temporary buffer with extra space for formatting and line number
// Print stack trace line in buffer
} else {
// Sourcename and linenumber
} else if (source_file_name != NULL) {
// Just sourcename
} else {
// Neither soucename and linenumber
}
}
}
return buf;
}
}
}
} else {
if (!HAS_PENDING_EXCEPTION) {
arg,
THREAD);
}
// Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
}
}
return "\t<<no stack trace available>>";
}
// Currently used only for exceptions occurring during startup
while (h_throwable.not_null()) {
return;
}
return;
}
}
}
{
THREAD);
// Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
if (HAS_PENDING_EXCEPTION) {
h_throwable = Handle();
} else {
if (h_throwable.not_null()) {
}
}
}
}
}
// Note: this is no longer used in Merlin, but we support it for compatibility.
return;
}
return;
}
}
}
}
// This class provides a simple wrapper over the internal structure of
// exception backtrace to insulate users of the backtrace from needing
// to know what it looks like.
private:
int _index;
public:
enum {
};
// constructor for new backtrace
_backtrace = _head;
_index = 0;
}
}
_methods = new_methods();
_index = 0;
}
return _backtrace();
}
// Smear the -1 bci to 0 since the array only holds unsigned
// shorts. The later line number lookup would just smear the -1
// to a 0 even if it could be recorded.
if (_index >= trace_chunk_size) {
}
_index++;
}
}
}
};
if (!StackTraceInThrowable) return;
// Start out by clearing the backtrace for this object, in case the VM
// runs out of memory while allocating the stack trace
if (JDK_Version::is_gte_jdk14x_version()) {
// New since 1.4, clear lazily constructed Java level stacktrace if
// refilling occurs
// This is unnecessary in 1.7+ but harmless
}
// If there is no Java frame just return the method that was being called
// with bci 0
if (!thread->has_last_Java_frame()) {
}
return;
}
// Instead of using vframe directly, this version of fill_in_stack_trace
// basically handles everything by hand. This significantly improved the
// speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows.
// See bug 6333838 for more details.
// The "ASSERT" here is to verify this method generates the exactly same stack
// trace as utilizing vframe.
#ifdef ASSERT
#endif
int total_count = 0;
int decode_offset = 0;
bool skip_fillInStackTrace_check = false;
bool skip_throwableInit_check = false;
int bci = 0;
// Compiled java method case.
if (decode_offset != 0) {
} else {
if (fr.is_first_frame()) break;
if (fr.is_interpreted_frame()) {
} else {
// HMMM QQQ might be nice to have frame return nm as NULL if cb is non-NULL
// but non nmethod
continue;
}
bci = 0;
} else {
// if decode_offset is not equal to 0, it will execute the
// "compiled java method case" at the beginning of the loop.
continue;
}
}
}
#ifdef ASSERT
"Wrong stack trace");
// vframeStream::method isn't GC-safe so store off a copy
// of the methodOop in case we GC.
}
#endif
// the format of the stacktrace will be:
// - 1 or more fillInStackTrace frames for the exception class (skipped)
// - 0 or more <init> methods for the exception class (skipped)
// - rest of the stack
if (!skip_fillInStackTrace_check) {
continue;
}
else {
skip_fillInStackTrace_check = true; // gone past them all
}
}
if (!skip_throwableInit_check) {
// skip <init> methods of the exception class and superclasses
// This is simlar to classic VM.
continue;
} else {
// there are none or we've seen them all - either way stop checking
skip_throwableInit_check = true;
}
}
if (skip_hidden) continue;
}
total_count++;
}
// Put completed stack trace into throwable object
}
// No-op if stack trace is disabled
if (!StackTraceInThrowable) {
return;
}
// Disable stack traces for some preallocated out of memory errors
return;
}
// ignore exceptions thrown during stack trace filling
}
// Allocate stack trace - backtrace is created but not filled in
// No-op if stack trace is disabled
if (!StackTraceInThrowable) return;
// backtrace has space for one chunk (next is NULL)
}
// Fill in stack trace into preallocated backtrace (no GC)
// No-op if stack trace is disabled
if (!StackTraceInThrowable) return;
// Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init
// methods as preallocated errors aren't created by "java" code.
// fill in as much stack trace as possible
int chunk_count = 0;
// Add entry and smear the -1 bci to 0 since the array only holds
// unsigned shorts. The later line number lookup would just smear
// the -1 to a 0 even if it could be recorded.
chunk_count++;
// Bail-out for deep stacks
if (chunk_count >= max_chunks) break;
}
// For Java 7+ we support the Throwable immutability protocol defined for Java 7. This support
// was missing in 7u0 so in 7u0 there is a workaround in the Throwable class. That workaround
// can be removed in a JDK using this JVM version
if (JDK_Version::is_gte_jdk17x_version()) {
}
}
}
int depth = 0;
// Iterate over chunks and count full ones
while (true) {
}
// Count element in remaining partial chunk
depth++;
}
}
return depth;
}
}
if (index < 0) {
}
// Compute how many chunks to skip and index into actual chunk
skip_chunks--;
}
}
// Get method,bci from chunk
// Chunk can be partial full
}
return element;
}
// SystemDictionary::stackTraceElement_klass() will be null for pre-1.4 JDKs
// Allocate java.lang.StackTraceElement instance
if (ik->should_be_initialized()) {
}
// Fill in class name
// Fill in method name
// Fill in source file name
// File in source line number
int line_number;
// Negative value different from -1 below, enabling Java code in
// class java.lang.StackTraceElement to distinguish "native" from
// "no LineNumberTable".
line_number = -2;
} else {
// Returns -1 if no LineNumberTable, and otherwise actual line number
}
}
return element();
}
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature());
compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature());
// The generic signature and annotations fields are only present in 1.5
signature_offset = -1;
annotations_offset = -1;
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature());
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
// This class is eagerly initialized during VM initialization, since we keep a refence
// to one of the methods
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (signature_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (annotations_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (parameter_annotations_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (annotation_default_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
compute_offset(parameterTypes_offset, k, vmSymbols::parameterTypes_name(), vmSymbols::class_array_signature());
compute_offset(exceptionTypes_offset, k, vmSymbols::exceptionTypes_name(), vmSymbols::class_array_signature());
// The generic signature and annotations fields are only present in 1.5
signature_offset = -1;
annotations_offset = -1;
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature());
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
// Ensure it is initialized
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (signature_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (annotations_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (parameter_annotations_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
// The generic signature and annotations fields are only present in 1.5
signature_offset = -1;
annotations_offset = -1;
compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature());
compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature());
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
// Ensure it is initialized
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (signature_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
return (annotations_offset >= 0);
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
// This null test can be removed post beta
if (k != NULL) {
compute_offset(_cp_oop_offset, k, vmSymbols::constantPoolOop_name(), vmSymbols::object_signature());
}
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
// Ensure it is initialized
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");
}
// This null test can be removed post beta
if (k != NULL) {
}
}
instanceKlassHandle h (THREAD, k);
return h->allocate_instance(THREAD);
}
switch (type) {
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_BYTE:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_LONG:
break;
default:
return NULL;
}
return box;
}
return T_ILLEGAL;
return type;
}
switch (type) {
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_BYTE:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_LONG:
break;
default:
return T_ILLEGAL;
} // end switch
return type;
}
switch (type) {
case T_BOOLEAN:
break;
case T_CHAR:
break;
case T_FLOAT:
break;
case T_DOUBLE:
break;
case T_BYTE:
break;
case T_SHORT:
break;
case T_INT:
break;
case T_LONG:
break;
default:
return T_ILLEGAL;
} // end switch
return type;
}
switch (type) {
}
}
// Support for java_lang_ref_Reference
if (UseCompressedOops) {
} else {
}
}
// XXX This might not be HeapWord aligned, almost rather be char *.
}
if (UseCompressedOops) {
} else {
}
}
// Support for java_lang_ref_SoftReference
}
return *offset;
}
}
// Support for java_lang_invoke_MethodHandle
compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature());
compute_optional_offset(_form_offset, klass_oop, vmSymbols::form_name(), vmSymbols::java_lang_invoke_LambdaForm_signature());
if (_form_offset == 0) {
EnableInvokeDynamic = false;
}
}
}
}
}
compute_offset(_vmentry_offset, klass_oop, vmSymbols::vmentry_name(), vmSymbols::java_lang_invoke_MemberName_signature());
}
}
}
}
}
}
/// MemberName accessors
}
}
}
}
}
}
}
}
}
#ifdef ASSERT
// check the type of the vmtarget
MN_IS_FIELD)) {
case MN_IS_METHOD:
case MN_IS_CONSTRUCTOR:
break;
case MN_IS_FIELD:
break;
default:
}
}
#endif //ASSERT
}
}
}
}
// Support for java_lang_invoke_MethodType
if (k != NULL) {
}
}
}
}
if (!intern_if_not_found) {
} else {
}
return name;
}
return true;
return false;
return false;
return false;
}
return true;
}
}
}
}
}
int slots = 0;
for (int i = 0; i < count; i++) {
}
return slots;
}
}
// Support for java_lang_invoke_CallSite
if (!EnableInvokeDynamic) return;
if (k != NULL) {
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
}
}
// Support for java_security_AccessControlContext
if (!ik->find_local_field(vmSymbols::context_name(), vmSymbols::protectiondomain_signature(), &fd)) {
}
if (!ik->find_local_field(vmSymbols::privilegedContext_name(), vmSymbols::accesscontrolcontext_signature(), &fd)) {
}
}
// The offset may not be present for bootstrapping with older JDK.
}
}
assert(context.not_null() && context->klass() == SystemDictionary::AccessControlContext_klass(), "Invalid type");
}
oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) {
// Ensure klass is initialized
// Allocate result
oop result = instanceKlass::cast(SystemDictionary::AccessControlContext_klass())->allocate_instance(CHECK_0);
// Fill in values
// whitelist AccessControlContexts created by the JVM if present
if (_isAuthorized_offset != -1) {
}
return result;
}
// Support for java_lang_ClassLoader
offsets_computed = true;
// The field indicating parallelCapable (parallelLockMap) is only present starting in 7,
}
}
// This loop taken verbatim from ClassLoader.java:
do {
return true;
}
return false;
}
// For class loader classes, parallelCapable defined
// based on non-null field
// Written to by java.lang.ClassLoader, vm only reads this field, doesn't set it
if (!JDK_Version::is_gte_jdk17x_version()
|| parallelCapable_offset == -1) {
// Default for backward compatibility is false
return false;
}
}
// Fix for 4474172; see evaluation for more details
}
return false;
}
// See whether this is one of the class loaders associated with
// the generated bytecodes for reflection, and if so, "magically"
// delegate to its parent to prevent class loading from occurring
// in places where applications using reflection didn't expect it.
// This might be null in non-1.4 JDKs
}
}
return loader;
}
// Support for java_lang_System
}
}
}
if (UseCompressedOops) {
} else {
}
}
// Support for java_lang_StackTraceElement
}
}
}
}
// Support for java Assertions - java_lang_AssertionStatusDirectives.
}
}
}
}
}
// Support for intrinsification of java.nio.Buffer.checkIndex
return _limit_offset;
}
}
if (_owner_offset != 0) return;
}
}
// Compute hard-coded offsets
// Invoked before SystemDictionary::initialize, so pre-loaded classes
// are not available to determine the offset_of_static_fields.
const int x = heapOopSize;
// Throwable Class
java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header;
java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x;
// java_lang_boxing_object
java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong);
// java_lang_ref_Reference:
java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
java_lang_ref_Reference::discovered_offset = java_lang_ref_Reference::hc_discovered_offset * x + header;
java_lang_ref_Reference::static_pending_offset = java_lang_ref_Reference::hc_static_pending_offset * x;
// Artificial fields for java_lang_ref_Reference
// The first field is for the discovered field added in 1.4
// java_lang_ref_SoftReference Class
java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong);
// Don't multiply static fields because they are always in wordSize units
java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
// java_lang_ClassLoader
// java_lang_System
// java_lang_StackTraceElement
java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header;
java_lang_StackTraceElement::methodName_offset = java_lang_StackTraceElement::hc_methodName_offset * x + header;
java_lang_StackTraceElement::fileName_offset = java_lang_StackTraceElement::hc_fileName_offset * x + header;
java_lang_StackTraceElement::lineNumber_offset = java_lang_StackTraceElement::hc_lineNumber_offset * x + header;
java_lang_AssertionStatusDirectives::classes_offset = java_lang_AssertionStatusDirectives::hc_classes_offset * x + header;
java_lang_AssertionStatusDirectives::classEnabled_offset = java_lang_AssertionStatusDirectives::hc_classEnabled_offset * x + header;
java_lang_AssertionStatusDirectives::packages_offset = java_lang_AssertionStatusDirectives::hc_packages_offset * x + header;
java_lang_AssertionStatusDirectives::packageEnabled_offset = java_lang_AssertionStatusDirectives::hc_packageEnabled_offset * x + header;
java_lang_AssertionStatusDirectives::deflt_offset = java_lang_AssertionStatusDirectives::hc_deflt_offset * x + header;
}
// Compute non-hard-coded field offsets of all the classes in this file
// java_lang_Class::compute_offsets was called earlier in bootstrap
if (EnableInvokeDynamic) {
}
// Initialize reflection classes. The layouts of these classes
// changed with the new reflection implementation in JDK 1.4, and
// since the Universe doesn't know what JDK version it is until this
// point we defer computation of these offsets until now.
if (JDK_Version::is_gte_jdk14x_version()) {
}
if (JDK_Version::is_gte_jdk15x_version()) {
}
// generated interpreter code wants to know about the offsets we just computed:
}
#ifndef PRODUCT
// These functions exist to assert the validity of hard-coded field offsets to guard
// against changes in the class files
bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
return false;
}
return false;
}
return true;
} else {
return false;
}
}
bool JavaClasses::check_static_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
return false;
}
return false;
}
return true;
} else {
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());
return false;
}
}
bool JavaClasses::check_constant(const char *klass_name, int hardcoded_constant, const char *field_name, const char* field_sig) {
return false;
}
return false;
}
return false;
}
if (field_value == hardcoded_constant) {
return true;
} else {
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);
return false;
}
}
// Check the hard-coded field offsets of all the classes in this file
bool valid = true;
valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig)
valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
// java.lang.String
if (java_lang_String::has_offset_field()) {
}
if (java_lang_String::has_hash_field()) {
}
// java.lang.Class
// Fake fields
// CHECK_OFFSET("java/lang/Class", java_lang_Class, resolved_constructor); // %%% this needs to be checked
// java.lang.Throwable
CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;");
// Boxed primitive objects (java_lang_boxing_object)
// java.lang.ClassLoader
// java.lang.System
// java.lang.StackTraceElement
CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, declaringClass, "Ljava/lang/String;");
CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, methodName, "Ljava/lang/String;");
CHECK_OFFSET("java/lang/StackTraceElement", java_lang_StackTraceElement, fileName, "Ljava/lang/String;");
// java.lang.ref.Reference
CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, queue, "Ljava/lang/ref/ReferenceQueue;");
CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, next, "Ljava/lang/ref/Reference;");
// Fake field
//CHECK_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, discovered, "Ljava/lang/ref/Reference;");
CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, lock, "Ljava/lang/ref/Reference$Lock;");
CHECK_STATIC_OFFSET("java/lang/ref/Reference", java_lang_ref_Reference, pending, "Ljava/lang/ref/Reference;");
// java.lang.ref.SoftReference
// java.lang.AssertionStatusDirectives
//
// The CheckAssertionStatusDirectives boolean can be removed from here and
// globals.hpp after the AssertionStatusDirectives class has been integrated
// into merlin "for some time." Without it, the vm will fail with early
// merlin builds.
}
}
#endif // PRODUCT
// Only look at injected fields
continue;
}
}
}
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)" : "");
#ifndef PRODUCT
tty->print_cr(" name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
}
#endif //PRODUCT
fatal("Invalid layout of preloaded class");
return -1;
}
void javaClasses_init() {
}