< 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 >