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 |