comparison src/share/vm/utilities/decoder.cpp @ 4803:d7e3846464d0

7071311: Decoder enhancement Summary: Made decoder thread-safe Reviewed-by: coleenp, kamg
author zgu
date Tue, 17 Jan 2012 13:08:52 -0500
parents f08d439fab8c
children db006a85bf91
comparison
equal deleted inserted replaced
4801:4f3ce9284781 4803:d7e3846464d0
22 * 22 *
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 "utilities/decoder.hpp" 28 #include "utilities/decoder.hpp"
28 29
29 Decoder::decoder_status Decoder::_decoder_status = Decoder::no_error; 30 #if defined(_WINDOWS)
30 bool Decoder::_initialized = false; 31 #include "decoder_windows.hpp"
32 #elif defined(__APPLE__)
33 #include "decoder_machO.hpp"
34 #else
35 #include "decoder_elf.hpp"
36 #endif
31 37
32 #if !defined(_WINDOWS) && !defined(__APPLE__) 38 NullDecoder* Decoder::_decoder = NULL;
39 NullDecoder Decoder::_do_nothing_decoder;
40 Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
41 "DecoderLock");
33 42
34 // Implementation of common functionalities among Solaris and Linux 43 // _decoder_lock should already acquired before enter this method
35 #include "utilities/elfFile.hpp" 44 NullDecoder* Decoder::get_decoder() {
45 assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
46 "Require DecoderLock to enter");
36 47
37 ElfFile* Decoder::_opened_elf_files = NULL; 48 if (_decoder != NULL) {
49 return _decoder;
50 }
51
52 // Decoder is a secondary service. Although, it is good to have,
53 // but we can live without it.
54 #if defined(_WINDOWS)
55 _decoder = new (std::nothrow) WindowsDecoder();
56 #elif defined (__APPLE__)
57 _decoder = new (std::nothrow)MachODecoder();
58 #else
59 _decoder = new (std::nothrow)ElfDecoder();
60 #endif
61
62 if (_decoder == NULL || _decoder->has_error()) {
63 if (_decoder != NULL) {
64 delete _decoder;
65 }
66 _decoder = &_do_nothing_decoder;
67 }
68 return _decoder;
69 }
70
71 bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
72 assert(_decoder_lock != NULL, "Just check");
73 MutexLockerEx locker(_decoder_lock, true);
74 NullDecoder* decoder = get_decoder();
75 assert(decoder != NULL, "null decoder");
76
77 return decoder->decode(addr, buf, buflen, offset, modulepath);
78 }
79
80 bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
81 assert(_decoder_lock != NULL, "Just check");
82 MutexLockerEx locker(_decoder_lock, true);
83 NullDecoder* decoder = get_decoder();
84 assert(decoder != NULL, "null decoder");
85 return decoder->demangle(symbol, buf, buflen);
86 }
38 87
39 bool Decoder::can_decode_C_frame_in_vm() { 88 bool Decoder::can_decode_C_frame_in_vm() {
40 return true; 89 assert(_decoder_lock != NULL, "Just check");
90 MutexLockerEx locker(_decoder_lock, true);
91 NullDecoder* decoder = get_decoder();
92 assert(decoder != NULL, "null decoder");
93 return decoder->can_decode_C_frame_in_vm();
41 } 94 }
42 95
43 void Decoder::initialize() { 96 // shutdown real decoder and replace it with
44 _initialized = true; 97 // _do_nothing_decoder
98 void Decoder::shutdown() {
99 assert(_decoder_lock != NULL, "Just check");
100 MutexLockerEx locker(_decoder_lock, true);
101
102 if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
103 delete _decoder;
104 }
105
106 _decoder = &_do_nothing_decoder;
45 } 107 }
46 108
47 void Decoder::uninitialize() {
48 if (_opened_elf_files != NULL) {
49 delete _opened_elf_files;
50 _opened_elf_files = NULL;
51 }
52 _initialized = false;
53 }
54
55 Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
56 if (_decoder_status != no_error) {
57 return _decoder_status;
58 }
59
60 ElfFile* file = get_elf_file(filepath);
61 if (_decoder_status != no_error) {
62 return _decoder_status;
63 }
64
65 const char* symbol = file->decode(addr, offset);
66 if (file->get_status() == out_of_memory) {
67 _decoder_status = out_of_memory;
68 return _decoder_status;
69 } else if (symbol != NULL) {
70 if (!demangle(symbol, buf, buflen)) {
71 jio_snprintf(buf, buflen, "%s", symbol);
72 }
73 return no_error;
74 } else {
75 return symbol_not_found;
76 }
77 }
78
79 ElfFile* Decoder::get_elf_file(const char* filepath) {
80 if (_decoder_status != no_error) {
81 return NULL;
82 }
83 ElfFile* file = _opened_elf_files;
84 while (file != NULL) {
85 if (file->same_elf_file(filepath)) {
86 return file;
87 }
88 file = file->m_next;
89 }
90
91 file = new ElfFile(filepath);
92 if (file == NULL) {
93 _decoder_status = out_of_memory;
94 }
95 if (_opened_elf_files != NULL) {
96 file->m_next = _opened_elf_files;
97 }
98
99 _opened_elf_files = file;
100 return file;
101 }
102
103 #endif