Mercurial > hg > truffle
annotate src/share/vm/runtime/signature.hpp @ 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 | 126ea7725993 |
children | f95d63e2154a |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
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:
1508
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
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:
1508
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 // SignatureIterators iterate over a Java signature (or parts of it). | |
26 // (Syntax according to: "The Java Virtual Machine Specification" by | |
27 // Tim Lindholm & Frank Yellin; section 4.3 Descriptors; p. 89ff.) | |
28 // | |
29 // Example: Iterating over ([Lfoo;D)I using | |
30 // 0123456789 | |
31 // | |
32 // iterate_parameters() calls: do_array(2, 7); do_double(); | |
33 // iterate_returntype() calls: do_int(); | |
34 // iterate() calls: do_array(2, 7); do_double(); do_int(); | |
35 // | |
36 // is_return_type() is: false ; false ; true | |
37 // | |
38 // NOTE: The new optimizer has an alternate, for-loop based signature | |
39 // iterator implemented in opto/type.cpp, TypeTuple::make(). | |
40 | |
41 class SignatureIterator: public ResourceObj { | |
42 protected: | |
43 symbolHandle _signature; // the signature to iterate over | |
44 int _index; // the current character index (only valid during iteration) | |
45 int _parameter_index; // the current parameter index (0 outside iteration phase) | |
46 BasicType _return_type; | |
47 | |
48 void expect(char c); | |
49 void skip_optional_size(); | |
50 int parse_type(); // returns the parameter size in words (0 for void) | |
51 void check_signature_end(); | |
52 | |
53 public: | |
54 // Definitions used in generating and iterating the | |
55 // bit field form of the signature generated by the | |
56 // Fingerprinter. | |
57 enum { | |
58 static_feature_size = 1, | |
59 result_feature_size = 4, | |
60 result_feature_mask = 0xF, | |
61 parameter_feature_size = 4, | |
62 parameter_feature_mask = 0xF, | |
63 | |
64 bool_parm = 1, | |
65 byte_parm = 2, | |
66 char_parm = 3, | |
67 short_parm = 4, | |
68 int_parm = 5, | |
69 long_parm = 6, | |
70 float_parm = 7, | |
71 double_parm = 8, | |
72 obj_parm = 9, | |
73 done_parm = 10, // marker for end of parameters | |
74 | |
75 // max parameters is wordsize minus | |
76 // The sign bit, termination field, the result and static bit fields | |
77 max_size_of_parameters = (BitsPerLong-1 - | |
78 result_feature_size - parameter_feature_size - | |
79 static_feature_size) / parameter_feature_size | |
80 }; | |
81 | |
82 // Constructors | |
83 SignatureIterator(symbolOop signature); | |
84 SignatureIterator(Thread *thread, symbolOop signature); | |
85 SignatureIterator(symbolHandle signature); | |
86 | |
87 // Iteration | |
88 void dispatch_field(); // dispatches once for field signatures | |
89 void iterate_parameters(); // iterates over parameters only | |
90 void iterate_parameters( uint64_t fingerprint ); | |
91 void iterate_returntype(); // iterates over returntype only | |
92 void iterate(); // iterates over whole signature | |
93 // Returns the word index of the current parameter; | |
94 int parameter_index() const { return _parameter_index; } | |
95 bool is_return_type() const { return parameter_index() < 0; } | |
96 BasicType get_ret_type() const { return _return_type; } | |
97 | |
98 // Basic types | |
99 virtual void do_bool () = 0; | |
100 virtual void do_char () = 0; | |
101 virtual void do_float () = 0; | |
102 virtual void do_double() = 0; | |
103 virtual void do_byte () = 0; | |
104 virtual void do_short () = 0; | |
105 virtual void do_int () = 0; | |
106 virtual void do_long () = 0; | |
107 virtual void do_void () = 0; | |
108 | |
109 // Object types (begin indexes the first character of the entry, end indexes the first character after the entry) | |
110 virtual void do_object(int begin, int end) = 0; | |
111 virtual void do_array (int begin, int end) = 0; | |
112 }; | |
113 | |
114 | |
115 // Specialized SignatureIterators: Used to compute signature specific values. | |
116 | |
117 class SignatureTypeNames : public SignatureIterator { | |
118 protected: | |
119 virtual void type_name(const char* name) = 0; | |
120 | |
121 void do_bool() { type_name("jboolean"); } | |
122 void do_char() { type_name("jchar" ); } | |
123 void do_float() { type_name("jfloat" ); } | |
124 void do_double() { type_name("jdouble" ); } | |
125 void do_byte() { type_name("jbyte" ); } | |
126 void do_short() { type_name("jshort" ); } | |
127 void do_int() { type_name("jint" ); } | |
128 void do_long() { type_name("jlong" ); } | |
129 void do_void() { type_name("void" ); } | |
130 void do_object(int begin, int end) { type_name("jobject" ); } | |
131 void do_array (int begin, int end) { type_name("jobject" ); } | |
132 | |
133 public: | |
134 SignatureTypeNames(symbolHandle signature) : SignatureIterator(signature) {} | |
135 }; | |
136 | |
137 | |
138 class SignatureInfo: public SignatureIterator { | |
139 protected: | |
140 bool _has_iterated; // need this because iterate cannot be called in constructor (set is virtual!) | |
141 bool _has_iterated_return; | |
142 int _size; | |
143 | |
144 void lazy_iterate_parameters() { if (!_has_iterated) { iterate_parameters(); _has_iterated = true; } } | |
145 void lazy_iterate_return() { if (!_has_iterated_return) { iterate_returntype(); _has_iterated_return = true; } } | |
146 | |
147 virtual void set(int size, BasicType type) = 0; | |
148 | |
149 void do_bool () { set(T_BOOLEAN_size, T_BOOLEAN); } | |
150 void do_char () { set(T_CHAR_size , T_CHAR ); } | |
151 void do_float () { set(T_FLOAT_size , T_FLOAT ); } | |
152 void do_double() { set(T_DOUBLE_size , T_DOUBLE ); } | |
153 void do_byte () { set(T_BYTE_size , T_BYTE ); } | |
154 void do_short () { set(T_SHORT_size , T_SHORT ); } | |
155 void do_int () { set(T_INT_size , T_INT ); } | |
156 void do_long () { set(T_LONG_size , T_LONG ); } | |
157 void do_void () { set(T_VOID_size , T_VOID ); } | |
158 void do_object(int begin, int end) { set(T_OBJECT_size , T_OBJECT ); } | |
159 void do_array (int begin, int end) { set(T_ARRAY_size , T_ARRAY ); } | |
160 | |
161 public: | |
162 SignatureInfo(symbolHandle signature) : SignatureIterator(signature) { | |
163 _has_iterated = _has_iterated_return = false; | |
164 _size = 0; | |
165 _return_type = T_ILLEGAL; | |
166 } | |
167 | |
168 }; | |
169 | |
170 | |
171 // Specialized SignatureIterator: Used to compute the argument size. | |
172 | |
173 class ArgumentSizeComputer: public SignatureInfo { | |
174 private: | |
175 void set(int size, BasicType type) { _size += size; } | |
176 public: | |
177 ArgumentSizeComputer(symbolHandle signature) : SignatureInfo(signature) {} | |
178 | |
179 int size() { lazy_iterate_parameters(); return _size; } | |
180 }; | |
181 | |
182 | |
183 class ArgumentCount: public SignatureInfo { | |
184 private: | |
185 void set(int size, BasicType type) { _size ++; } | |
186 public: | |
187 ArgumentCount(symbolHandle signature) : SignatureInfo(signature) {} | |
188 | |
189 int size() { lazy_iterate_parameters(); return _size; } | |
190 }; | |
191 | |
192 | |
193 // Specialized SignatureIterator: Used to compute the result type. | |
194 | |
195 class ResultTypeFinder: public SignatureInfo { | |
196 private: | |
197 void set(int size, BasicType type) { _return_type = type; } | |
198 public: | |
199 BasicType type() { lazy_iterate_return(); return _return_type; } | |
200 | |
201 ResultTypeFinder(symbolHandle signature) : SignatureInfo(signature) {} | |
202 }; | |
203 | |
204 | |
205 // Fingerprinter computes a unique ID for a given method. The ID | |
206 // is a bitvector characterizing the methods signature (incl. the receiver). | |
207 class Fingerprinter: public SignatureIterator { | |
208 private: | |
209 uint64_t _fingerprint; | |
210 int _shift_count; | |
211 methodHandle mh; | |
212 | |
213 public: | |
214 | |
215 void do_bool() { _fingerprint |= (((uint64_t)bool_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
216 void do_char() { _fingerprint |= (((uint64_t)char_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
217 void do_byte() { _fingerprint |= (((uint64_t)byte_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
218 void do_short() { _fingerprint |= (((uint64_t)short_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
219 void do_int() { _fingerprint |= (((uint64_t)int_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
220 void do_long() { _fingerprint |= (((uint64_t)long_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
221 void do_float() { _fingerprint |= (((uint64_t)float_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
222 void do_double() { _fingerprint |= (((uint64_t)double_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
223 | |
224 void do_object(int begin, int end) { _fingerprint |= (((uint64_t)obj_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
225 void do_array (int begin, int end) { _fingerprint |= (((uint64_t)obj_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
226 | |
227 void do_void() { ShouldNotReachHere(); } | |
228 | |
229 Fingerprinter(methodHandle method) : SignatureIterator(method->signature()) { | |
230 mh = method; | |
231 _fingerprint = 0; | |
232 } | |
233 | |
234 Fingerprinter(Thread *thread, methodHandle method) : SignatureIterator(thread, method->signature()) { | |
235 mh = method; | |
236 _fingerprint = 0; | |
237 } | |
238 | |
239 uint64_t fingerprint() { | |
240 // See if we fingerprinted this method already | |
241 if (mh->constMethod()->fingerprint() != CONST64(0)) { | |
242 return mh->constMethod()->fingerprint(); | |
243 } | |
244 | |
245 if (mh->size_of_parameters() > max_size_of_parameters ) { | |
246 _fingerprint = UCONST64(-1); | |
247 mh->constMethod()->set_fingerprint(_fingerprint); | |
248 return _fingerprint; | |
249 } | |
250 | |
251 assert( (int)mh->result_type() <= (int)result_feature_mask, "bad result type"); | |
252 _fingerprint = mh->result_type(); | |
253 _fingerprint <<= static_feature_size; | |
254 if (mh->is_static()) _fingerprint |= 1; | |
255 _shift_count = result_feature_size + static_feature_size; | |
256 iterate_parameters(); | |
257 _fingerprint |= ((uint64_t)done_parm) << _shift_count;// mark end of sig | |
258 mh->constMethod()->set_fingerprint(_fingerprint); | |
259 return _fingerprint; | |
260 } | |
261 }; | |
262 | |
263 | |
264 // Specialized SignatureIterator: Used for native call purposes | |
265 | |
266 class NativeSignatureIterator: public SignatureIterator { | |
267 private: | |
268 methodHandle _method; | |
605 | 269 // We need separate JNI and Java offset values because in 64 bit mode, |
0 | 270 // the argument offsets are not in sync with the Java stack. |
271 // For example a long takes up 1 "C" stack entry but 2 Java stack entries. | |
272 int _offset; // The java stack offset | |
273 int _prepended; // number of prepended JNI parameters (1 JNIEnv, plus 1 mirror if static) | |
274 int _jni_offset; // the current parameter offset, starting with 0 | |
275 | |
276 void do_bool () { pass_int(); _jni_offset++; _offset++; } | |
277 void do_char () { pass_int(); _jni_offset++; _offset++; } | |
1010 | 278 void do_float () { pass_float(); _jni_offset++; _offset++; } |
0 | 279 #ifdef _LP64 |
280 void do_double() { pass_double(); _jni_offset++; _offset += 2; } | |
281 #else | |
282 void do_double() { pass_double(); _jni_offset += 2; _offset += 2; } | |
283 #endif | |
284 void do_byte () { pass_int(); _jni_offset++; _offset++; } | |
285 void do_short () { pass_int(); _jni_offset++; _offset++; } | |
286 void do_int () { pass_int(); _jni_offset++; _offset++; } | |
287 #ifdef _LP64 | |
288 void do_long () { pass_long(); _jni_offset++; _offset += 2; } | |
289 #else | |
290 void do_long () { pass_long(); _jni_offset += 2; _offset += 2; } | |
291 #endif | |
292 void do_void () { ShouldNotReachHere(); } | |
293 void do_object(int begin, int end) { pass_object(); _jni_offset++; _offset++; } | |
294 void do_array (int begin, int end) { pass_object(); _jni_offset++; _offset++; } | |
295 | |
296 public: | |
297 methodHandle method() const { return _method; } | |
298 int offset() const { return _offset; } | |
299 int jni_offset() const { return _jni_offset + _prepended; } | |
300 // int java_offset() const { return method()->size_of_parameters() - _offset - 1; } | |
301 bool is_static() const { return method()->is_static(); } | |
302 virtual void pass_int() = 0; | |
303 virtual void pass_long() = 0; | |
304 virtual void pass_object() = 0; | |
1010 | 305 virtual void pass_float() = 0; |
0 | 306 #ifdef _LP64 |
307 virtual void pass_double() = 0; | |
308 #else | |
309 virtual void pass_double() { pass_long(); } // may be same as long | |
310 #endif | |
311 | |
312 NativeSignatureIterator(methodHandle method) : SignatureIterator(method->signature()) { | |
313 _method = method; | |
314 _offset = 0; | |
315 _jni_offset = 0; | |
316 | |
317 const int JNIEnv_words = 1; | |
318 const int mirror_words = 1; | |
319 _prepended = !is_static() ? JNIEnv_words : JNIEnv_words + mirror_words; | |
320 } | |
321 | |
322 // iterate() calles the 2 virtual methods according to the following invocation syntax: | |
323 // | |
324 // {pass_int | pass_long | pass_object} | |
325 // | |
326 // Arguments are handled from left to right (receiver first, if any). | |
327 // The offset() values refer to the Java stack offsets but are 0 based and increasing. | |
328 // The java_offset() values count down to 0, and refer to the Java TOS. | |
329 // The jni_offset() values increase from 1 or 2, and refer to C arguments. | |
330 | |
331 void iterate() { iterate(Fingerprinter(method()).fingerprint()); | |
332 } | |
333 | |
334 | |
335 // Optimized path if we have the bitvector form of signature | |
336 void iterate( uint64_t fingerprint ) { | |
337 | |
338 if (!is_static()) { | |
339 // handle receiver (not handled by iterate because not in signature) | |
340 pass_object(); _jni_offset++; _offset++; | |
341 } | |
342 | |
343 SignatureIterator::iterate_parameters( fingerprint ); | |
344 } | |
345 }; | |
346 | |
347 | |
348 // Handy stream for iterating over signature | |
349 | |
350 class SignatureStream : public StackObj { | |
351 private: | |
352 symbolHandle _signature; | |
353 int _begin; | |
354 int _end; | |
355 BasicType _type; | |
356 bool _at_return_type; | |
357 | |
358 public: | |
359 bool at_return_type() const { return _at_return_type; } | |
360 bool is_done() const; | |
361 void next_non_primitive(int t); | |
362 void next() { | |
363 symbolOop sig = _signature(); | |
364 int len = sig->utf8_length(); | |
365 if (_end >= len) { | |
366 _end = len + 1; | |
367 return; | |
368 } | |
369 | |
370 _begin = _end; | |
371 int t = sig->byte_at(_begin); | |
372 switch (t) { | |
373 case 'B': _type = T_BYTE; break; | |
374 case 'C': _type = T_CHAR; break; | |
375 case 'D': _type = T_DOUBLE; break; | |
376 case 'F': _type = T_FLOAT; break; | |
377 case 'I': _type = T_INT; break; | |
378 case 'J': _type = T_LONG; break; | |
379 case 'S': _type = T_SHORT; break; | |
380 case 'Z': _type = T_BOOLEAN; break; | |
381 case 'V': _type = T_VOID; break; | |
382 default : next_non_primitive(t); | |
383 return; | |
384 } | |
385 _end++; | |
386 } | |
387 | |
388 SignatureStream(symbolHandle signature, | |
389 bool is_method = true) : | |
390 _signature(signature), _at_return_type(false) { | |
391 _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures | |
392 next(); | |
393 } | |
394 | |
395 bool is_object() const; // True if this argument is an object | |
396 bool is_array() const; // True if this argument is an array | |
397 BasicType type() const { return _type; } | |
398 symbolOop as_symbol(TRAPS); | |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1010
diff
changeset
|
399 enum FailureMode { ReturnNull, CNFException, NCDFError }; |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1010
diff
changeset
|
400 klassOop as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1010
diff
changeset
|
401 oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); |
0 | 402 |
403 // return same as_symbol except allocation of new symbols is avoided. | |
404 symbolOop as_symbol_or_null(); | |
405 }; | |
406 | |
407 class SignatureVerifier : public StackObj { | |
408 public: | |
409 // Returns true if the symbol is valid method or type signature | |
410 static bool is_valid_signature(symbolHandle sig); | |
411 | |
412 static bool is_valid_method_signature(symbolHandle sig); | |
413 static bool is_valid_type_signature(symbolHandle sig); | |
414 private: | |
415 | |
416 static ssize_t is_valid_type(const char*, ssize_t); | |
417 static bool invalid_name_char(char); | |
418 }; |