changeset 37179 | 4dbcb3a642d2 |
parent 36508 | 5f9eee6b383b |
parent 37172 | ff4d69314a4c |
child 37301 | a936b4e01afb |
child 37438 | 873c4aea8d1b |
36617:390e8993b88e | 37179:4dbcb3a642d2 |
---|---|
511 UNICODE::as_quoted_ascii(base, length, result, result_length); |
511 UNICODE::as_quoted_ascii(base, length, result, result_length); |
512 } |
512 } |
513 assert(result_length >= length + 1, "must not be shorter"); |
513 assert(result_length >= length + 1, "must not be shorter"); |
514 assert(result_length == (int)strlen(result) + 1, "must match"); |
514 assert(result_length == (int)strlen(result) + 1, "must match"); |
515 return result; |
515 return result; |
516 } |
|
517 |
|
518 unsigned int java_lang_String::hash_string(oop java_string) { |
|
519 int length = java_lang_String::length(java_string); |
|
520 // Zero length string doesn't necessarily hash to zero. |
|
521 if (length == 0) { |
|
522 return StringTable::hash_string((jchar*) NULL, 0); |
|
523 } |
|
524 |
|
525 typeArrayOop value = java_lang_String::value(java_string); |
|
526 bool is_latin1 = java_lang_String::is_latin1(java_string); |
|
527 if (is_latin1) { |
|
528 return StringTable::hash_string(value->byte_at_addr(0), length); |
|
529 } else { |
|
530 return StringTable::hash_string(value->char_at_addr(0), length); |
|
531 } |
|
532 } |
516 } |
533 |
517 |
534 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { |
518 Symbol* java_lang_String::as_symbol(Handle java_string, TRAPS) { |
535 oop obj = java_string(); |
519 oop obj = java_string(); |
536 typeArrayOop value = java_lang_String::value(obj); |
520 typeArrayOop value = java_lang_String::value(obj); |
1471 compute_offset(_vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature()); |
1455 compute_offset(_vmAllowSuspension_offset, k, vmSymbols::vmAllowSuspension_name(), vmSymbols::bool_signature()); |
1472 compute_offset(_nthreads_offset, k, vmSymbols::nthreads_name(), vmSymbols::int_signature()); |
1456 compute_offset(_nthreads_offset, k, vmSymbols::nthreads_name(), vmSymbols::int_signature()); |
1473 compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); |
1457 compute_offset(_ngroups_offset, k, vmSymbols::ngroups_name(), vmSymbols::int_signature()); |
1474 } |
1458 } |
1475 |
1459 |
1460 |
|
1461 void java_lang_Throwable::compute_offsets() { |
|
1462 Klass* k = SystemDictionary::Throwable_klass(); |
|
1463 compute_offset(depth_offset, k, vmSymbols::depth_name(), vmSymbols::int_signature()); |
|
1464 } |
|
1465 |
|
1476 oop java_lang_Throwable::unassigned_stacktrace() { |
1466 oop java_lang_Throwable::unassigned_stacktrace() { |
1477 InstanceKlass* ik = SystemDictionary::Throwable_klass(); |
1467 InstanceKlass* ik = SystemDictionary::Throwable_klass(); |
1478 address addr = ik->static_field_addr(static_unassigned_stacktrace_offset); |
1468 address addr = ik->static_field_addr(static_unassigned_stacktrace_offset); |
1479 if (UseCompressedOops) { |
1469 if (UseCompressedOops) { |
1480 return oopDesc::load_decode_heap_oop((narrowOop *)addr); |
1470 return oopDesc::load_decode_heap_oop((narrowOop *)addr); |
1490 |
1480 |
1491 void java_lang_Throwable::set_backtrace(oop throwable, oop value) { |
1481 void java_lang_Throwable::set_backtrace(oop throwable, oop value) { |
1492 throwable->release_obj_field_put(backtrace_offset, value); |
1482 throwable->release_obj_field_put(backtrace_offset, value); |
1493 } |
1483 } |
1494 |
1484 |
1495 |
1485 int java_lang_Throwable::depth(oop throwable) { |
1496 oop java_lang_Throwable::message(oop throwable) { |
1486 return throwable->int_field(depth_offset); |
1497 return throwable->obj_field(detailMessage_offset); |
1487 } |
1498 } |
1488 |
1499 |
1489 void java_lang_Throwable::set_depth(oop throwable, int value) { |
1490 throwable->int_field_put(depth_offset, value); |
|
1491 } |
|
1500 |
1492 |
1501 oop java_lang_Throwable::message(Handle throwable) { |
1493 oop java_lang_Throwable::message(Handle throwable) { |
1502 return throwable->obj_field(detailMessage_offset); |
1494 return throwable->obj_field(detailMessage_offset); |
1503 } |
1495 } |
1504 |
1496 |
1544 static inline bool version_matches(Method* method, int version) { |
1536 static inline bool version_matches(Method* method, int version) { |
1545 assert(version < MAX_VERSION, "version is too big"); |
1537 assert(version < MAX_VERSION, "version is too big"); |
1546 return method != NULL && (method->constants()->version() == version); |
1538 return method != NULL && (method->constants()->version() == version); |
1547 } |
1539 } |
1548 |
1540 |
1541 |
|
1549 // This class provides a simple wrapper over the internal structure of |
1542 // This class provides a simple wrapper over the internal structure of |
1550 // exception backtrace to insulate users of the backtrace from needing |
1543 // exception backtrace to insulate users of the backtrace from needing |
1551 // to know what it looks like. |
1544 // to know what it looks like. |
1552 class BacktraceBuilder: public StackObj { |
1545 class BacktraceBuilder: public StackObj { |
1546 friend class BacktraceIterator; |
|
1553 private: |
1547 private: |
1554 Handle _backtrace; |
1548 Handle _backtrace; |
1555 objArrayOop _head; |
1549 objArrayOop _head; |
1556 typeArrayOop _methods; |
1550 typeArrayOop _methods; |
1557 typeArrayOop _bcis; |
1551 typeArrayOop _bcis; |
1558 objArrayOop _mirrors; |
1552 objArrayOop _mirrors; |
1559 typeArrayOop _cprefs; // needed to insulate method name against redefinition |
1553 typeArrayOop _cprefs; // needed to insulate method name against redefinition |
1560 int _index; |
1554 int _index; |
1561 NoSafepointVerifier _nsv; |
1555 NoSafepointVerifier _nsv; |
1562 |
1556 |
1563 public: |
|
1564 |
|
1565 enum { |
1557 enum { |
1566 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
1558 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
1567 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
1559 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
1568 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
1560 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
1569 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset, |
1561 trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset, |
1592 typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset)); |
1584 typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset)); |
1593 assert(cprefs != NULL, "cprefs array should be initialized in backtrace"); |
1585 assert(cprefs != NULL, "cprefs array should be initialized in backtrace"); |
1594 return cprefs; |
1586 return cprefs; |
1595 } |
1587 } |
1596 |
1588 |
1589 public: |
|
1590 |
|
1597 // constructor for new backtrace |
1591 // constructor for new backtrace |
1598 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) { |
1592 BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) { |
1599 expand(CHECK); |
1593 expand(CHECK); |
1600 _backtrace = _head; |
1594 _backtrace = _head; |
1601 _index = 0; |
1595 _index = 0; |
1677 _index++; |
1671 _index++; |
1678 } |
1672 } |
1679 |
1673 |
1680 }; |
1674 }; |
1681 |
1675 |
1676 struct BacktraceElement : public StackObj { |
|
1677 int _method_id; |
|
1678 int _bci; |
|
1679 int _version; |
|
1680 int _cpref; |
|
1681 Handle _mirror; |
|
1682 BacktraceElement(Handle mirror, int mid, int version, int bci, int cpref) : |
|
1683 _mirror(mirror), _method_id(mid), _version(version), _bci(bci), _cpref(cpref) {} |
|
1684 }; |
|
1685 |
|
1686 class BacktraceIterator : public StackObj { |
|
1687 int _index; |
|
1688 objArrayHandle _result; |
|
1689 objArrayHandle _mirrors; |
|
1690 typeArrayHandle _methods; |
|
1691 typeArrayHandle _bcis; |
|
1692 typeArrayHandle _cprefs; |
|
1693 |
|
1694 void init(objArrayHandle result, Thread* thread) { |
|
1695 // Get method id, bci, version and mirror from chunk |
|
1696 _result = result; |
|
1697 if (_result.not_null()) { |
|
1698 _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result)); |
|
1699 _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result)); |
|
1700 _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result)); |
|
1701 _cprefs = typeArrayHandle(thread, BacktraceBuilder::get_cprefs(_result)); |
|
1702 _index = 0; |
|
1703 } |
|
1704 } |
|
1705 public: |
|
1706 BacktraceIterator(objArrayHandle result, Thread* thread) { |
|
1707 init(result, thread); |
|
1708 assert(_methods.is_null() || _methods->length() == java_lang_Throwable::trace_chunk_size, "lengths don't match"); |
|
1709 } |
|
1710 |
|
1711 BacktraceElement next(Thread* thread) { |
|
1712 BacktraceElement e (Handle(thread, _mirrors->obj_at(_index)), |
|
1713 _methods->short_at(_index), |
|
1714 Backtrace::version_at(_bcis->int_at(_index)), |
|
1715 Backtrace::bci_at(_bcis->int_at(_index)), |
|
1716 _cprefs->short_at(_index)); |
|
1717 _index++; |
|
1718 |
|
1719 if (_index >= java_lang_Throwable::trace_chunk_size) { |
|
1720 int next_offset = java_lang_Throwable::trace_next_offset; |
|
1721 // Get next chunk |
|
1722 objArrayHandle result (thread, objArrayOop(_result->obj_at(next_offset))); |
|
1723 init(result, thread); |
|
1724 } |
|
1725 return e; |
|
1726 } |
|
1727 |
|
1728 bool repeat() { |
|
1729 return _result.not_null() && _mirrors->obj_at(_index) != NULL; |
|
1730 } |
|
1731 }; |
|
1732 |
|
1733 |
|
1682 // Print stack trace element to resource allocated buffer |
1734 // Print stack trace element to resource allocated buffer |
1683 char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, |
1735 static void print_stack_element_to_stream(outputStream* st, Handle mirror, int method_id, |
1684 int method_id, int version, int bci, int cpref) { |
1736 int version, int bci, int cpref) { |
1737 ResourceMark rm; |
|
1685 |
1738 |
1686 // Get strings and string lengths |
1739 // Get strings and string lengths |
1687 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); |
1740 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); |
1688 const char* klass_name = holder->external_name(); |
1741 const char* klass_name = holder->external_name(); |
1689 int buf_len = (int)strlen(klass_name); |
1742 int buf_len = (int)strlen(klass_name); |
1750 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); |
1803 sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm); |
1751 } |
1804 } |
1752 } |
1805 } |
1753 } |
1806 } |
1754 |
1807 |
1755 return buf; |
|
1756 } |
|
1757 |
|
1758 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, |
|
1759 int method_id, int version, int bci, int cpref) { |
|
1760 ResourceMark rm; |
|
1761 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref); |
|
1762 st->print_cr("%s", buf); |
1808 st->print_cr("%s", buf); |
1763 } |
1809 } |
1764 |
1810 |
1765 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { |
1811 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { |
1766 Handle mirror = method->method_holder()->java_mirror(); |
1812 Handle mirror = method->method_holder()->java_mirror(); |
1767 int method_id = method->orig_method_idnum(); |
1813 int method_id = method->orig_method_idnum(); |
1768 int version = method->constants()->version(); |
1814 int version = method->constants()->version(); |
1769 int cpref = method->name_index(); |
1815 int cpref = method->name_index(); |
1770 print_stack_element(st, mirror, method_id, version, bci, cpref); |
1816 print_stack_element_to_stream(st, mirror, method_id, version, bci, cpref); |
1771 } |
|
1772 |
|
1773 const char* java_lang_Throwable::no_stack_trace_message() { |
|
1774 return "\t<<no stack trace available>>"; |
|
1775 } |
1817 } |
1776 |
1818 |
1777 /** |
1819 /** |
1778 * Print the throwable message and its stack trace plus all causes by walking the |
1820 * Print the throwable message and its stack trace plus all causes by walking the |
1779 * cause chain. The output looks the same as of Throwable.printStackTrace(). |
1821 * cause chain. The output looks the same as of Throwable.printStackTrace(). |
1786 // Now print the stack trace. |
1828 // Now print the stack trace. |
1787 Thread* THREAD = Thread::current(); |
1829 Thread* THREAD = Thread::current(); |
1788 while (throwable.not_null()) { |
1830 while (throwable.not_null()) { |
1789 objArrayHandle result (THREAD, objArrayOop(backtrace(throwable()))); |
1831 objArrayHandle result (THREAD, objArrayOop(backtrace(throwable()))); |
1790 if (result.is_null()) { |
1832 if (result.is_null()) { |
1791 st->print_raw_cr(no_stack_trace_message()); |
1833 st->print_raw_cr("\t<<no stack trace available>>"); |
1792 return; |
1834 return; |
1793 } |
1835 } |
1794 |
1836 BacktraceIterator iter(result, THREAD); |
1795 while (result.not_null()) { |
1837 |
1796 // Get method id, bci, version and mirror from chunk |
1838 while (iter.repeat()) { |
1797 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); |
1839 BacktraceElement bte = iter.next(THREAD); |
1798 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); |
1840 print_stack_element_to_stream(st, bte._mirror, bte._method_id, bte._version, bte._bci, bte._cpref); |
1799 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); |
1841 } |
1800 typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result)); |
|
1801 |
|
1802 int length = methods()->length(); |
|
1803 for (int index = 0; index < length; index++) { |
|
1804 Handle mirror(THREAD, mirrors->obj_at(index)); |
|
1805 // NULL mirror means end of stack trace |
|
1806 if (mirror.is_null()) goto handle_cause; |
|
1807 int method = methods->short_at(index); |
|
1808 int version = Backtrace::version_at(bcis->int_at(index)); |
|
1809 int bci = Backtrace::bci_at(bcis->int_at(index)); |
|
1810 int cpref = cprefs->short_at(index); |
|
1811 print_stack_element(st, mirror, method, version, bci, cpref); |
|
1812 } |
|
1813 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); |
|
1814 } |
|
1815 handle_cause: |
|
1816 { |
1842 { |
1843 // Call getCause() which doesn't necessarily return the _cause field. |
|
1817 EXCEPTION_MARK; |
1844 EXCEPTION_MARK; |
1818 JavaValue cause(T_OBJECT); |
1845 JavaValue cause(T_OBJECT); |
1819 JavaCalls::call_virtual(&cause, |
1846 JavaCalls::call_virtual(&cause, |
1820 throwable, |
1847 throwable, |
1821 KlassHandle(THREAD, throwable->klass()), |
1848 KlassHandle(THREAD, throwable->klass()), |
1863 // This is unnecessary in 1.7+ but harmless |
1890 // This is unnecessary in 1.7+ but harmless |
1864 clear_stacktrace(throwable()); |
1891 clear_stacktrace(throwable()); |
1865 |
1892 |
1866 int max_depth = MaxJavaStackTraceDepth; |
1893 int max_depth = MaxJavaStackTraceDepth; |
1867 JavaThread* thread = (JavaThread*)THREAD; |
1894 JavaThread* thread = (JavaThread*)THREAD; |
1895 |
|
1868 BacktraceBuilder bt(CHECK); |
1896 BacktraceBuilder bt(CHECK); |
1869 |
1897 |
1870 // If there is no Java frame just return the method that was being called |
1898 // If there is no Java frame just return the method that was being called |
1871 // with bci 0 |
1899 // with bci 0 |
1872 if (!thread->has_last_Java_frame()) { |
1900 if (!thread->has_last_Java_frame()) { |
1873 if (max_depth >= 1 && method() != NULL) { |
1901 if (max_depth >= 1 && method() != NULL) { |
1874 bt.push(method(), 0, CHECK); |
1902 bt.push(method(), 0, CHECK); |
1903 log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), 1); |
|
1904 set_depth(throwable(), 1); |
|
1875 set_backtrace(throwable(), bt.backtrace()); |
1905 set_backtrace(throwable(), bt.backtrace()); |
1876 } |
1906 } |
1877 return; |
1907 return; |
1878 } |
1908 } |
1879 |
1909 |
1977 } |
2007 } |
1978 bt.push(method, bci, CHECK); |
2008 bt.push(method, bci, CHECK); |
1979 total_count++; |
2009 total_count++; |
1980 } |
2010 } |
1981 |
2011 |
2012 log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), total_count); |
|
2013 |
|
1982 // Put completed stack trace into throwable object |
2014 // Put completed stack trace into throwable object |
1983 set_backtrace(throwable(), bt.backtrace()); |
2015 set_backtrace(throwable(), bt.backtrace()); |
2016 set_depth(throwable(), total_count); |
|
1984 } |
2017 } |
1985 |
2018 |
1986 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method) { |
2019 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method) { |
1987 // No-op if stack trace is disabled |
2020 // No-op if stack trace is disabled |
1988 if (!StackTraceInThrowable) { |
2021 if (!StackTraceInThrowable) { |
2032 |
2065 |
2033 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init |
2066 // Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init |
2034 // methods as preallocated errors aren't created by "java" code. |
2067 // methods as preallocated errors aren't created by "java" code. |
2035 |
2068 |
2036 // fill in as much stack trace as possible |
2069 // fill in as much stack trace as possible |
2037 typeArrayOop methods = BacktraceBuilder::get_methods(backtrace); |
|
2038 int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth); |
|
2039 int chunk_count = 0; |
2070 int chunk_count = 0; |
2040 |
|
2041 for (;!st.at_end(); st.next()) { |
2071 for (;!st.at_end(); st.next()) { |
2042 bt.push(st.method(), st.bci(), CHECK); |
2072 bt.push(st.method(), st.bci(), CHECK); |
2043 chunk_count++; |
2073 chunk_count++; |
2044 |
2074 |
2045 // Bail-out for deep stacks |
2075 // Bail-out for deep stacks |
2046 if (chunk_count >= max_chunks) break; |
2076 if (chunk_count >= trace_chunk_size) break; |
2047 } |
2077 } |
2078 set_depth(throwable(), chunk_count); |
|
2079 log_info(stacktrace)("%s, %d", throwable->klass()->external_name(), chunk_count); |
|
2048 |
2080 |
2049 // We support the Throwable immutability protocol defined for Java 7. |
2081 // We support the Throwable immutability protocol defined for Java 7. |
2050 java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); |
2082 java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace()); |
2051 assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); |
2083 assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized"); |
2052 } |
2084 } |
2053 |
2085 |
2054 |
2086 void java_lang_Throwable::get_stack_trace_elements(Handle throwable, |
2055 int java_lang_Throwable::get_stack_trace_depth(oop throwable, TRAPS) { |
2087 objArrayHandle stack_trace_array_h, TRAPS) { |
2056 if (throwable == NULL) { |
2088 |
2057 THROW_0(vmSymbols::java_lang_NullPointerException()); |
2089 if (throwable.is_null() || stack_trace_array_h.is_null()) { |
2058 } |
2090 THROW(vmSymbols::java_lang_NullPointerException()); |
2059 objArrayOop chunk = objArrayOop(backtrace(throwable)); |
2091 } |
2060 int depth = 0; |
2092 |
2061 if (chunk != NULL) { |
2093 assert(stack_trace_array_h->is_objArray(), "Stack trace array should be an array of StackTraceElenent"); |
2062 // Iterate over chunks and count full ones |
2094 |
2063 while (true) { |
2095 if (stack_trace_array_h->length() != depth(throwable())) { |
2064 objArrayOop next = objArrayOop(chunk->obj_at(trace_next_offset)); |
2096 THROW(vmSymbols::java_lang_IndexOutOfBoundsException()); |
2065 if (next == NULL) break; |
2097 } |
2066 depth += trace_chunk_size; |
2098 |
2067 chunk = next; |
2099 objArrayHandle result(THREAD, objArrayOop(backtrace(throwable()))); |
2068 } |
2100 BacktraceIterator iter(result, THREAD); |
2069 assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check"); |
2101 |
2070 // Count element in remaining partial chunk. NULL value for mirror |
2102 int index = 0; |
2071 // marks the end of the stack trace elements that are saved. |
2103 while (iter.repeat()) { |
2072 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); |
2104 BacktraceElement bte = iter.next(THREAD); |
2073 assert(mirrors != NULL, "sanity check"); |
2105 |
2074 for (int i = 0; i < mirrors->length(); i++) { |
2106 Handle stack_trace_element(THREAD, stack_trace_array_h->obj_at(index++)); |
2075 if (mirrors->obj_at(i) == NULL) break; |
2107 |
2076 depth++; |
2108 if (stack_trace_element.is_null()) { |
2077 } |
2109 THROW(vmSymbols::java_lang_NullPointerException()); |
2078 } |
2110 } |
2079 return depth; |
2111 |
2080 } |
2112 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(bte._mirror())); |
2081 |
2113 methodHandle method (THREAD, holder->method_with_orig_idnum(bte._method_id, bte._version)); |
2082 |
2114 |
2083 oop java_lang_Throwable::get_stack_trace_element(oop throwable, int index, TRAPS) { |
2115 java_lang_StackTraceElement::fill_in(stack_trace_element, holder, |
2084 if (throwable == NULL) { |
2116 method, |
2085 THROW_0(vmSymbols::java_lang_NullPointerException()); |
2117 bte._version, |
2086 } |
2118 bte._bci, |
2087 if (index < 0) { |
2119 bte._cpref, CHECK); |
2088 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); |
2120 } |
2089 } |
2121 } |
2090 // Compute how many chunks to skip and index into actual chunk |
2122 |
2091 objArrayOop chunk = objArrayOop(backtrace(throwable)); |
2123 oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) { |
2092 int skip_chunks = index / trace_chunk_size; |
|
2093 int chunk_index = index % trace_chunk_size; |
|
2094 while (chunk != NULL && skip_chunks > 0) { |
|
2095 chunk = objArrayOop(chunk->obj_at(trace_next_offset)); |
|
2096 skip_chunks--; |
|
2097 } |
|
2098 if (chunk == NULL) { |
|
2099 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); |
|
2100 } |
|
2101 // Get method id, bci, version, mirror and cpref from chunk |
|
2102 typeArrayOop methods = BacktraceBuilder::get_methods(chunk); |
|
2103 typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); |
|
2104 objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); |
|
2105 typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk); |
|
2106 |
|
2107 assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); |
|
2108 |
|
2109 int method = methods->short_at(chunk_index); |
|
2110 int version = Backtrace::version_at(bcis->int_at(chunk_index)); |
|
2111 int bci = Backtrace::bci_at(bcis->int_at(chunk_index)); |
|
2112 int cpref = cprefs->short_at(chunk_index); |
|
2113 Handle mirror(THREAD, mirrors->obj_at(chunk_index)); |
|
2114 |
|
2115 // Chunk can be partial full |
|
2116 if (mirror.is_null()) { |
|
2117 THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); |
|
2118 } |
|
2119 oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0); |
|
2120 return element; |
|
2121 } |
|
2122 |
|
2123 oop java_lang_StackTraceElement::create(Handle mirror, int method_id, |
|
2124 int version, int bci, int cpref, TRAPS) { |
|
2125 // Allocate java.lang.StackTraceElement instance |
2124 // Allocate java.lang.StackTraceElement instance |
2126 Klass* k = SystemDictionary::StackTraceElement_klass(); |
2125 Klass* k = SystemDictionary::StackTraceElement_klass(); |
2127 assert(k != NULL, "must be loaded in 1.4+"); |
2126 assert(k != NULL, "must be loaded in 1.4+"); |
2128 instanceKlassHandle ik (THREAD, k); |
2127 instanceKlassHandle ik (THREAD, k); |
2129 if (ik->should_be_initialized()) { |
2128 if (ik->should_be_initialized()) { |
2130 ik->initialize(CHECK_0); |
2129 ik->initialize(CHECK_0); |
2131 } |
2130 } |
2132 |
2131 |
2133 Handle element = ik->allocate_instance_handle(CHECK_0); |
2132 Handle element = ik->allocate_instance_handle(CHECK_0); |
2134 |
2133 |
2134 int cpref = method->name_index(); |
|
2135 int version = method->constants()->version(); |
|
2136 fill_in(element, method->method_holder(), method, version, bci, cpref, CHECK_0); |
|
2137 return element(); |
|
2138 } |
|
2139 |
|
2140 void java_lang_StackTraceElement::fill_in(Handle element, |
|
2141 InstanceKlass* holder, const methodHandle& method, |
|
2142 int version, int bci, int cpref, TRAPS) { |
|
2143 assert(element->is_a(SystemDictionary::StackTraceElement_klass()), "sanity check"); |
|
2144 |
|
2135 // Fill in class name |
2145 // Fill in class name |
2136 ResourceMark rm(THREAD); |
2146 ResourceMark rm(THREAD); |
2137 InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); |
|
2138 const char* str = holder->external_name(); |
2147 const char* str = holder->external_name(); |
2139 oop classname = StringTable::intern((char*) str, CHECK_0); |
2148 oop classname = StringTable::intern((char*) str, CHECK); |
2140 java_lang_StackTraceElement::set_declaringClass(element(), classname); |
2149 java_lang_StackTraceElement::set_declaringClass(element(), classname); |
2141 |
2150 |
2142 Method* method = holder->method_with_orig_idnum(method_id, version); |
|
2143 |
|
2144 // The method can be NULL if the requested class version is gone |
2151 // The method can be NULL if the requested class version is gone |
2145 Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); |
2152 Symbol* sym = !method.is_null() ? method->name() : holder->constants()->symbol_at(cpref); |
2146 |
2153 |
2147 // Fill in method name |
2154 // Fill in method name |
2148 oop methodname = StringTable::intern(sym, CHECK_0); |
2155 oop methodname = StringTable::intern(sym, CHECK); |
2149 java_lang_StackTraceElement::set_methodName(element(), methodname); |
2156 java_lang_StackTraceElement::set_methodName(element(), methodname); |
2150 |
2157 |
2151 // Fill in module name and version |
2158 // Fill in module name and version |
2152 ModuleEntry* module = holder->module(); |
2159 ModuleEntry* module = holder->module(); |
2153 if (module->is_named()) { |
2160 if (module->is_named()) { |
2154 oop module_name = StringTable::intern(module->name(), CHECK_0); |
2161 oop module_name = StringTable::intern(module->name(), CHECK); |
2155 java_lang_StackTraceElement::set_moduleName(element(), module_name); |
2162 java_lang_StackTraceElement::set_moduleName(element(), module_name); |
2156 oop module_version; |
2163 oop module_version; |
2157 if (module->version() != NULL) { |
2164 if (module->version() != NULL) { |
2158 module_version = StringTable::intern(module->version(), CHECK_0); |
2165 module_version = StringTable::intern(module->version(), CHECK); |
2159 } else { |
2166 } else { |
2160 module_version = NULL; |
2167 module_version = NULL; |
2161 } |
2168 } |
2162 java_lang_StackTraceElement::set_moduleVersion(element(), module_version); |
2169 java_lang_StackTraceElement::set_moduleVersion(element(), module_version); |
2163 } |
2170 } |
2164 |
2171 |
2165 if (!version_matches(method, version)) { |
2172 if (!version_matches(method(), version)) { |
2166 // The method was redefined, accurate line number information isn't available |
2173 // The method was redefined, accurate line number information isn't available |
2167 java_lang_StackTraceElement::set_fileName(element(), NULL); |
2174 java_lang_StackTraceElement::set_fileName(element(), NULL); |
2168 java_lang_StackTraceElement::set_lineNumber(element(), -1); |
2175 java_lang_StackTraceElement::set_lineNumber(element(), -1); |
2169 } else { |
2176 } else { |
2170 // Fill in source file name and line number. |
2177 // Fill in source file name and line number. |
2171 Symbol* source = Backtrace::get_source_file_name(holder, version); |
2178 Symbol* source = Backtrace::get_source_file_name(holder, version); |
2172 if (ShowHiddenFrames && source == NULL) |
2179 if (ShowHiddenFrames && source == NULL) |
2173 source = vmSymbols::unknown_class_name(); |
2180 source = vmSymbols::unknown_class_name(); |
2174 oop filename = StringTable::intern(source, CHECK_0); |
2181 oop filename = StringTable::intern(source, CHECK); |
2175 java_lang_StackTraceElement::set_fileName(element(), filename); |
2182 java_lang_StackTraceElement::set_fileName(element(), filename); |
2176 |
2183 |
2177 int line_number = Backtrace::get_line_number(method, bci); |
2184 int line_number = Backtrace::get_line_number(method, bci); |
2178 java_lang_StackTraceElement::set_lineNumber(element(), line_number); |
2185 java_lang_StackTraceElement::set_lineNumber(element(), line_number); |
2179 } |
2186 } |
2180 return element(); |
|
2181 } |
|
2182 |
|
2183 oop java_lang_StackTraceElement::create(const methodHandle& method, int bci, TRAPS) { |
|
2184 Handle mirror (THREAD, method->method_holder()->java_mirror()); |
|
2185 int method_id = method->orig_method_idnum(); |
|
2186 int cpref = method->name_index(); |
|
2187 return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD); |
|
2188 } |
2187 } |
2189 |
2188 |
2190 Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) { |
2189 Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) { |
2191 if (MemberNameInStackFrame) { |
2190 if (MemberNameInStackFrame) { |
2192 Handle mname(THREAD, stackFrame->obj_field(_memberName_offset)); |
2191 Handle mname(THREAD, stackFrame->obj_field(_memberName_offset)); |
3627 int java_lang_Class::_signers_offset; |
3626 int java_lang_Class::_signers_offset; |
3628 GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL; |
3627 GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL; |
3629 GrowableArray<Klass*>* java_lang_Class::_fixup_module_field_list = NULL; |
3628 GrowableArray<Klass*>* java_lang_Class::_fixup_module_field_list = NULL; |
3630 int java_lang_Throwable::backtrace_offset; |
3629 int java_lang_Throwable::backtrace_offset; |
3631 int java_lang_Throwable::detailMessage_offset; |
3630 int java_lang_Throwable::detailMessage_offset; |
3632 int java_lang_Throwable::cause_offset; |
|
3633 int java_lang_Throwable::stackTrace_offset; |
3631 int java_lang_Throwable::stackTrace_offset; |
3632 int java_lang_Throwable::depth_offset; |
|
3634 int java_lang_Throwable::static_unassigned_stacktrace_offset; |
3633 int java_lang_Throwable::static_unassigned_stacktrace_offset; |
3635 int java_lang_reflect_AccessibleObject::override_offset; |
3634 int java_lang_reflect_AccessibleObject::override_offset; |
3636 int java_lang_reflect_Method::clazz_offset; |
3635 int java_lang_reflect_Method::clazz_offset; |
3637 int java_lang_reflect_Method::name_offset; |
3636 int java_lang_reflect_Method::name_offset; |
3638 int java_lang_reflect_Method::returnType_offset; |
3637 int java_lang_reflect_Method::returnType_offset; |
3839 const int header = instanceOopDesc::base_offset_in_bytes(); |
3838 const int header = instanceOopDesc::base_offset_in_bytes(); |
3840 |
3839 |
3841 // Throwable Class |
3840 // Throwable Class |
3842 java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; |
3841 java_lang_Throwable::backtrace_offset = java_lang_Throwable::hc_backtrace_offset * x + header; |
3843 java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; |
3842 java_lang_Throwable::detailMessage_offset = java_lang_Throwable::hc_detailMessage_offset * x + header; |
3844 java_lang_Throwable::cause_offset = java_lang_Throwable::hc_cause_offset * x + header; |
|
3845 java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; |
3843 java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; |
3846 java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x; |
3844 java_lang_Throwable::static_unassigned_stacktrace_offset = java_lang_Throwable::hc_static_unassigned_stacktrace_offset * x; |
3847 |
3845 |
3848 // java_lang_boxing_object |
3846 // java_lang_boxing_object |
3849 java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header; |
3847 java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header; |
3892 |
3890 |
3893 // Compute non-hard-coded field offsets of all the classes in this file |
3891 // Compute non-hard-coded field offsets of all the classes in this file |
3894 void JavaClasses::compute_offsets() { |
3892 void JavaClasses::compute_offsets() { |
3895 // java_lang_Class::compute_offsets was called earlier in bootstrap |
3893 // java_lang_Class::compute_offsets was called earlier in bootstrap |
3896 java_lang_ClassLoader::compute_offsets(); |
3894 java_lang_ClassLoader::compute_offsets(); |
3895 java_lang_Throwable::compute_offsets(); |
|
3897 java_lang_Thread::compute_offsets(); |
3896 java_lang_Thread::compute_offsets(); |
3898 java_lang_ThreadGroup::compute_offsets(); |
3897 java_lang_ThreadGroup::compute_offsets(); |
3899 java_lang_invoke_MethodHandle::compute_offsets(); |
3898 java_lang_invoke_MethodHandle::compute_offsets(); |
3900 java_lang_invoke_DirectMethodHandle::compute_offsets(); |
3899 java_lang_invoke_DirectMethodHandle::compute_offsets(); |
3901 java_lang_invoke_MemberName::compute_offsets(); |
3900 java_lang_invoke_MemberName::compute_offsets(); |
4046 |
4045 |
4047 // java.lang.Throwable |
4046 // java.lang.Throwable |
4048 |
4047 |
4049 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, backtrace, "Ljava/lang/Object;"); |
4048 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, backtrace, "Ljava/lang/Object;"); |
4050 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, detailMessage, "Ljava/lang/String;"); |
4049 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, detailMessage, "Ljava/lang/String;"); |
4051 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, cause, "Ljava/lang/Throwable;"); |
|
4052 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;"); |
4050 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, stackTrace, "[Ljava/lang/StackTraceElement;"); |
4051 CHECK_OFFSET("java/lang/Throwable", java_lang_Throwable, depth, "I"); |
|
4053 |
4052 |
4054 // Boxed primitive objects (java_lang_boxing_object) |
4053 // Boxed primitive objects (java_lang_boxing_object) |
4055 |
4054 |
4056 CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z"); |
4055 CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z"); |
4057 CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C"); |
4056 CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C"); |