1966 |
1966 |
1967 if (bt == NULL) { |
1967 if (bt == NULL) { |
1968 return false; |
1968 return false; |
1969 } |
1969 } |
1970 |
1970 |
|
1971 // If the exception happened in a frame that has been hidden, i.e., |
|
1972 // omitted from the back trace, we can not compute the message. |
|
1973 oop hidden = bt->obj_at(trace_hidden_offset); |
|
1974 if (hidden != NULL) { |
|
1975 return false; |
|
1976 } |
|
1977 |
1971 oop ms = bt->obj_at(trace_methods_offset); |
1978 oop ms = bt->obj_at(trace_methods_offset); |
1972 typeArrayOop methods = typeArrayOop(ms); |
1979 typeArrayOop methods = typeArrayOop(ms); |
1973 typeArrayOop bcis = (typeArrayOop)bt->obj_at(trace_bcis_offset); |
1980 typeArrayOop bcis = (typeArrayOop)bt->obj_at(trace_bcis_offset); |
1974 objArrayOop mirrors = (objArrayOop)bt->obj_at(trace_mirrors_offset); |
1981 objArrayOop mirrors = (objArrayOop)bt->obj_at(trace_mirrors_offset); |
1975 if ((methods == NULL) || (bcis == NULL) || (mirrors == NULL)) { |
1982 if ((methods == NULL) || (bcis == NULL) || (mirrors == NULL)) { |
2003 Handle _backtrace; |
2010 Handle _backtrace; |
2004 objArrayOop _head; |
2011 objArrayOop _head; |
2005 typeArrayOop _methods; |
2012 typeArrayOop _methods; |
2006 typeArrayOop _bcis; |
2013 typeArrayOop _bcis; |
2007 objArrayOop _mirrors; |
2014 objArrayOop _mirrors; |
2008 typeArrayOop _names; // needed to insulate method name against redefinition |
2015 typeArrayOop _names; // Needed to insulate method name against redefinition. |
|
2016 // This is set to a java.lang.Boolean(true) if the top frame |
|
2017 // of the backtrace is omitted because it shall be hidden. |
|
2018 // Else it is null. |
|
2019 oop _has_hidden_top_frame; |
2009 int _index; |
2020 int _index; |
2010 NoSafepointVerifier _nsv; |
2021 NoSafepointVerifier _nsv; |
2011 |
2022 |
2012 enum { |
2023 enum { |
2013 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
2024 trace_methods_offset = java_lang_Throwable::trace_methods_offset, |
2014 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
2025 trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, |
2015 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
2026 trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, |
2016 trace_names_offset = java_lang_Throwable::trace_names_offset, |
2027 trace_names_offset = java_lang_Throwable::trace_names_offset, |
2017 trace_next_offset = java_lang_Throwable::trace_next_offset, |
2028 trace_next_offset = java_lang_Throwable::trace_next_offset, |
|
2029 trace_hidden_offset = java_lang_Throwable::trace_hidden_offset, |
2018 trace_size = java_lang_Throwable::trace_size, |
2030 trace_size = java_lang_Throwable::trace_size, |
2019 trace_chunk_size = java_lang_Throwable::trace_chunk_size |
2031 trace_chunk_size = java_lang_Throwable::trace_chunk_size |
2020 }; |
2032 }; |
2021 |
2033 |
2022 // get info out of chunks |
2034 // get info out of chunks |
2038 static typeArrayOop get_names(objArrayHandle chunk) { |
2050 static typeArrayOop get_names(objArrayHandle chunk) { |
2039 typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset)); |
2051 typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset)); |
2040 assert(names != NULL, "names array should be initialized in backtrace"); |
2052 assert(names != NULL, "names array should be initialized in backtrace"); |
2041 return names; |
2053 return names; |
2042 } |
2054 } |
|
2055 static oop get_has_hidden_top_frame(objArrayHandle chunk) { |
|
2056 oop hidden = chunk->obj_at(trace_hidden_offset); |
|
2057 return hidden; |
|
2058 } |
2043 |
2059 |
2044 public: |
2060 public: |
2045 |
2061 |
2046 // constructor for new backtrace |
2062 // constructor for new backtrace |
2047 BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL) { |
2063 BacktraceBuilder(TRAPS): _head(NULL), _methods(NULL), _bcis(NULL), _mirrors(NULL), _names(NULL), _has_hidden_top_frame(NULL) { |
2048 expand(CHECK); |
2064 expand(CHECK); |
2049 _backtrace = Handle(THREAD, _head); |
2065 _backtrace = Handle(THREAD, _head); |
2050 _index = 0; |
2066 _index = 0; |
2051 } |
2067 } |
2052 |
2068 |
2053 BacktraceBuilder(Thread* thread, objArrayHandle backtrace) { |
2069 BacktraceBuilder(Thread* thread, objArrayHandle backtrace) { |
2054 _methods = get_methods(backtrace); |
2070 _methods = get_methods(backtrace); |
2055 _bcis = get_bcis(backtrace); |
2071 _bcis = get_bcis(backtrace); |
2056 _mirrors = get_mirrors(backtrace); |
2072 _mirrors = get_mirrors(backtrace); |
2057 _names = get_names(backtrace); |
2073 _names = get_names(backtrace); |
|
2074 _has_hidden_top_frame = get_has_hidden_top_frame(backtrace); |
2058 assert(_methods->length() == _bcis->length() && |
2075 assert(_methods->length() == _bcis->length() && |
2059 _methods->length() == _mirrors->length() && |
2076 _methods->length() == _mirrors->length() && |
2060 _mirrors->length() == _names->length(), |
2077 _mirrors->length() == _names->length(), |
2061 "method and source information arrays should match"); |
2078 "method and source information arrays should match"); |
2062 |
2079 |
2090 } |
2107 } |
2091 new_head->obj_at_put(trace_methods_offset, new_methods()); |
2108 new_head->obj_at_put(trace_methods_offset, new_methods()); |
2092 new_head->obj_at_put(trace_bcis_offset, new_bcis()); |
2109 new_head->obj_at_put(trace_bcis_offset, new_bcis()); |
2093 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); |
2110 new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); |
2094 new_head->obj_at_put(trace_names_offset, new_names()); |
2111 new_head->obj_at_put(trace_names_offset, new_names()); |
|
2112 new_head->obj_at_put(trace_hidden_offset, NULL); |
2095 |
2113 |
2096 _head = new_head(); |
2114 _head = new_head(); |
2097 _methods = new_methods(); |
2115 _methods = new_methods(); |
2098 _bcis = new_bcis(); |
2116 _bcis = new_bcis(); |
2099 _mirrors = new_mirrors(); |
2117 _mirrors = new_mirrors(); |
2128 // We need to save the mirrors in the backtrace to keep the class |
2146 // We need to save the mirrors in the backtrace to keep the class |
2129 // from being unloaded while we still have this stack trace. |
2147 // from being unloaded while we still have this stack trace. |
2130 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); |
2148 assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror"); |
2131 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); |
2149 _mirrors->obj_at_put(_index, method->method_holder()->java_mirror()); |
2132 _index++; |
2150 _index++; |
|
2151 } |
|
2152 |
|
2153 void set_has_hidden_top_frame(TRAPS) { |
|
2154 if (_has_hidden_top_frame == NULL) { |
|
2155 jvalue prim; |
|
2156 prim.z = 1; |
|
2157 PauseNoSafepointVerifier pnsv(&_nsv); |
|
2158 _has_hidden_top_frame = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK); |
|
2159 _head->obj_at_put(trace_hidden_offset, _has_hidden_top_frame); |
|
2160 } |
2133 } |
2161 } |
2134 |
2162 |
2135 }; |
2163 }; |
2136 |
2164 |
2137 struct BacktraceElement : public StackObj { |
2165 struct BacktraceElement : public StackObj { |
2459 // there are none or we've seen them all - either way stop checking |
2487 // there are none or we've seen them all - either way stop checking |
2460 skip_throwableInit_check = true; |
2488 skip_throwableInit_check = true; |
2461 } |
2489 } |
2462 } |
2490 } |
2463 if (method->is_hidden()) { |
2491 if (method->is_hidden()) { |
2464 if (skip_hidden) continue; |
2492 if (skip_hidden) { |
|
2493 if (total_count == 0) { |
|
2494 // The top frame will be hidden from the stack trace. |
|
2495 bt.set_has_hidden_top_frame(CHECK); |
|
2496 } |
|
2497 continue; |
|
2498 } |
2465 } |
2499 } |
2466 bt.push(method, bci, CHECK); |
2500 bt.push(method, bci, CHECK); |
2467 total_count++; |
2501 total_count++; |
2468 } |
2502 } |
2469 |
2503 |