Mercurial > hg > truffle
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 |