Mercurial > hg > truffle
annotate src/share/vm/runtime/signature.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
2 * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_signature.cpp.incl" | |
27 | |
28 | |
29 // Implementation of SignatureIterator | |
30 | |
31 // Signature syntax: | |
32 // | |
33 // Signature = "(" {Parameter} ")" ReturnType. | |
34 // Parameter = FieldType. | |
35 // ReturnType = FieldType | "V". | |
36 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. | |
37 // ClassName = string. | |
38 | |
39 | |
40 SignatureIterator::SignatureIterator(symbolHandle signature) { | |
41 assert(signature->is_symbol(), "not a symbol"); | |
42 _signature = signature; | |
43 _parameter_index = 0; | |
44 } | |
45 | |
46 // Overloaded version called without handle | |
47 SignatureIterator::SignatureIterator(symbolOop signature) { | |
48 symbolHandle sh(Thread::current(), signature); | |
49 _signature = sh; | |
50 _parameter_index = 0; | |
51 } | |
52 | |
53 SignatureIterator::SignatureIterator(Thread *thread, symbolOop signature) { | |
54 symbolHandle sh(thread, signature); | |
55 _signature = sh; | |
56 _parameter_index = 0; | |
57 } | |
58 | |
59 void SignatureIterator::expect(char c) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
0
diff
changeset
|
60 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); |
0 | 61 _index++; |
62 } | |
63 | |
64 | |
65 void SignatureIterator::skip_optional_size() { | |
66 symbolOop sig = _signature(); | |
67 char c = sig->byte_at(_index); | |
68 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); | |
69 } | |
70 | |
71 | |
72 int SignatureIterator::parse_type() { | |
73 // Note: This function could be simplified by using "return T_XXX_size;" | |
74 // instead of the assignment and the break statements. However, it | |
75 // seems that the product build for win32_i486 with MS VC++ 6.0 doesn't | |
76 // work (stack underflow for some tests) - this seems to be a VC++ 6.0 | |
77 // compiler bug (was problem - gri 4/27/2000). | |
78 int size = -1; | |
79 switch(_signature->byte_at(_index)) { | |
80 case 'B': do_byte (); if (_parameter_index < 0 ) _return_type = T_BYTE; | |
81 _index++; size = T_BYTE_size ; break; | |
82 case 'C': do_char (); if (_parameter_index < 0 ) _return_type = T_CHAR; | |
83 _index++; size = T_CHAR_size ; break; | |
84 case 'D': do_double(); if (_parameter_index < 0 ) _return_type = T_DOUBLE; | |
85 _index++; size = T_DOUBLE_size ; break; | |
86 case 'F': do_float (); if (_parameter_index < 0 ) _return_type = T_FLOAT; | |
87 _index++; size = T_FLOAT_size ; break; | |
88 case 'I': do_int (); if (_parameter_index < 0 ) _return_type = T_INT; | |
89 _index++; size = T_INT_size ; break; | |
90 case 'J': do_long (); if (_parameter_index < 0 ) _return_type = T_LONG; | |
91 _index++; size = T_LONG_size ; break; | |
92 case 'S': do_short (); if (_parameter_index < 0 ) _return_type = T_SHORT; | |
93 _index++; size = T_SHORT_size ; break; | |
94 case 'Z': do_bool (); if (_parameter_index < 0 ) _return_type = T_BOOLEAN; | |
95 _index++; size = T_BOOLEAN_size; break; | |
96 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; | |
97 _index++; size = T_VOID_size; ; break; | |
98 case 'L': | |
99 { int begin = ++_index; | |
100 symbolOop sig = _signature(); | |
101 while (sig->byte_at(_index++) != ';') ; | |
102 do_object(begin, _index); | |
103 } | |
104 if (_parameter_index < 0 ) _return_type = T_OBJECT; | |
105 size = T_OBJECT_size; | |
106 break; | |
107 case '[': | |
108 { int begin = ++_index; | |
109 skip_optional_size(); | |
110 symbolOop sig = _signature(); | |
111 while (sig->byte_at(_index) == '[') { | |
112 _index++; | |
113 skip_optional_size(); | |
114 } | |
115 if (sig->byte_at(_index) == 'L') { | |
116 while (sig->byte_at(_index++) != ';') ; | |
117 } else { | |
118 _index++; | |
119 } | |
120 do_array(begin, _index); | |
121 if (_parameter_index < 0 ) _return_type = T_ARRAY; | |
122 } | |
123 size = T_ARRAY_size; | |
124 break; | |
125 default: | |
126 ShouldNotReachHere(); | |
127 break; | |
128 } | |
129 assert(size >= 0, "size must be set"); | |
130 return size; | |
131 } | |
132 | |
133 | |
134 void SignatureIterator::check_signature_end() { | |
135 if (_index < _signature->utf8_length()) { | |
136 tty->print_cr("too many chars in signature"); | |
137 _signature->print_value_on(tty); | |
138 tty->print_cr(" @ %d", _index); | |
139 } | |
140 } | |
141 | |
142 | |
143 void SignatureIterator::dispatch_field() { | |
144 // no '(', just one (field) type | |
145 _index = 0; | |
146 _parameter_index = 0; | |
147 parse_type(); | |
148 check_signature_end(); | |
149 } | |
150 | |
151 | |
152 void SignatureIterator::iterate_parameters() { | |
153 // Parse parameters | |
154 _index = 0; | |
155 _parameter_index = 0; | |
156 expect('('); | |
157 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); | |
158 expect(')'); | |
159 _parameter_index = 0; | |
160 } | |
161 | |
162 // Optimized version of iterat_parameters when fingerprint is known | |
163 void SignatureIterator::iterate_parameters( uint64_t fingerprint ) { | |
164 uint64_t saved_fingerprint = fingerprint; | |
165 | |
166 // Check for too many arguments | |
167 if ( fingerprint == UCONST64(-1) ) { | |
168 SignatureIterator::iterate_parameters(); | |
169 return; | |
170 } | |
171 | |
172 assert(fingerprint, "Fingerprint should not be 0"); | |
173 | |
174 _parameter_index = 0; | |
175 fingerprint = fingerprint >> (static_feature_size + result_feature_size); | |
176 while ( 1 ) { | |
177 switch ( fingerprint & parameter_feature_mask ) { | |
178 case bool_parm: | |
179 do_bool(); | |
180 _parameter_index += T_BOOLEAN_size; | |
181 break; | |
182 case byte_parm: | |
183 do_byte(); | |
184 _parameter_index += T_BYTE_size; | |
185 break; | |
186 case char_parm: | |
187 do_char(); | |
188 _parameter_index += T_CHAR_size; | |
189 break; | |
190 case short_parm: | |
191 do_short(); | |
192 _parameter_index += T_SHORT_size; | |
193 break; | |
194 case int_parm: | |
195 do_int(); | |
196 _parameter_index += T_INT_size; | |
197 break; | |
198 case obj_parm: | |
199 do_object(0, 0); | |
200 _parameter_index += T_OBJECT_size; | |
201 break; | |
202 case long_parm: | |
203 do_long(); | |
204 _parameter_index += T_LONG_size; | |
205 break; | |
206 case float_parm: | |
207 do_float(); | |
208 _parameter_index += T_FLOAT_size; | |
209 break; | |
210 case double_parm: | |
211 do_double(); | |
212 _parameter_index += T_DOUBLE_size; | |
213 break; | |
214 case done_parm: | |
215 return; | |
216 break; | |
217 default: | |
218 tty->print_cr("*** parameter is %d", fingerprint & parameter_feature_mask); | |
219 tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint); | |
220 ShouldNotReachHere(); | |
221 break; | |
222 } | |
223 fingerprint >>= parameter_feature_size; | |
224 } | |
225 _parameter_index = 0; | |
226 } | |
227 | |
228 | |
229 void SignatureIterator::iterate_returntype() { | |
230 // Ignore parameters | |
231 _index = 0; | |
232 expect('('); | |
233 symbolOop sig = _signature(); | |
234 while (sig->byte_at(_index) != ')') _index++; | |
235 expect(')'); | |
236 // Parse return type | |
237 _parameter_index = -1; | |
238 parse_type(); | |
239 check_signature_end(); | |
240 _parameter_index = 0; | |
241 } | |
242 | |
243 | |
244 void SignatureIterator::iterate() { | |
245 // Parse parameters | |
246 _parameter_index = 0; | |
247 _index = 0; | |
248 expect('('); | |
249 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); | |
250 expect(')'); | |
251 // Parse return type | |
252 _parameter_index = -1; | |
253 parse_type(); | |
254 check_signature_end(); | |
255 _parameter_index = 0; | |
256 } | |
257 | |
258 | |
259 // Implementation of SignatureStream | |
260 | |
261 bool SignatureStream::is_done() const { | |
262 return _end > _signature()->utf8_length(); | |
263 } | |
264 | |
265 | |
266 void SignatureStream::next_non_primitive(int t) { | |
267 switch (t) { | |
268 case 'L': { | |
269 _type = T_OBJECT; | |
270 symbolOop sig = _signature(); | |
271 while (sig->byte_at(_end++) != ';'); | |
272 break; | |
273 } | |
274 case '[': { | |
275 _type = T_ARRAY; | |
276 symbolOop sig = _signature(); | |
277 char c = sig->byte_at(_end); | |
278 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); | |
279 while (sig->byte_at(_end) == '[') { | |
280 _end++; | |
281 c = sig->byte_at(_end); | |
282 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); | |
283 } | |
284 switch(sig->byte_at(_end)) { | |
285 case 'B': | |
286 case 'C': | |
287 case 'D': | |
288 case 'F': | |
289 case 'I': | |
290 case 'J': | |
291 case 'S': | |
292 case 'Z':_end++; break; | |
293 default: { | |
294 while (sig->byte_at(_end++) != ';'); | |
295 break; | |
296 } | |
297 } | |
298 break; | |
299 } | |
300 case ')': _end++; next(); _at_return_type = true; break; | |
301 default : ShouldNotReachHere(); | |
302 } | |
303 } | |
304 | |
305 | |
306 bool SignatureStream::is_object() const { | |
307 return _type == T_OBJECT | |
308 || _type == T_ARRAY; | |
309 } | |
310 | |
311 bool SignatureStream::is_array() const { | |
312 return _type == T_ARRAY; | |
313 } | |
314 | |
315 symbolOop SignatureStream::as_symbol(TRAPS) { | |
316 // Create a symbol from for string _begin _end | |
317 int begin = _begin; | |
318 int end = _end; | |
319 | |
320 if ( _signature()->byte_at(_begin) == 'L' | |
321 && _signature()->byte_at(_end-1) == ';') { | |
322 begin++; | |
323 end--; | |
324 } | |
325 | |
326 symbolOop result = oopFactory::new_symbol(_signature, begin, end, CHECK_NULL); | |
327 return result; | |
328 } | |
329 | |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
330 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
331 FailureMode failure_mode, TRAPS) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
332 if (!is_object()) return NULL; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
333 symbolOop name = as_symbol(CHECK_NULL); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
334 if (failure_mode == ReturnNull) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
335 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
336 } else { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
337 bool throw_error = (failure_mode == NCDFError); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
338 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
339 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
340 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
341 |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
342 oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
343 FailureMode failure_mode, TRAPS) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
344 if (!is_object()) |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
345 return Universe::java_mirror(type()); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
346 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
347 if (klass == NULL) return NULL; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
348 return Klass::cast(klass)->java_mirror(); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
349 } |
0 | 350 |
351 symbolOop SignatureStream::as_symbol_or_null() { | |
352 // Create a symbol from for string _begin _end | |
353 ResourceMark rm; | |
354 | |
355 int begin = _begin; | |
356 int end = _end; | |
357 | |
358 if ( _signature()->byte_at(_begin) == 'L' | |
359 && _signature()->byte_at(_end-1) == ';') { | |
360 begin++; | |
361 end--; | |
362 } | |
363 | |
364 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); | |
365 for (int index = begin; index < end; index++) { | |
366 buffer[index - begin] = _signature()->byte_at(index); | |
367 } | |
368 symbolOop result = SymbolTable::probe(buffer, end - begin); | |
369 return result; | |
370 } | |
371 | |
372 bool SignatureVerifier::is_valid_signature(symbolHandle sig) { | |
373 const char* signature = (const char*)sig->bytes(); | |
374 ssize_t len = sig->utf8_length(); | |
375 if (signature == NULL || signature[0] == '\0' || len < 1) { | |
376 return false; | |
377 } else if (signature[0] == '(') { | |
378 return is_valid_method_signature(sig); | |
379 } else { | |
380 return is_valid_type_signature(sig); | |
381 } | |
382 } | |
383 | |
384 bool SignatureVerifier::is_valid_method_signature(symbolHandle sig) { | |
385 const char* method_sig = (const char*)sig->bytes(); | |
386 ssize_t len = sig->utf8_length(); | |
387 ssize_t index = 0; | |
388 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { | |
389 ++index; | |
390 while (index < len && method_sig[index] != ')') { | |
391 ssize_t res = is_valid_type(&method_sig[index], len - index); | |
392 if (res == -1) { | |
393 return false; | |
394 } else { | |
395 index += res; | |
396 } | |
397 } | |
398 if (index < len && method_sig[index] == ')') { | |
399 // check the return type | |
400 ++index; | |
401 return (is_valid_type(&method_sig[index], len - index) == (len - index)); | |
402 } | |
403 } | |
404 return false; | |
405 } | |
406 | |
407 bool SignatureVerifier::is_valid_type_signature(symbolHandle sig) { | |
408 const char* type_sig = (const char*)sig->bytes(); | |
409 ssize_t len = sig->utf8_length(); | |
410 return (type_sig != NULL && len >= 1 && | |
411 (is_valid_type(type_sig, len) == len)); | |
412 } | |
413 | |
414 // Checks to see if the type (not to go beyond 'limit') refers to a valid type. | |
415 // Returns -1 if it is not, or the index of the next character that is not part | |
416 // of the type. The type encoding may end before 'limit' and that's ok. | |
417 ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) { | |
418 ssize_t index = 0; | |
419 | |
420 // Iterate over any number of array dimensions | |
421 while (index < limit && type[index] == '[') ++index; | |
422 if (index >= limit) { | |
423 return -1; | |
424 } | |
425 switch (type[index]) { | |
426 case 'B': case 'C': case 'D': case 'F': case 'I': | |
427 case 'J': case 'S': case 'Z': case 'V': | |
428 return index + 1; | |
429 case 'L': | |
430 for (index = index + 1; index < limit; ++index) { | |
431 char c = type[index]; | |
432 if (c == ';') { | |
433 return index + 1; | |
434 } | |
435 if (invalid_name_char(c)) { | |
436 return -1; | |
437 } | |
438 } | |
439 // fall through | |
440 default: ; // fall through | |
441 } | |
442 return -1; | |
443 } | |
444 | |
445 bool SignatureVerifier::invalid_name_char(char c) { | |
446 switch (c) { | |
447 case '\0': case '.': case ';': case '[': | |
448 return true; | |
449 default: | |
450 return false; | |
451 } | |
452 } |