< prev index next >
hotspot/src/share/vm/classfile/javaClasses.cpp
Print this page
*** 1313,1359 ****
}
// After this many redefines, the stack trace is unreliable.
const int MAX_VERSION = USHRT_MAX;
- // Helper backtrace functions to store bci|version together.
- static inline int merge_bci_and_version(int bci, int version) {
- // only store u2 for version, checking for overflow.
- if (version > USHRT_MAX || version < 0) version = MAX_VERSION;
- assert((jushort)bci == bci, "bci should be short");
- return build_int_from_shorts(version, bci);
- }
-
- static inline int bci_at(unsigned int merged) {
- return extract_high_short_from_int(merged);
- }
- static inline int version_at(unsigned int merged) {
- return extract_low_short_from_int(merged);
- }
-
static inline bool version_matches(Method* method, int version) {
assert(version < MAX_VERSION, "version is too big");
return method != NULL && (method->constants()->version() == version);
}
- static inline int get_line_number(Method* method, int bci) {
- int line_number = 0;
- if (method->is_native()) {
- // Negative value different from -1 below, enabling Java code in
- // class java.lang.StackTraceElement to distinguish "native" from
- // "no LineNumberTable". JDK tests for -2.
- line_number = -2;
- } else {
- // Returns -1 if no LineNumberTable, and otherwise actual line number
- line_number = method->line_number_from_bci(bci);
- if (line_number == -1 && ShowHiddenFrames) {
- line_number = bci + 1000000;
- }
- }
- return line_number;
- }
-
// This class provides a simple wrapper over the internal structure of
// exception backtrace to insulate users of the backtrace from needing
// to know what it looks like.
class BacktraceBuilder: public StackObj {
private:
--- 1313,1327 ----
*** 1471,1481 ****
expand(CHECK);
method = mhandle();
}
_methods->short_at_put(_index, method->orig_method_idnum());
! _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version()));
_cprefs->short_at_put(_index, method->name_index());
// We need to save the mirrors in the backtrace to keep the class
// from being unloaded while we still have this stack trace.
assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror");
--- 1439,1449 ----
expand(CHECK);
method = mhandle();
}
_methods->short_at_put(_index, method->orig_method_idnum());
! _bcis->int_at_put(_index, BackTrace::merge_bci_and_version(bci, method->constants()->version()));
_cprefs->short_at_put(_index, method->name_index());
// We need to save the mirrors in the backtrace to keep the class
// from being unloaded while we still have this stack trace.
assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror");
*** 1483,1505 ****
_index++;
}
};
- Symbol* get_source_file_name(InstanceKlass* holder, int version) {
- // Find the specific ik version that contains this source_file_name_index
- // via the previous versions list, but use the current version's
- // constant pool to look it up. The previous version's index has been
- // merged for the current constant pool.
- InstanceKlass* ik = holder->get_klass_version(version);
- // This version has been cleaned up.
- if (ik == NULL) return NULL;
- int source_file_name_index = ik->source_file_name_index();
- return (source_file_name_index == 0) ?
- (Symbol*)NULL : holder->constants()->symbol_at(source_file_name_index);
- }
-
// Print stack trace element to resource allocated buffer
char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
int method_id, int version, int bci, int cpref) {
// Get strings and string lengths
--- 1451,1460 ----
*** 1513,1523 ****
Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
char* method_name = sym->as_C_string();
buf_len += (int)strlen(method_name);
char* source_file_name = NULL;
! Symbol* source = get_source_file_name(holder, version);
if (source != NULL) {
source_file_name = source->as_C_string();
buf_len += (int)strlen(source_file_name);
}
--- 1468,1478 ----
Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
char* method_name = sym->as_C_string();
buf_len += (int)strlen(method_name);
char* source_file_name = NULL;
! Symbol* source = BackTrace::get_source_file_name(holder, version);
if (source != NULL) {
source_file_name = source->as_C_string();
buf_len += (int)strlen(source_file_name);
}
*** 1528,1538 ****
sprintf(buf, "\tat %s.%s", klass_name, method_name);
if (!version_matches(method, version)) {
strcat(buf, "(Redefined)");
} else {
! int line_number = get_line_number(method, bci);
if (line_number == -2) {
strcat(buf, "(Native Method)");
} else {
if (source_file_name != NULL && (line_number != -1)) {
// Sourcename and linenumber
--- 1483,1493 ----
sprintf(buf, "\tat %s.%s", klass_name, method_name);
if (!version_matches(method, version)) {
strcat(buf, "(Redefined)");
} else {
! int line_number = BackTrace::get_line_number(method, bci);
if (line_number == -2) {
strcat(buf, "(Native Method)");
} else {
if (source_file_name != NULL && (line_number != -1)) {
// Sourcename and linenumber
*** 1597,1608 ****
for (int index = 0; index < length; index++) {
Handle mirror(THREAD, mirrors->obj_at(index));
// NULL mirror means end of stack trace
if (mirror.is_null()) goto handle_cause;
int method = methods->short_at(index);
! int version = version_at(bcis->int_at(index));
! int bci = bci_at(bcis->int_at(index));
int cpref = cprefs->short_at(index);
print_stack_element(st, mirror, method, version, bci, cpref);
}
result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
}
--- 1552,1563 ----
for (int index = 0; index < length; index++) {
Handle mirror(THREAD, mirrors->obj_at(index));
// NULL mirror means end of stack trace
if (mirror.is_null()) goto handle_cause;
int method = methods->short_at(index);
! int version = BackTrace::version_at(bcis->int_at(index));
! int bci = BackTrace::bci_at(bcis->int_at(index));
int cpref = cprefs->short_at(index);
print_stack_element(st, mirror, method, version, bci, cpref);
}
result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
}
*** 1885,1896 ****
typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk);
assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
int method = methods->short_at(chunk_index);
! int version = version_at(bcis->int_at(chunk_index));
! int bci = bci_at(bcis->int_at(chunk_index));
int cpref = cprefs->short_at(chunk_index);
Handle mirror(THREAD, mirrors->obj_at(chunk_index));
// Chunk can be partial full
if (mirror.is_null()) {
--- 1840,1851 ----
typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk);
assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
int method = methods->short_at(chunk_index);
! int version = BackTrace::version_at(bcis->int_at(chunk_index));
! int bci = BackTrace::bci_at(bcis->int_at(chunk_index));
int cpref = cprefs->short_at(chunk_index);
Handle mirror(THREAD, mirrors->obj_at(chunk_index));
// Chunk can be partial full
if (mirror.is_null()) {
*** 1909,1959 ****
if (ik->should_be_initialized()) {
ik->initialize(CHECK_0);
}
Handle element = ik->allocate_instance_handle(CHECK_0);
// Fill in class name
ResourceMark rm(THREAD);
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
const char* str = holder->external_name();
! oop classname = StringTable::intern((char*) str, CHECK_0);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
Method* method = holder->method_with_orig_idnum(method_id, version);
// The method can be NULL if the requested class version is gone
Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
// Fill in method name
! oop methodname = StringTable::intern(sym, CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
if (!version_matches(method, version)) {
// The method was redefined, accurate line number information isn't available
java_lang_StackTraceElement::set_fileName(element(), NULL);
java_lang_StackTraceElement::set_lineNumber(element(), -1);
} else {
// Fill in source file name and line number.
! Symbol* source = get_source_file_name(holder, version);
if (ShowHiddenFrames && source == NULL)
source = vmSymbols::unknown_class_name();
! oop filename = StringTable::intern(source, CHECK_0);
java_lang_StackTraceElement::set_fileName(element(), filename);
! int line_number = get_line_number(method, bci);
java_lang_StackTraceElement::set_lineNumber(element(), line_number);
}
- return element();
}
oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
Handle mirror (THREAD, method->method_holder()->java_mirror());
int method_id = method->orig_method_idnum();
int cpref = method->name_index();
return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
}
void java_lang_reflect_AccessibleObject::compute_offsets() {
Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature());
}
--- 1864,2019 ----
if (ik->should_be_initialized()) {
ik->initialize(CHECK_0);
}
Handle element = ik->allocate_instance_handle(CHECK_0);
+ java_lang_StackTraceElement::init(element, mirror, method_id, version, bci, cpref, CHECK_0);
+ return element();
+ }
+
+ void java_lang_StackTraceElement::init(Handle element, Handle mirror, int method_id,
+ int version, int bci, int cpref, TRAPS) {
+
// Fill in class name
ResourceMark rm(THREAD);
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
const char* str = holder->external_name();
! oop classname = StringTable::intern((char*) str, CHECK);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
Method* method = holder->method_with_orig_idnum(method_id, version);
// The method can be NULL if the requested class version is gone
Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
// Fill in method name
! oop methodname = StringTable::intern(sym, CHECK);
java_lang_StackTraceElement::set_methodName(element(), methodname);
if (!version_matches(method, version)) {
// The method was redefined, accurate line number information isn't available
java_lang_StackTraceElement::set_fileName(element(), NULL);
java_lang_StackTraceElement::set_lineNumber(element(), -1);
} else {
// Fill in source file name and line number.
! Symbol* source = BackTrace::get_source_file_name(holder, version);
if (ShowHiddenFrames && source == NULL)
source = vmSymbols::unknown_class_name();
! oop filename = StringTable::intern(source, CHECK);
java_lang_StackTraceElement::set_fileName(element(), filename);
! int line_number = BackTrace::get_line_number(method, bci);
java_lang_StackTraceElement::set_lineNumber(element(), line_number);
}
}
oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
Handle mirror (THREAD, method->method_holder()->java_mirror());
int method_id = method->orig_method_idnum();
int cpref = method->name_index();
return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD);
}
+ int java_lang_StackFrameInfo::bci(oop stackFrame) {
+ int value = stackFrame->int_field(bci_offset);
+ if (MemberNameInStackFrame) {
+ return value;
+ } else {
+ return BackTrace::bci_at(value);
+ }
+ }
+
+ oop java_lang_StackFrameInfo::member_name(oop stackFrame) {
+ return stackFrame->obj_field(memberName_offset);
+ }
+
+ Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
+ if (MemberNameInStackFrame) {
+ Handle mname(THREAD, stackFrame->obj_field(memberName_offset));
+ Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(mname());
+ // we should expand MemberName::name when Throwable uses StackTrace
+ // MethodHandles::expand_MemberName(mname, MethodHandles::_suppress_defc|MethodHandles::_suppress_type, CHECK_NULL);
+ return method;
+ } else {
+ int bci_version = stackFrame->int_field(bci_offset);
+ int version = BackTrace::version_at(bci_version);
+ int mid_cpref = stackFrame->int_field(mid_offset);
+ int mid = BackTrace::mid_at(mid_cpref);
+ int cpref = BackTrace::cpref_at(mid_cpref);
+ return holder->method_with_orig_idnum(mid, version);
+ }
+ }
+
+ Symbol* java_lang_StackFrameInfo::get_file_name(Handle stackFrame, InstanceKlass* holder) {
+ if (MemberNameInStackFrame) {
+ return holder->source_file_name();
+ } else {
+ int bci_version = stackFrame->int_field(bci_offset);
+ int version = BackTrace::version_at(bci_version);
+ Symbol* source = BackTrace::get_source_file_name(holder, version);
+ if (source == NULL) {
+ source = vmSymbols::unknown_class_name();
+ }
+ return source;
+ }
+ }
+
+ void java_lang_StackFrameInfo::fill_methodInfo(Handle stackFrame, TRAPS) {
+ ResourceMark rm(THREAD);
+ oop k = stackFrame->obj_field(declaringClass_offset);
+ InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k));
+ Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK);
+ int bci = java_lang_StackFrameInfo::bci(stackFrame());
+
+ // The method can be NULL if the requested class version is gone
+ Symbol* sym = (method != NULL) ? method->name() : NULL;
+ if (MemberNameInStackFrame) {
+ assert(sym != NULL, "MemberName must have method name");
+ } else {
+ bci = BackTrace::bci_at(bci); // merged with version
+ // The method can be NULL if the requested class version is gone
+ if (sym == NULL) {
+ int mid_cpref = stackFrame->int_field(mid_offset);
+ int cpref = BackTrace::cpref_at(mid_cpref);
+ sym = holder->constants()->symbol_at(cpref);
+ }
+ }
+
+ // set method name
+ oop methodname = StringTable::intern(sym, CHECK);
+ java_lang_StackFrameInfo::set_methodName(stackFrame(), methodname);
+
+ // set file name and line number
+ Symbol* source = get_file_name(stackFrame, holder);
+ if (source != NULL) {
+ oop filename = StringTable::intern(source, CHECK);
+ java_lang_StackFrameInfo::set_fileName(stackFrame(), filename);
+ }
+ if (method != NULL) {
+ int line_number = BackTrace::get_line_number(method, bci);
+ java_lang_StackFrameInfo::set_lineNumber(stackFrame(), line_number);
+ }
+ }
+
+ void java_lang_StackFrameInfo::compute_offsets() {
+ Klass* k = SystemDictionary::StackFrameInfo_klass();
+ compute_offset(declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature());
+ compute_offset(memberName_offset, k, vmSymbols::memberName_name(), vmSymbols::object_signature());
+ compute_offset(mid_offset, k, vmSymbols::mid_name(), vmSymbols::int_signature());
+ compute_offset(bci_offset, k, vmSymbols::bci_name(), vmSymbols::int_signature());
+ compute_offset(methodName_offset, k, vmSymbols::methodName_name(), vmSymbols::string_signature());
+ compute_offset(fileName_offset, k, vmSymbols::fileName_name(), vmSymbols::string_signature());
+ compute_offset(lineNumber_offset, k, vmSymbols::lineNumber_name(), vmSymbols::int_signature());
+ }
+
+ void java_lang_LiveStackFrameInfo::compute_offsets() {
+ Klass* k = SystemDictionary::LiveStackFrameInfo_klass();
+ compute_offset(monitors_offset, k, vmSymbols::monitors_name(), vmSymbols::object_array_signature());
+ compute_offset(locals_offset, k, vmSymbols::locals_name(), vmSymbols::object_array_signature());
+ compute_offset(operands_offset, k, vmSymbols::operands_name(), vmSymbols::object_array_signature());
+ }
+
void java_lang_reflect_AccessibleObject::compute_offsets() {
Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
compute_offset(override_offset, k, vmSymbols::override_name(), vmSymbols::bool_signature());
}
*** 3266,3275 ****
--- 3326,3345 ----
int java_lang_System::static_security_offset;
int java_lang_StackTraceElement::declaringClass_offset;
int java_lang_StackTraceElement::methodName_offset;
int java_lang_StackTraceElement::fileName_offset;
int java_lang_StackTraceElement::lineNumber_offset;
+ int java_lang_StackFrameInfo::declaringClass_offset;
+ int java_lang_StackFrameInfo::memberName_offset;
+ int java_lang_StackFrameInfo::mid_offset;
+ int java_lang_StackFrameInfo::bci_offset;
+ int java_lang_StackFrameInfo::methodName_offset;
+ int java_lang_StackFrameInfo::fileName_offset;
+ int java_lang_StackFrameInfo::lineNumber_offset;
+ int java_lang_LiveStackFrameInfo::monitors_offset;
+ int java_lang_LiveStackFrameInfo::locals_offset;
+ int java_lang_LiveStackFrameInfo::operands_offset;
int java_lang_AssertionStatusDirectives::classes_offset;
int java_lang_AssertionStatusDirectives::classEnabled_offset;
int java_lang_AssertionStatusDirectives::packages_offset;
int java_lang_AssertionStatusDirectives::packageEnabled_offset;
int java_lang_AssertionStatusDirectives::deflt_offset;
*** 3295,3304 ****
--- 3365,3409 ----
void java_lang_StackTraceElement::set_lineNumber(oop element, int value) {
element->int_field_put(lineNumber_offset, value);
}
+ // Support for java_lang_StackFrameInfo
+ void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) {
+ element->obj_field_put(declaringClass_offset, value);
+ }
+
+ void java_lang_StackFrameInfo::set_mid(oop element, int value) {
+ element->int_field_put(mid_offset, value);
+ }
+ void java_lang_StackFrameInfo::set_bci(oop element, int value) {
+ element->int_field_put(bci_offset, value);
+ }
+
+ void java_lang_StackFrameInfo::set_fileName(oop element, oop value) {
+ element->obj_field_put(fileName_offset, value);
+ }
+
+ void java_lang_StackFrameInfo::set_methodName(oop element, oop value) {
+ element->obj_field_put(methodName_offset, value);
+ }
+
+ void java_lang_StackFrameInfo::set_lineNumber(oop element, int value) {
+ element->int_field_put(lineNumber_offset, value);
+ }
+
+ void java_lang_LiveStackFrameInfo::set_monitors(oop element, oop value) {
+ element->obj_field_put(monitors_offset, value);
+ }
+
+ void java_lang_LiveStackFrameInfo::set_locals(oop element, oop value) {
+ element->obj_field_put(locals_offset, value);
+ }
+
+ void java_lang_LiveStackFrameInfo::set_operands(oop element, oop value) {
+ element->obj_field_put(operands_offset, value);
+ }
// Support for java Assertions - java_lang_AssertionStatusDirectives.
void java_lang_AssertionStatusDirectives::set_classes(oop o, oop val) {
o->obj_field_put(classes_offset, val);
*** 3428,3437 ****
--- 3533,3544 ----
java_lang_reflect_Field::compute_offsets();
java_nio_Buffer::compute_offsets();
sun_reflect_ConstantPool::compute_offsets();
sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
java_lang_reflect_Parameter::compute_offsets();
+ java_lang_StackFrameInfo::compute_offsets();
+ java_lang_LiveStackFrameInfo::compute_offsets();
// generated interpreter code wants to know about the offsets we just computed:
AbstractAssembler::update_delayed_values();
}
< prev index next >