34 class FormatBufferBase { |
34 class FormatBufferBase { |
35 protected: |
35 protected: |
36 char* _buf; |
36 char* _buf; |
37 inline FormatBufferBase(char* buf) : _buf(buf) {} |
37 inline FormatBufferBase(char* buf) : _buf(buf) {} |
38 public: |
38 public: |
|
39 static const int BufferSize = 256; |
39 operator const char *() const { return _buf; } |
40 operator const char *() const { return _buf; } |
40 }; |
41 }; |
41 |
42 |
42 // Use resource area for buffer |
43 // Use resource area for buffer |
43 #define RES_BUFSZ 256 |
|
44 class FormatBufferResource : public FormatBufferBase { |
44 class FormatBufferResource : public FormatBufferBase { |
45 public: |
45 public: |
46 FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); |
46 FormatBufferResource(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); |
47 }; |
47 }; |
48 |
48 |
49 // Use stack for buffer |
49 // Use stack for buffer |
50 template <size_t bufsz = 256> |
50 template <size_t bufsz = FormatBufferBase::BufferSize> |
51 class FormatBuffer : public FormatBufferBase { |
51 class FormatBuffer : public FormatBufferBase { |
52 public: |
52 public: |
53 inline FormatBuffer(const char * format, ...) ATTRIBUTE_PRINTF(2, 3); |
53 inline FormatBuffer(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
54 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
54 inline void append(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
55 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
55 inline void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3); |
56 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); |
56 inline void printv(const char* format, va_list ap) ATTRIBUTE_PRINTF(2, 0); |
57 |
57 |
58 char* buffer() { return _buf; } |
58 char* buffer() { return _buf; } |
103 va_start(argp, format); |
103 va_start(argp, format); |
104 jio_vsnprintf(buf_end, bufsz - len, format, argp); |
104 jio_vsnprintf(buf_end, bufsz - len, format, argp); |
105 va_end(argp); |
105 va_end(argp); |
106 } |
106 } |
107 |
107 |
108 // Used to format messages for vmassert(), guarantee(), fatal(), etc. |
108 // Used to format messages. |
109 typedef FormatBuffer<> err_msg; |
109 typedef FormatBuffer<> err_msg; |
110 typedef FormatBufferResource err_msg_res; |
|
111 |
110 |
112 // assertions |
111 // assertions |
113 #ifndef ASSERT |
112 #ifndef ASSERT |
114 #define vmassert(p, msg) |
113 #define vmassert(p, ...) |
115 #else |
114 #else |
116 // Note: message says "assert" rather than "vmassert" for backward |
115 // Note: message says "assert" rather than "vmassert" for backward |
117 // compatibility with tools that parse/match the message text. |
116 // compatibility with tools that parse/match the message text. |
118 #define vmassert(p, msg) \ |
117 // Note: The signature is vmassert(p, format, ...), but the solaris |
119 do { \ |
118 // compiler can't handle an empty ellipsis in a macro without a warning. |
120 if (!(p)) { \ |
119 #define vmassert(p, ...) \ |
121 report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \ |
120 do { \ |
122 BREAKPOINT; \ |
121 if (!(p)) { \ |
123 } \ |
122 report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", __VA_ARGS__); \ |
124 } while (0) |
123 BREAKPOINT; \ |
|
124 } \ |
|
125 } while (0) |
|
126 |
125 #endif |
127 #endif |
126 |
128 |
127 // For backward compatibility. |
129 // For backward compatibility. |
128 #define assert(p, msg) vmassert(p, msg) |
130 #define assert(p, ...) vmassert(p, __VA_ARGS__) |
129 |
131 |
130 // This version of vmassert is for use with checking return status from |
132 // This version of vmassert is for use with checking return status from |
131 // library calls that return actual error values eg. EINVAL, |
133 // library calls that return actual error values eg. EINVAL, |
132 // ENOMEM etc, rather than returning -1 and setting errno. |
134 // ENOMEM etc, rather than returning -1 and setting errno. |
133 // When the status is not what is expected it is very useful to know |
135 // When the status is not what is expected it is very useful to know |
134 // what status was actually returned, so we pass the status variable as |
136 // what status was actually returned, so we pass the status variable as |
135 // an extra arg and use strerror to convert it to a meaningful string |
137 // an extra arg and use strerror to convert it to a meaningful string |
136 // like "Invalid argument", "out of memory" etc |
138 // like "Invalid argument", "out of memory" etc |
137 #define vmassert_status(p, status, msg) \ |
139 #define vmassert_status(p, status, msg) \ |
138 vmassert(p, err_msg("error %s(%d), %s", strerror(status), status, msg)) |
140 vmassert(p, "error %s(%d), %s", strerror(status), status, msg) |
139 |
141 |
140 // For backward compatibility. |
142 // For backward compatibility. |
141 #define assert_status(p, status, msg) vmassert_status(p, status, msg) |
143 #define assert_status(p, status, msg) vmassert_status(p, status, msg) |
142 |
144 |
143 // guarantee is like vmassert except it's always executed -- use it for |
145 // guarantee is like vmassert except it's always executed -- use it for |
144 // cheap tests that catch errors that would otherwise be hard to find. |
146 // cheap tests that catch errors that would otherwise be hard to find. |
145 // guarantee is also used for Verify options. |
147 // guarantee is also used for Verify options. |
146 #define guarantee(p, msg) \ |
148 #define guarantee(p, ...) \ |
147 do { \ |
149 do { \ |
148 if (!(p)) { \ |
150 if (!(p)) { \ |
149 report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", msg); \ |
151 report_vm_error(__FILE__, __LINE__, "guarantee(" #p ") failed", __VA_ARGS__); \ |
150 BREAKPOINT; \ |
152 BREAKPOINT; \ |
151 } \ |
153 } \ |
152 } while (0) |
154 } while (0) |
153 |
155 |
154 #define fatal(msg) \ |
156 #define fatal(...) \ |
155 do { \ |
157 do { \ |
156 report_fatal(__FILE__, __LINE__, msg); \ |
158 report_fatal(__FILE__, __LINE__, __VA_ARGS__); \ |
157 BREAKPOINT; \ |
159 BREAKPOINT; \ |
158 } while (0) |
160 } while (0) |
159 |
161 |
160 // out of memory |
162 // out of memory |
161 #define vm_exit_out_of_memory(size, vm_err_type, msg) \ |
163 #define vm_exit_out_of_memory(size, vm_err_type, ...) \ |
162 do { \ |
164 do { \ |
163 report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, msg); \ |
165 report_vm_out_of_memory(__FILE__, __LINE__, size, vm_err_type, __VA_ARGS__); \ |
164 BREAKPOINT; \ |
166 BREAKPOINT; \ |
165 } while (0) |
167 } while (0) |
166 |
168 |
167 #define ShouldNotCallThis() \ |
169 #define ShouldNotCallThis() \ |
168 do { \ |
170 do { \ |
169 report_should_not_call(__FILE__, __LINE__); \ |
171 report_should_not_call(__FILE__, __LINE__); \ |
170 BREAKPOINT; \ |
172 BREAKPOINT; \ |
171 } while (0) |
173 } while (0) |
172 |
174 |
173 #define ShouldNotReachHere() \ |
175 #define ShouldNotReachHere() \ |
174 do { \ |
176 do { \ |
175 report_should_not_reach_here(__FILE__, __LINE__); \ |
177 report_should_not_reach_here(__FILE__, __LINE__); \ |
176 BREAKPOINT; \ |
178 BREAKPOINT; \ |
177 } while (0) |
179 } while (0) |
178 |
180 |
179 #define Unimplemented() \ |
181 #define Unimplemented() \ |
180 do { \ |
182 do { \ |
181 report_unimplemented(__FILE__, __LINE__); \ |
183 report_unimplemented(__FILE__, __LINE__); \ |
182 BREAKPOINT; \ |
184 BREAKPOINT; \ |
183 } while (0) |
185 } while (0) |
184 |
186 |
185 #define Untested(msg) \ |
187 #define Untested(msg) \ |
186 do { \ |
188 do { \ |
187 report_untested(__FILE__, __LINE__, msg); \ |
189 report_untested(__FILE__, __LINE__, msg); \ |
188 BREAKPOINT; \ |
190 BREAKPOINT; \ |
189 } while (0); |
191 } while (0); |
190 |
192 |
191 |
193 |
192 // types of VM error - originally in vmError.hpp |
194 // types of VM error - originally in vmError.hpp |
193 enum VMErrorType { |
195 enum VMErrorType { |
195 OOM_MALLOC_ERROR = 0xe0000001, |
197 OOM_MALLOC_ERROR = 0xe0000001, |
196 OOM_MMAP_ERROR = 0xe0000002 |
198 OOM_MMAP_ERROR = 0xe0000002 |
197 }; |
199 }; |
198 |
200 |
199 // error reporting helper functions |
201 // error reporting helper functions |
|
202 void report_vm_error(const char* file, int line, const char* error_msg); |
200 void report_vm_error(const char* file, int line, const char* error_msg, |
203 void report_vm_error(const char* file, int line, const char* error_msg, |
201 const char* detail_msg = NULL); |
204 const char* detail_fmt, ...) ATTRIBUTE_PRINTF(4, 5); |
202 void report_fatal(const char* file, int line, const char* message); |
205 void report_fatal(const char* file, int line, const char* detail_fmt, ...) ATTRIBUTE_PRINTF(3, 4); |
203 void report_vm_out_of_memory(const char* file, int line, size_t size, |
206 void report_vm_out_of_memory(const char* file, int line, size_t size, VMErrorType vm_err_type, |
204 VMErrorType vm_err_type, const char* message); |
207 const char* detail_fmt, ...) ATTRIBUTE_PRINTF(5, 6); |
205 void report_should_not_call(const char* file, int line); |
208 void report_should_not_call(const char* file, int line); |
206 void report_should_not_reach_here(const char* file, int line); |
209 void report_should_not_reach_here(const char* file, int line); |
207 void report_unimplemented(const char* file, int line); |
210 void report_unimplemented(const char* file, int line); |
208 void report_untested(const char* file, int line, const char* message); |
211 void report_untested(const char* file, int line, const char* message); |
209 |
212 |