23 */ |
23 */ |
24 |
24 |
25 #ifndef SHARE_VM_UTILITIES_DEBUG_HPP |
25 #ifndef SHARE_VM_UTILITIES_DEBUG_HPP |
26 #define SHARE_VM_UTILITIES_DEBUG_HPP |
26 #define SHARE_VM_UTILITIES_DEBUG_HPP |
27 |
27 |
28 #include "utilities/globalDefinitions.hpp" |
28 #include "utilities/breakpoint.hpp" |
29 #include "prims/jvm.h" |
29 #include "utilities/compilerWarnings.hpp" |
30 |
30 #include "utilities/macros.hpp" |
31 #include <stdarg.h> |
31 |
32 |
32 #include <stddef.h> |
33 // Simple class to format the ctor arguments into a fixed-sized buffer. |
|
34 class FormatBufferBase { |
|
35 protected: |
|
36 char* _buf; |
|
37 inline FormatBufferBase(char* buf) : _buf(buf) {} |
|
38 public: |
|
39 static const int BufferSize = 256; |
|
40 operator const char *() const { return _buf; } |
|
41 }; |
|
42 |
|
43 // Use resource area for buffer |
|
44 class FormatBufferResource : public FormatBufferBase { |
|
45 public: |
|
46 FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); |
|
47 }; |
|
48 |
|
49 class FormatBufferDummy {}; |
|
50 |
|
51 // Use stack for buffer |
|
52 template <size_t bufsz = FormatBufferBase::BufferSize> |
|
53 class FormatBuffer : public FormatBufferBase { |
|
54 public: |
|
55 inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
|
56 // since va_list is unspecified type (can be char*), we use FormatBufferDummy to disambiguate these constructors |
|
57 inline FormatBuffer(FormatBufferDummy dummy, const char* format, va_list ap) ATTRIBUTE_PRINTF(3, 0); |
|
58 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
|
59 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
|
60 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); |
|
61 |
|
62 char* buffer() { return _buf; } |
|
63 int size() { return bufsz; } |
|
64 |
|
65 private: |
|
66 FormatBuffer(const FormatBuffer &); // prevent copies |
|
67 char _buffer[bufsz]; |
|
68 |
|
69 protected: |
|
70 inline FormatBuffer(); |
|
71 }; |
|
72 |
|
73 template <size_t bufsz> |
|
74 FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) { |
|
75 va_list argp; |
|
76 va_start(argp, format); |
|
77 jio_vsnprintf(_buf, bufsz, format, argp); |
|
78 va_end(argp); |
|
79 } |
|
80 |
|
81 template <size_t bufsz> |
|
82 FormatBuffer<bufsz>::FormatBuffer(FormatBufferDummy dummy, const char * format, va_list ap) : FormatBufferBase(_buffer) { |
|
83 jio_vsnprintf(_buf, bufsz, format, ap); |
|
84 } |
|
85 |
|
86 template <size_t bufsz> |
|
87 FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) { |
|
88 _buf[0] = '\0'; |
|
89 } |
|
90 |
|
91 template <size_t bufsz> |
|
92 void FormatBuffer<bufsz>::print(const char * format, ...) { |
|
93 va_list argp; |
|
94 va_start(argp, format); |
|
95 jio_vsnprintf(_buf, bufsz, format, argp); |
|
96 va_end(argp); |
|
97 } |
|
98 |
|
99 template <size_t bufsz> |
|
100 void FormatBuffer<bufsz>::printv(const char * format, va_list argp) { |
|
101 jio_vsnprintf(_buf, bufsz, format, argp); |
|
102 } |
|
103 |
|
104 template <size_t bufsz> |
|
105 void FormatBuffer<bufsz>::append(const char* format, ...) { |
|
106 // Given that the constructor does a vsnprintf we can assume that |
|
107 // _buf is already initialized. |
|
108 size_t len = strlen(_buf); |
|
109 char* buf_end = _buf + len; |
|
110 |
|
111 va_list argp; |
|
112 va_start(argp, format); |
|
113 jio_vsnprintf(buf_end, bufsz - len, format, argp); |
|
114 va_end(argp); |
|
115 } |
|
116 |
|
117 // Used to format messages. |
|
118 typedef FormatBuffer<> err_msg; |
|
119 |
33 |
120 // assertions |
34 // assertions |
121 #ifndef ASSERT |
35 #ifndef ASSERT |
122 #define vmassert(p, ...) |
36 #define vmassert(p, ...) |
123 #else |
37 #else |