512 assert(result_length >= length + 1, "must not be shorter"); |
512 assert(result_length >= length + 1, "must not be shorter"); |
513 assert(result_length == (int)strlen(result) + 1, "must match"); |
513 assert(result_length == (int)strlen(result) + 1, "must match"); |
514 return result; |
514 return result; |
515 } |
515 } |
516 |
516 |
517 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { |
517 Symbol* java_lang_String::as_symbol(oop java_string, TRAPS) { |
518 oop obj = java_string(); |
518 typeArrayOop value = java_lang_String::value(java_string); |
519 typeArrayOop value = java_lang_String::value(obj); |
519 int length = java_lang_String::length(java_string); |
520 int length = java_lang_String::length(obj); |
520 bool is_latin1 = java_lang_String::is_latin1(java_string); |
521 bool is_latin1 = java_lang_String::is_latin1(obj); |
|
522 if (!is_latin1) { |
521 if (!is_latin1) { |
523 jchar* base = (length == 0) ? NULL : value->char_at_addr(0); |
522 jchar* base = (length == 0) ? NULL : value->char_at_addr(0); |
524 Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD); |
523 Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD); |
525 return sym; |
524 return sym; |
526 } else { |
525 } else { |
751 fs.set_offset(real_offset); |
750 fs.set_offset(real_offset); |
752 } |
751 } |
753 } |
752 } |
754 } |
753 } |
755 } |
754 } |
756 create_mirror(k, Handle(NULL), Handle(NULL), Handle(NULL), CHECK); |
755 create_mirror(k, Handle(), Handle(), Handle(), CHECK); |
757 } |
756 } |
758 |
757 |
759 void java_lang_Class::initialize_mirror_fields(KlassHandle k, |
758 void java_lang_Class::initialize_mirror_fields(KlassHandle k, |
760 Handle mirror, |
759 Handle mirror, |
761 Handle protection_domain, |
760 Handle protection_domain, |
826 k->set_modifier_flags(computed_modifiers); |
825 k->set_modifier_flags(computed_modifiers); |
827 // Class_klass has to be loaded because it is used to allocate |
826 // Class_klass has to be loaded because it is used to allocate |
828 // the mirror. |
827 // the mirror. |
829 if (SystemDictionary::Class_klass_loaded()) { |
828 if (SystemDictionary::Class_klass_loaded()) { |
830 // Allocate mirror (java.lang.Class instance) |
829 // Allocate mirror (java.lang.Class instance) |
831 Handle mirror = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); |
830 oop mirror_oop = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK); |
|
831 Handle mirror(THREAD, mirror_oop); |
832 |
832 |
833 // Setup indirection from mirror->klass |
833 // Setup indirection from mirror->klass |
834 if (!k.is_null()) { |
834 if (!k.is_null()) { |
835 java_lang_Class::set_klass(mirror(), k()); |
835 java_lang_Class::set_klass(mirror(), k()); |
836 } |
836 } |
840 |
840 |
841 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); |
841 java_lang_Class::set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror())); |
842 |
842 |
843 // It might also have a component mirror. This mirror must already exist. |
843 // It might also have a component mirror. This mirror must already exist. |
844 if (k->is_array_klass()) { |
844 if (k->is_array_klass()) { |
845 Handle comp_mirror; |
845 oop comp_mirror; |
846 if (k->is_typeArray_klass()) { |
846 if (k->is_typeArray_klass()) { |
847 BasicType type = TypeArrayKlass::cast(k())->element_type(); |
847 BasicType type = TypeArrayKlass::cast(k())->element_type(); |
848 comp_mirror = Universe::java_mirror(type); |
848 comp_mirror = Universe::java_mirror(type); |
849 } else { |
849 } else { |
850 assert(k->is_objArray_klass(), "Must be"); |
850 assert(k->is_objArray_klass(), "Must be"); |
851 Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); |
851 Klass* element_klass = ObjArrayKlass::cast(k())->element_klass(); |
852 assert(element_klass != NULL, "Must have an element klass"); |
852 assert(element_klass != NULL, "Must have an element klass"); |
853 comp_mirror = element_klass->java_mirror(); |
853 comp_mirror = element_klass->java_mirror(); |
854 } |
854 } |
855 assert(comp_mirror.not_null(), "must have a mirror"); |
855 assert(comp_mirror != NULL, "must have a mirror"); |
856 |
856 |
857 // Two-way link between the array klass and its component mirror: |
857 // Two-way link between the array klass and its component mirror: |
858 // (array_klass) k -> mirror -> component_mirror -> array_klass -> k |
858 // (array_klass) k -> mirror -> component_mirror -> array_klass -> k |
859 set_component_mirror(mirror(), comp_mirror()); |
859 set_component_mirror(mirror(), comp_mirror); |
860 set_array_klass(comp_mirror(), k()); |
860 set_array_klass(comp_mirror, k()); |
861 } else { |
861 } else { |
862 assert(k->is_instance_klass(), "Must be"); |
862 assert(k->is_instance_klass(), "Must be"); |
863 |
863 |
864 initialize_mirror_fields(k, mirror, protection_domain, THREAD); |
864 initialize_mirror_fields(k, mirror, protection_domain, THREAD); |
865 if (HAS_PENDING_EXCEPTION) { |
865 if (HAS_PENDING_EXCEPTION) { |
1516 |
1516 |
1517 void java_lang_Throwable::set_depth(oop throwable, int value) { |
1517 void java_lang_Throwable::set_depth(oop throwable, int value) { |
1518 throwable->int_field_put(depth_offset, value); |
1518 throwable->int_field_put(depth_offset, value); |
1519 } |
1519 } |
1520 |
1520 |
1521 oop java_lang_Throwable::message(Handle throwable) { |
1521 oop java_lang_Throwable::message(oop throwable) { |
1522 return throwable->obj_field(detailMessage_offset); |
1522 return throwable->obj_field(detailMessage_offset); |
1523 } |
1523 } |
1524 |
1524 |
1525 |
1525 |
1526 // Return Symbol for detailed_message or NULL |
1526 // Return Symbol for detailed_message or NULL |
1545 void java_lang_Throwable::clear_stacktrace(oop throwable) { |
1545 void java_lang_Throwable::clear_stacktrace(oop throwable) { |
1546 set_stacktrace(throwable, NULL); |
1546 set_stacktrace(throwable, NULL); |
1547 } |
1547 } |
1548 |
1548 |
1549 |
1549 |
1550 void java_lang_Throwable::print(Handle throwable, outputStream* st) { |
1550 void java_lang_Throwable::print(oop throwable, outputStream* st) { |
1551 ResourceMark rm; |
1551 ResourceMark rm; |
1552 Klass* k = throwable->klass(); |
1552 Klass* k = throwable->klass(); |
1553 assert(k != NULL, "just checking"); |
1553 assert(k != NULL, "just checking"); |
1554 st->print("%s", k->external_name()); |
1554 st->print("%s", k->external_name()); |
1555 oop msg = message(throwable); |
1555 oop msg = message(throwable); |
1576 Handle _backtrace; |
1576 Handle _backtrace; |
1577 objArrayOop _head; |
1577 objArrayOop _head; |
1578 typeArrayOop _methods; |
1578 typeArrayOop _methods; |
1579 typeArrayOop _bcis; |
1579 typeArrayOop _bcis; |
1580 objArrayOop _mirrors; |
1580 objArrayOop _mirrors; |
1581 typeArrayOop _cprefs; // needed to insulate method name against redefinition |
1581 typeArrayOop _names; // needed to insulate method name against redefinition |
1582 int _index; |
1582 int _index; |
1583 NoSafepointVerifier _nsv; |
1583 NoSafepointVerifier _nsv; |
1584 |
1584 |
1585 enum { |
1585 enum { |
1586 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
1586 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
1587 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
1587 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
1588 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
1588 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
1589 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset, |
1589 trace_names_offset = java_lang_Throwable::trace_names_offset, |
1590 trace_next_offset = java_lang_Throwable::trace_next_offset, |
1590 trace_next_offset = java_lang_Throwable::trace_next_offset, |
1591 trace_size = java_lang_Throwable::trace_size, |
1591 trace_size = java_lang_Throwable::trace_size, |
1592 trace_chunk_size = java_lang_Throwable::trace_chunk_size |
1592 trace_chunk_size = java_lang_Throwable::trace_chunk_size |
1593 }; |
1593 }; |
1594 |
1594 |
1606 static objArrayOop get_mirrors(objArrayHandle chunk) { |
1606 static objArrayOop get_mirrors(objArrayHandle chunk) { |
1607 objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); |
1607 objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset)); |
1608 assert(mirrors != NULL, "mirror array should be initialized in backtrace"); |
1608 assert(mirrors != NULL, "mirror array should be initialized in backtrace"); |
1609 return mirrors; |
1609 return mirrors; |
1610 } |
1610 } |
1611 static typeArrayOop get_cprefs(objArrayHandle chunk) { |
1611 static typeArrayOop get_names(objArrayHandle chunk) { |
1612 typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset)); |
1612 typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset)); |
1613 assert(cprefs != NULL, "cprefs array should be initialized in backtrace"); |
1613 assert(names != NULL, "names array should be initialized in backtrace"); |
1614 return cprefs; |
1614 return names; |
1615 } |
1615 } |
1616 |
1616 |
1617 public: |
1617 public: |
1618 |
1618 |
1619 // constructor for new backtrace |
1619 // constructor for new backtrace |
1620 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) { |
1620 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _names(NULL) { |
1621 expand(CHECK); |
1621 expand(CHECK); |
1622 _backtrace = _head; |
1622 _backtrace = Handle(THREAD, _head); |
1623 _index = 0; |
1623 _index = 0; |
1624 } |
1624 } |
1625 |
1625 |
1626 BacktraceBuilder(objArrayHandle backtrace) { |
1626 BacktraceBuilder(Thread* thread, objArrayHandle backtrace) { |
1627 _methods = get_methods(backtrace); |
1627 _methods = get_methods(backtrace); |
1628 _bcis = get_bcis(backtrace); |
1628 _bcis = get_bcis(backtrace); |
1629 _mirrors = get_mirrors(backtrace); |
1629 _mirrors = get_mirrors(backtrace); |
1630 _cprefs = get_cprefs(backtrace); |
1630 _names = get_names(backtrace); |
1631 assert(_methods->length() == _bcis->length() && |
1631 assert(_methods->length() == _bcis->length() && |
1632 _methods->length() == _mirrors->length(), |
1632 _methods->length() == _mirrors->length() && |
|
1633 _mirrors->length() == _names->length(), |
1633 "method and source information arrays should match"); |
1634 "method and source information arrays should match"); |
1634 |
1635 |
1635 // head is the preallocated backtrace |
1636 // head is the preallocated backtrace |
1636 _backtrace = _head = backtrace(); |
1637 _head = backtrace(); |
|
1638 _backtrace = Handle(thread, _head); |
1637 _index = 0; |
1639 _index = 0; |
1638 } |
1640 } |
1639 |
1641 |
1640 void expand(TRAPS) { |
1642 void expand(TRAPS) { |
1641 objArrayHandle old_head(THREAD, _head); |
1643 objArrayHandle old_head(THREAD, _head); |
1651 typeArrayHandle new_bcis(THREAD, bcis); |
1653 typeArrayHandle new_bcis(THREAD, bcis); |
1652 |
1654 |
1653 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); |
1655 objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); |
1654 objArrayHandle new_mirrors(THREAD, mirrors); |
1656 objArrayHandle new_mirrors(THREAD, mirrors); |
1655 |
1657 |
1656 typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK); |
1658 typeArrayOop names = oopFactory::new_symbolArray(trace_chunk_size, CHECK); |
1657 typeArrayHandle new_cprefs(THREAD, cprefs); |
1659 typeArrayHandle new_names(THREAD, names); |
1658 |
1660 |
1659 if (!old_head.is_null()) { |
1661 if (!old_head.is_null()) { |
1660 old_head->obj_at_put(trace_next_offset, new_head()); |
1662 old_head->obj_at_put(trace_next_offset, new_head()); |
1661 } |
1663 } |
1662 new_head->obj_at_put(trace_methods_offset, new_methods()); |
1664 new_head->obj_at_put(trace_methods_offset, new_methods()); |
1663 new_head->obj_at_put(trace_bcis_offset, new_bcis()); |
1665 new_head->obj_at_put(trace_bcis_offset, new_bcis()); |
1664 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); |
1666 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); |
1665 new_head->obj_at_put(trace_cprefs_offset, new_cprefs()); |
1667 new_head->obj_at_put(trace_names_offset, new_names()); |
1666 |
1668 |
1667 _head = new_head(); |
1669 _head = new_head(); |
1668 _methods = new_methods(); |
1670 _methods = new_methods(); |
1669 _bcis = new_bcis(); |
1671 _bcis = new_bcis(); |
1670 _mirrors = new_mirrors(); |
1672 _mirrors = new_mirrors(); |
1671 _cprefs = new_cprefs(); |
1673 _names = new_names(); |
1672 _index = 0; |
1674 _index = 0; |
1673 } |
1675 } |
1674 |
1676 |
1675 oop backtrace() { |
1677 oop backtrace() { |
1676 return _backtrace(); |
1678 return _backtrace(); |
1688 method = mhandle(); |
1690 method = mhandle(); |
1689 } |
1691 } |
1690 |
1692 |
1691 _methods->short_at_put(_index, method->orig_method_idnum()); |
1693 _methods->short_at_put(_index, method->orig_method_idnum()); |
1692 _bcis->int_at_put(_index, Backtrace::merge_bci_and_version(bci, method->constants()->version())); |
1694 _bcis->int_at_put(_index, Backtrace::merge_bci_and_version(bci, method->constants()->version())); |
1693 _cprefs->short_at_put(_index, method->name_index()); |
1695 |
|
1696 // Note:this doesn't leak symbols because the mirror in the backtrace keeps the |
|
1697 // klass owning the symbols alive so their refcounts aren't decremented. |
|
1698 Symbol* name = method->name(); |
|
1699 _names->symbol_at_put(_index, name); |
1694 |
1700 |
1695 // We need to save the mirrors in the backtrace to keep the class |
1701 // We need to save the mirrors in the backtrace to keep the class |
1696 // from being unloaded while we still have this stack trace. |
1702 // from being unloaded while we still have this stack trace. |
1697 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); |
1703 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); |
1698 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); |
1704 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); |
1703 |
1709 |
1704 struct BacktraceElement : public StackObj { |
1710 struct BacktraceElement : public StackObj { |
1705 int _method_id; |
1711 int _method_id; |
1706 int _bci; |
1712 int _bci; |
1707 int _version; |
1713 int _version; |
1708 int _cpref; |
1714 Symbol* _name; |
1709 Handle _mirror; |
1715 Handle _mirror; |
1710 BacktraceElement(Handle mirror, int mid, int version, int bci, int cpref) : |
1716 BacktraceElement(Handle mirror, int mid, int version, int bci, Symbol* name) : |
1711 _mirror(mirror), _method_id(mid), _version(version), _bci(bci), _cpref(cpref) {} |
1717 _mirror(mirror), _method_id(mid), _version(version), _bci(bci), _name(name) {} |
1712 }; |
1718 }; |
1713 |
1719 |
1714 class BacktraceIterator : public StackObj { |
1720 class BacktraceIterator : public StackObj { |
1715 int _index; |
1721 int _index; |
1716 objArrayHandle _result; |
1722 objArrayHandle _result; |
1717 objArrayHandle _mirrors; |
1723 objArrayHandle _mirrors; |
1718 typeArrayHandle _methods; |
1724 typeArrayHandle _methods; |
1719 typeArrayHandle _bcis; |
1725 typeArrayHandle _bcis; |
1720 typeArrayHandle _cprefs; |
1726 typeArrayHandle _names; |
1721 |
1727 |
1722 void init(objArrayHandle result, Thread* thread) { |
1728 void init(objArrayHandle result, Thread* thread) { |
1723 // Get method id, bci, version and mirror from chunk |
1729 // Get method id, bci, version and mirror from chunk |
1724 _result = result; |
1730 _result = result; |
1725 if (_result.not_null()) { |
1731 if (_result.not_null()) { |
1726 _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result)); |
1732 _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result)); |
1727 _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result)); |
1733 _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result)); |
1728 _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result)); |
1734 _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result)); |
1729 _cprefs = typeArrayHandle(thread, BacktraceBuilder::get_cprefs(_result)); |
1735 _names = typeArrayHandle(thread, BacktraceBuilder::get_names(_result)); |
1730 _index = 0; |
1736 _index = 0; |
1731 } |
1737 } |
1732 } |
1738 } |
1733 public: |
1739 public: |
1734 BacktraceIterator(objArrayHandle result, Thread* thread) { |
1740 BacktraceIterator(objArrayHandle result, Thread* thread) { |
1739 BacktraceElement next(Thread* thread) { |
1745 BacktraceElement next(Thread* thread) { |
1740 BacktraceElement e (Handle(thread, _mirrors->obj_at(_index)), |
1746 BacktraceElement e (Handle(thread, _mirrors->obj_at(_index)), |
1741 _methods->short_at(_index), |
1747 _methods->short_at(_index), |
1742 Backtrace::version_at(_bcis->int_at(_index)), |
1748 Backtrace::version_at(_bcis->int_at(_index)), |
1743 Backtrace::bci_at(_bcis->int_at(_index)), |
1749 Backtrace::bci_at(_bcis->int_at(_index)), |
1744 _cprefs->short_at(_index)); |
1750 _names->symbol_at(_index)); |
1745 _index++; |
1751 _index++; |
1746 |
1752 |
1747 if (_index >= java_lang_Throwable::trace_chunk_size) { |
1753 if (_index >= java_lang_Throwable::trace_chunk_size) { |
1748 int next_offset = java_lang_Throwable::trace_next_offset; |
1754 int next_offset = java_lang_Throwable::trace_next_offset; |
1749 // Get next chunk |
1755 // Get next chunk |
1759 }; |
1765 }; |
1760 |
1766 |
1761 |
1767 |
1762 // Print stack trace element to resource allocated buffer |
1768 // Print stack trace element to resource allocated buffer |
1763 static void print_stack_element_to_stream(outputStream* st, Handle mirror, int method_id, |
1769 static void print_stack_element_to_stream(outputStream* st, Handle mirror, int method_id, |
1764 int version, int bci, int cpref) { |
1770 int version, int bci, Symbol* name) { |
1765 ResourceMark rm; |
1771 ResourceMark rm; |
1766 |
1772 |
1767 // Get strings and string lengths |
1773 // Get strings and string lengths |
1768 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); |
1774 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); |
1769 const char* klass_name = holder->external_name(); |
1775 const char* klass_name = holder->external_name(); |
1770 int buf_len = (int)strlen(klass_name); |
1776 int buf_len = (int)strlen(klass_name); |
1771 |
1777 |
1772 Method* method = holder->method_with_orig_idnum(method_id, version); |
1778 char* method_name = name->as_C_string(); |
1773 |
|
1774 // The method can be NULL if the requested class version is gone |
|
1775 Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); |
|
1776 char* method_name = sym->as_C_string(); |
|
1777 buf_len += (int)strlen(method_name); |
1779 buf_len += (int)strlen(method_name); |
1778 |
1780 |
1779 char* source_file_name = NULL; |
1781 char* source_file_name = NULL; |
1780 Symbol* source = Backtrace::get_source_file_name(holder, version); |
1782 Symbol* source = Backtrace::get_source_file_name(holder, version); |
1781 if (source != NULL) { |
1783 if (source != NULL) { |
1807 } else { |
1809 } else { |
1808 sprintf(buf + (int)strlen(buf), "%s/", module_name); |
1810 sprintf(buf + (int)strlen(buf), "%s/", module_name); |
1809 } |
1811 } |
1810 } |
1812 } |
1811 |
1813 |
|
1814 // The method can be NULL if the requested class version is gone |
|
1815 Method* method = holder->method_with_orig_idnum(method_id, version); |
1812 if (!version_matches(method, version)) { |
1816 if (!version_matches(method, version)) { |
1813 strcat(buf, "Redefined)"); |
1817 strcat(buf, "Redefined)"); |
1814 } else { |
1818 } else { |
1815 int line_number = Backtrace::get_line_number(method, bci); |
1819 int line_number = Backtrace::get_line_number(method, bci); |
1816 if (line_number == -2) { |
1820 if (line_number == -2) { |
1835 |
1839 |
1836 st->print_cr("%s", buf); |
1840 st->print_cr("%s", buf); |
1837 } |
1841 } |
1838 |
1842 |
1839 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { |
1843 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { |
1840 Handle mirror = method->method_holder()->java_mirror(); |
1844 Handle mirror (Thread::current(), method->method_holder()->java_mirror()); |
1841 int method_id = method->orig_method_idnum(); |
1845 int method_id = method->orig_method_idnum(); |
1842 int version = method->constants()->version(); |
1846 int version = method->constants()->version(); |
1843 int cpref = method->name_index(); |
1847 print_stack_element_to_stream(st, mirror, method_id, version, bci, method->name()); |
1844 print_stack_element_to_stream(st, mirror, method_id, version, bci, cpref); |
|
1845 } |
1848 } |
1846 |
1849 |
1847 /** |
1850 /** |
1848 * Print the throwable message and its stack trace plus all causes by walking the |
1851 * Print the throwable message and its stack trace plus all causes by walking the |
1849 * cause chain. The output looks the same as of Throwable.printStackTrace(). |
1852 * cause chain. The output looks the same as of Throwable.printStackTrace(). |
1850 */ |
1853 */ |
1851 void java_lang_Throwable::print_stack_trace(Handle throwable, outputStream* st) { |
1854 void java_lang_Throwable::print_stack_trace(Handle throwable, outputStream* st) { |
1852 // First, print the message. |
1855 // First, print the message. |
1853 print(throwable, st); |
1856 print(throwable(), st); |
1854 st->cr(); |
1857 st->cr(); |
1855 |
1858 |
1856 // Now print the stack trace. |
1859 // Now print the stack trace. |
1857 Thread* THREAD = Thread::current(); |
1860 Thread* THREAD = Thread::current(); |
1858 while (throwable.not_null()) { |
1861 while (throwable.not_null()) { |
1863 } |
1866 } |
1864 BacktraceIterator iter(result, THREAD); |
1867 BacktraceIterator iter(result, THREAD); |
1865 |
1868 |
1866 while (iter.repeat()) { |
1869 while (iter.repeat()) { |
1867 BacktraceElement bte = iter.next(THREAD); |
1870 BacktraceElement bte = iter.next(THREAD); |
1868 print_stack_element_to_stream(st, bte._mirror, bte._method_id, bte._version, bte._bci, bte._cpref); |
1871 print_stack_element_to_stream(st, bte._mirror, bte._method_id, bte._version, bte._bci, bte._name); |
1869 } |
1872 } |
1870 { |
1873 { |
1871 // Call getCause() which doesn't necessarily return the _cause field. |
1874 // Call getCause() which doesn't necessarily return the _cause field. |
1872 EXCEPTION_MARK; |
1875 EXCEPTION_MARK; |
1873 JavaValue cause(T_OBJECT); |
1876 JavaValue cause(T_OBJECT); |
2087 assert(backtrace.not_null(), "backtrace should have been preallocated"); |
2090 assert(backtrace.not_null(), "backtrace should have been preallocated"); |
2088 |
2091 |
2089 ResourceMark rm(THREAD); |
2092 ResourceMark rm(THREAD); |
2090 vframeStream st(THREAD); |
2093 vframeStream st(THREAD); |
2091 |
2094 |
2092 BacktraceBuilder bt(backtrace); |
2095 BacktraceBuilder bt(THREAD, backtrace); |
2093 |
2096 |
2094 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init |
2097 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init |
2095 // methods as preallocated errors aren't created by "java" code. |
2098 // methods as preallocated errors aren't created by "java" code. |
2096 |
2099 |
2097 // fill in as much stack trace as possible |
2100 // fill in as much stack trace as possible |
2157 ik->initialize(CHECK_0); |
2160 ik->initialize(CHECK_0); |
2158 } |
2161 } |
2159 |
2162 |
2160 Handle element = ik->allocate_instance_handle(CHECK_0); |
2163 Handle element = ik->allocate_instance_handle(CHECK_0); |
2161 |
2164 |
2162 int cpref = method->name_index(); |
|
2163 int version = method->constants()->version(); |
2165 int version = method->constants()->version(); |
2164 fill_in(element, method->method_holder(), method, version, bci, cpref, CHECK_0); |
2166 fill_in(element, method->method_holder(), method, version, bci, method->name(), CHECK_0); |
2165 return element(); |
2167 return element(); |
2166 } |
2168 } |
2167 |
2169 |
2168 void java_lang_StackTraceElement::fill_in(Handle element, |
2170 void java_lang_StackTraceElement::fill_in(Handle element, |
2169 InstanceKlass* holder, const methodHandle& method, |
2171 InstanceKlass* holder, const methodHandle& method, |
2170 int version, int bci, int cpref, TRAPS) { |
2172 int version, int bci, Symbol* name, TRAPS) { |
2171 assert(element->is_a(SystemDictionary::StackTraceElement_klass()), "sanity check"); |
2173 assert(element->is_a(SystemDictionary::StackTraceElement_klass()), "sanity check"); |
2172 |
2174 |
2173 // Fill in class name |
2175 // Fill in class name |
2174 ResourceMark rm(THREAD); |
2176 ResourceMark rm(THREAD); |
2175 const char* str = holder->external_name(); |
2177 const char* str = holder->external_name(); |
2182 oop loader_name = java_lang_ClassLoader::name(loader); |
2184 oop loader_name = java_lang_ClassLoader::name(loader); |
2183 if (loader_name != NULL) |
2185 if (loader_name != NULL) |
2184 java_lang_StackTraceElement::set_classLoaderName(element(), loader_name); |
2186 java_lang_StackTraceElement::set_classLoaderName(element(), loader_name); |
2185 } |
2187 } |
2186 |
2188 |
2187 // The method can be NULL if the requested class version is gone |
|
2188 Symbol* sym = !method.is_null() ? method->name() : holder->constants()->symbol_at(cpref); |
|
2189 |
|
2190 // Fill in method name |
2189 // Fill in method name |
2191 oop methodname = StringTable::intern(sym, CHECK); |
2190 oop methodname = StringTable::intern(name, CHECK); |
2192 java_lang_StackTraceElement::set_methodName(element(), methodname); |
2191 java_lang_StackTraceElement::set_methodName(element(), methodname); |
2193 |
2192 |
2194 // Fill in module name and version |
2193 // Fill in module name and version |
2195 ModuleEntry* module = holder->module(); |
2194 ModuleEntry* module = holder->module(); |
2196 if (module->is_named()) { |
2195 if (module->is_named()) { |
2203 module_version = NULL; |
2202 module_version = NULL; |
2204 } |
2203 } |
2205 java_lang_StackTraceElement::set_moduleVersion(element(), module_version); |
2204 java_lang_StackTraceElement::set_moduleVersion(element(), module_version); |
2206 } |
2205 } |
2207 |
2206 |
2208 if (!version_matches(method(), version)) { |
2207 if (method() == NULL || !version_matches(method(), version)) { |
2209 // The method was redefined, accurate line number information isn't available |
2208 // The method was redefined, accurate line number information isn't available |
2210 java_lang_StackTraceElement::set_fileName(element(), NULL); |
2209 java_lang_StackTraceElement::set_fileName(element(), NULL); |
2211 java_lang_StackTraceElement::set_lineNumber(element(), -1); |
2210 java_lang_StackTraceElement::set_lineNumber(element(), -1); |
2212 } else { |
2211 } else { |
2213 // Fill in source file name and line number. |
2212 // Fill in source file name and line number. |
2230 return method; |
2229 return method; |
2231 } |
2230 } |
2232 |
2231 |
2233 void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) { |
2232 void java_lang_StackFrameInfo::set_method_and_bci(Handle stackFrame, const methodHandle& method, int bci) { |
2234 // set Method* or mid/cpref |
2233 // set Method* or mid/cpref |
2235 oop mname = stackFrame->obj_field(_memberName_offset); |
2234 Handle mname(Thread::current(), stackFrame->obj_field(_memberName_offset)); |
2236 InstanceKlass* ik = method->method_holder(); |
2235 InstanceKlass* ik = method->method_holder(); |
2237 CallInfo info(method(), ik); |
2236 CallInfo info(method(), ik); |
2238 MethodHandles::init_method_MemberName(mname, info); |
2237 MethodHandles::init_method_MemberName(mname, info); |
2239 // set bci |
2238 // set bci |
2240 java_lang_StackFrameInfo::set_bci(stackFrame(), bci); |
2239 java_lang_StackFrameInfo::set_bci(stackFrame(), bci); |
2250 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k())); |
2249 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(k())); |
2251 Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK); |
2250 Method* method = java_lang_StackFrameInfo::get_method(stackFrame, holder, CHECK); |
2252 |
2251 |
2253 short version = stackFrame->short_field(_version_offset); |
2252 short version = stackFrame->short_field(_version_offset); |
2254 short bci = stackFrame->short_field(_bci_offset); |
2253 short bci = stackFrame->short_field(_bci_offset); |
2255 int cpref = method->name_index(); |
2254 Symbol* name = method->name(); |
2256 java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, cpref, CHECK); |
2255 java_lang_StackTraceElement::fill_in(stack_trace_element, holder, method, version, bci, name, CHECK); |
2257 } |
2256 } |
2258 |
2257 |
2259 void java_lang_StackFrameInfo::compute_offsets() { |
2258 void java_lang_StackFrameInfo::compute_offsets() { |
2260 Klass* k = SystemDictionary::StackFrameInfo_klass(); |
2259 Klass* k = SystemDictionary::StackFrameInfo_klass(); |
2261 compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature()); |
2260 compute_offset(_declaringClass_offset, k, vmSymbols::declaringClass_name(), vmSymbols::class_signature()); |
3973 |
3972 |
3974 // Check the hard-coded field offsets of all the classes in this file |
3973 // Check the hard-coded field offsets of all the classes in this file |
3975 |
3974 |
3976 void JavaClasses::check_offsets() { |
3975 void JavaClasses::check_offsets() { |
3977 bool valid = true; |
3976 bool valid = true; |
3978 HandleMark hm; |
|
3979 |
3977 |
3980 #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ |
3978 #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ |
3981 valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig) |
3979 valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig) |
3982 |
3980 |
3983 #define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ |
3981 #define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ |