comparison src/share/vm/utilities/decoder.cpp @ 4917:db006a85bf91

7141259: Native stack is missing in hs_err Summary: Code cleanup and creating a private decoder for error handler, since it can be triggered from in signal handler, where no lock can be taken Reviewed-by: dholmes, kamg, acorn, coleenp
author zgu
date Thu, 09 Feb 2012 10:16:26 -0500
parents d7e3846464d0
children 3b01d0321dfa
comparison
equal deleted inserted replaced
4864:b2cd0ee8f778 4917:db006a85bf91
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "prims/jvm.h" 26 #include "prims/jvm.h"
27 #include "runtime/mutexLocker.hpp" 27 #include "runtime/mutexLocker.hpp"
28 #include "runtime/os.hpp"
28 #include "utilities/decoder.hpp" 29 #include "utilities/decoder.hpp"
30 #include "utilities/vmError.hpp"
29 31
30 #if defined(_WINDOWS) 32 #if defined(_WINDOWS)
31 #include "decoder_windows.hpp" 33 #include "decoder_windows.hpp"
32 #elif defined(__APPLE__) 34 #elif defined(__APPLE__)
33 #include "decoder_machO.hpp" 35 #include "decoder_machO.hpp"
34 #else 36 #else
35 #include "decoder_elf.hpp" 37 #include "decoder_elf.hpp"
36 #endif 38 #endif
37 39
38 NullDecoder* Decoder::_decoder = NULL; 40 AbstractDecoder* Decoder::_shared_decoder = NULL;
39 NullDecoder Decoder::_do_nothing_decoder; 41 AbstractDecoder* Decoder::_error_handler_decoder = NULL;
40 Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint, 42 NullDecoder Decoder::_do_nothing_decoder;
41 "DecoderLock"); 43 Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native,
44 "SharedDecoderLock");
42 45
43 // _decoder_lock should already acquired before enter this method 46 AbstractDecoder* Decoder::get_shared_instance() {
44 NullDecoder* Decoder::get_decoder() { 47 assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(),
45 assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
46 "Require DecoderLock to enter"); 48 "Require DecoderLock to enter");
47 49
48 if (_decoder != NULL) { 50 if (_shared_decoder == NULL) {
49 return _decoder; 51 _shared_decoder = create_decoder();
50 } 52 }
53 return _shared_decoder;
54 }
51 55
52 // Decoder is a secondary service. Although, it is good to have, 56 AbstractDecoder* Decoder::get_error_handler_instance() {
53 // but we can live without it. 57 if (_error_handler_decoder == NULL) {
58 _error_handler_decoder = create_decoder();
59 }
60 return _error_handler_decoder;
61 }
62
63
64 AbstractDecoder* Decoder::create_decoder() {
65 AbstractDecoder* decoder;
54 #if defined(_WINDOWS) 66 #if defined(_WINDOWS)
55 _decoder = new (std::nothrow) WindowsDecoder(); 67 decoder = new (std::nothrow) WindowsDecoder();
56 #elif defined (__APPLE__) 68 #elif defined (__APPLE__)
57 _decoder = new (std::nothrow)MachODecoder(); 69 decoder = new (std::nothrow)MachODecoder();
58 #else 70 #else
59 _decoder = new (std::nothrow)ElfDecoder(); 71 decoder = new (std::nothrow)ElfDecoder();
60 #endif 72 #endif
61 73
62 if (_decoder == NULL || _decoder->has_error()) { 74 if (decoder == NULL || decoder->has_error()) {
63 if (_decoder != NULL) { 75 if (decoder != NULL) {
64 delete _decoder; 76 delete decoder;
65 } 77 }
66 _decoder = &_do_nothing_decoder; 78 decoder = &_do_nothing_decoder;
67 } 79 }
68 return _decoder; 80 return decoder;
69 } 81 }
70 82
71 bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { 83 bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
72 assert(_decoder_lock != NULL, "Just check"); 84 assert(_shared_decoder_lock != NULL, "Just check");
73 MutexLockerEx locker(_decoder_lock, true); 85 bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
74 NullDecoder* decoder = get_decoder(); 86 MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
87 AbstractDecoder* decoder = error_handling_thread ?
88 get_error_handler_instance(): get_shared_instance();
75 assert(decoder != NULL, "null decoder"); 89 assert(decoder != NULL, "null decoder");
76 90
77 return decoder->decode(addr, buf, buflen, offset, modulepath); 91 return decoder->decode(addr, buf, buflen, offset, modulepath);
78 } 92 }
79 93
80 bool Decoder::demangle(const char* symbol, char* buf, int buflen) { 94 bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
81 assert(_decoder_lock != NULL, "Just check"); 95 assert(_shared_decoder_lock != NULL, "Just check");
82 MutexLockerEx locker(_decoder_lock, true); 96 bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
83 NullDecoder* decoder = get_decoder(); 97 MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
98 AbstractDecoder* decoder = error_handling_thread ?
99 get_error_handler_instance(): get_shared_instance();
84 assert(decoder != NULL, "null decoder"); 100 assert(decoder != NULL, "null decoder");
85 return decoder->demangle(symbol, buf, buflen); 101 return decoder->demangle(symbol, buf, buflen);
86 } 102 }
87 103
88 bool Decoder::can_decode_C_frame_in_vm() { 104 bool Decoder::can_decode_C_frame_in_vm() {
89 assert(_decoder_lock != NULL, "Just check"); 105 assert(_shared_decoder_lock != NULL, "Just check");
90 MutexLockerEx locker(_decoder_lock, true); 106 bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
91 NullDecoder* decoder = get_decoder(); 107 MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
108 AbstractDecoder* decoder = error_handling_thread ?
109 get_error_handler_instance(): get_shared_instance();
92 assert(decoder != NULL, "null decoder"); 110 assert(decoder != NULL, "null decoder");
93 return decoder->can_decode_C_frame_in_vm(); 111 return decoder->can_decode_C_frame_in_vm();
94 } 112 }
95 113
96 // shutdown real decoder and replace it with 114 /*
97 // _do_nothing_decoder 115 * Shutdown shared decoder and replace it with
116 * _do_nothing_decoder. Do nothing with error handler
117 * instance, since the JVM is going down.
118 */
98 void Decoder::shutdown() { 119 void Decoder::shutdown() {
99 assert(_decoder_lock != NULL, "Just check"); 120 assert(_shared_decoder_lock != NULL, "Just check");
100 MutexLockerEx locker(_decoder_lock, true); 121 MutexLockerEx locker(_shared_decoder_lock, true);
101 122
102 if (_decoder != NULL && _decoder != &_do_nothing_decoder) { 123 if (_shared_decoder != NULL &&
103 delete _decoder; 124 _shared_decoder != &_do_nothing_decoder) {
125 delete _shared_decoder;
104 } 126 }
105 127
106 _decoder = &_do_nothing_decoder; 128 _shared_decoder = &_do_nothing_decoder;
107 } 129 }
108 130