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