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