Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/signature.hpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | da91efe96a93 |
children | d13d7aba8c12 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2 * Copyright (c) 1997, 2012, 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 | |
1972 | 25 #ifndef SHARE_VM_RUNTIME_SIGNATURE_HPP |
26 #define SHARE_VM_RUNTIME_SIGNATURE_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
29 #include "oops/method.hpp" |
1972 | 30 #include "utilities/top.hpp" |
31 | |
0 | 32 // SignatureIterators iterate over a Java signature (or parts of it). |
33 // (Syntax according to: "The Java Virtual Machine Specification" by | |
34 // Tim Lindholm & Frank Yellin; section 4.3 Descriptors; p. 89ff.) | |
35 // | |
36 // Example: Iterating over ([Lfoo;D)I using | |
37 // 0123456789 | |
38 // | |
39 // iterate_parameters() calls: do_array(2, 7); do_double(); | |
40 // iterate_returntype() calls: do_int(); | |
41 // iterate() calls: do_array(2, 7); do_double(); do_int(); | |
42 // | |
43 // is_return_type() is: false ; false ; true | |
44 // | |
45 // NOTE: The new optimizer has an alternate, for-loop based signature | |
46 // iterator implemented in opto/type.cpp, TypeTuple::make(). | |
47 | |
48 class SignatureIterator: public ResourceObj { | |
49 protected: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
50 Symbol* _signature; // the signature to iterate over |
0 | 51 int _index; // the current character index (only valid during iteration) |
52 int _parameter_index; // the current parameter index (0 outside iteration phase) | |
53 BasicType _return_type; | |
54 | |
55 void expect(char c); | |
56 void skip_optional_size(); | |
57 int parse_type(); // returns the parameter size in words (0 for void) | |
58 void check_signature_end(); | |
59 | |
60 public: | |
61 // Definitions used in generating and iterating the | |
62 // bit field form of the signature generated by the | |
63 // Fingerprinter. | |
64 enum { | |
65 static_feature_size = 1, | |
66 result_feature_size = 4, | |
67 result_feature_mask = 0xF, | |
68 parameter_feature_size = 4, | |
69 parameter_feature_mask = 0xF, | |
70 | |
71 bool_parm = 1, | |
72 byte_parm = 2, | |
73 char_parm = 3, | |
74 short_parm = 4, | |
75 int_parm = 5, | |
76 long_parm = 6, | |
77 float_parm = 7, | |
78 double_parm = 8, | |
79 obj_parm = 9, | |
80 done_parm = 10, // marker for end of parameters | |
81 | |
82 // max parameters is wordsize minus | |
83 // The sign bit, termination field, the result and static bit fields | |
84 max_size_of_parameters = (BitsPerLong-1 - | |
85 result_feature_size - parameter_feature_size - | |
86 static_feature_size) / parameter_feature_size | |
87 }; | |
88 | |
89 // Constructors | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
90 SignatureIterator(Symbol* signature); |
0 | 91 |
92 // Iteration | |
93 void dispatch_field(); // dispatches once for field signatures | |
94 void iterate_parameters(); // iterates over parameters only | |
95 void iterate_parameters( uint64_t fingerprint ); | |
96 void iterate_returntype(); // iterates over returntype only | |
97 void iterate(); // iterates over whole signature | |
98 // Returns the word index of the current parameter; | |
99 int parameter_index() const { return _parameter_index; } | |
100 bool is_return_type() const { return parameter_index() < 0; } | |
101 BasicType get_ret_type() const { return _return_type; } | |
102 | |
103 // Basic types | |
104 virtual void do_bool () = 0; | |
105 virtual void do_char () = 0; | |
106 virtual void do_float () = 0; | |
107 virtual void do_double() = 0; | |
108 virtual void do_byte () = 0; | |
109 virtual void do_short () = 0; | |
110 virtual void do_int () = 0; | |
111 virtual void do_long () = 0; | |
112 virtual void do_void () = 0; | |
113 | |
114 // Object types (begin indexes the first character of the entry, end indexes the first character after the entry) | |
115 virtual void do_object(int begin, int end) = 0; | |
116 virtual void do_array (int begin, int end) = 0; | |
117 }; | |
118 | |
119 | |
120 // Specialized SignatureIterators: Used to compute signature specific values. | |
121 | |
122 class SignatureTypeNames : public SignatureIterator { | |
123 protected: | |
124 virtual void type_name(const char* name) = 0; | |
125 | |
126 void do_bool() { type_name("jboolean"); } | |
127 void do_char() { type_name("jchar" ); } | |
128 void do_float() { type_name("jfloat" ); } | |
129 void do_double() { type_name("jdouble" ); } | |
130 void do_byte() { type_name("jbyte" ); } | |
131 void do_short() { type_name("jshort" ); } | |
132 void do_int() { type_name("jint" ); } | |
133 void do_long() { type_name("jlong" ); } | |
134 void do_void() { type_name("void" ); } | |
135 void do_object(int begin, int end) { type_name("jobject" ); } | |
136 void do_array (int begin, int end) { type_name("jobject" ); } | |
137 | |
138 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
139 SignatureTypeNames(Symbol* signature) : SignatureIterator(signature) {} |
0 | 140 }; |
141 | |
142 | |
143 class SignatureInfo: public SignatureIterator { | |
144 protected: | |
145 bool _has_iterated; // need this because iterate cannot be called in constructor (set is virtual!) | |
146 bool _has_iterated_return; | |
147 int _size; | |
148 | |
149 void lazy_iterate_parameters() { if (!_has_iterated) { iterate_parameters(); _has_iterated = true; } } | |
150 void lazy_iterate_return() { if (!_has_iterated_return) { iterate_returntype(); _has_iterated_return = true; } } | |
151 | |
152 virtual void set(int size, BasicType type) = 0; | |
153 | |
154 void do_bool () { set(T_BOOLEAN_size, T_BOOLEAN); } | |
155 void do_char () { set(T_CHAR_size , T_CHAR ); } | |
156 void do_float () { set(T_FLOAT_size , T_FLOAT ); } | |
157 void do_double() { set(T_DOUBLE_size , T_DOUBLE ); } | |
158 void do_byte () { set(T_BYTE_size , T_BYTE ); } | |
159 void do_short () { set(T_SHORT_size , T_SHORT ); } | |
160 void do_int () { set(T_INT_size , T_INT ); } | |
161 void do_long () { set(T_LONG_size , T_LONG ); } | |
162 void do_void () { set(T_VOID_size , T_VOID ); } | |
163 void do_object(int begin, int end) { set(T_OBJECT_size , T_OBJECT ); } | |
164 void do_array (int begin, int end) { set(T_ARRAY_size , T_ARRAY ); } | |
165 | |
166 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
167 SignatureInfo(Symbol* signature) : SignatureIterator(signature) { |
0 | 168 _has_iterated = _has_iterated_return = false; |
169 _size = 0; | |
170 _return_type = T_ILLEGAL; | |
171 } | |
172 | |
173 }; | |
174 | |
175 | |
176 // Specialized SignatureIterator: Used to compute the argument size. | |
177 | |
178 class ArgumentSizeComputer: public SignatureInfo { | |
179 private: | |
180 void set(int size, BasicType type) { _size += size; } | |
181 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
182 ArgumentSizeComputer(Symbol* signature) : SignatureInfo(signature) {} |
0 | 183 |
184 int size() { lazy_iterate_parameters(); return _size; } | |
185 }; | |
186 | |
187 | |
188 class ArgumentCount: public SignatureInfo { | |
189 private: | |
190 void set(int size, BasicType type) { _size ++; } | |
191 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
192 ArgumentCount(Symbol* signature) : SignatureInfo(signature) {} |
0 | 193 |
194 int size() { lazy_iterate_parameters(); return _size; } | |
195 }; | |
196 | |
197 | |
198 // Specialized SignatureIterator: Used to compute the result type. | |
199 | |
200 class ResultTypeFinder: public SignatureInfo { | |
201 private: | |
202 void set(int size, BasicType type) { _return_type = type; } | |
203 public: | |
204 BasicType type() { lazy_iterate_return(); return _return_type; } | |
205 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
206 ResultTypeFinder(Symbol* signature) : SignatureInfo(signature) {} |
0 | 207 }; |
208 | |
209 | |
210 // Fingerprinter computes a unique ID for a given method. The ID | |
211 // is a bitvector characterizing the methods signature (incl. the receiver). | |
212 class Fingerprinter: public SignatureIterator { | |
213 private: | |
214 uint64_t _fingerprint; | |
215 int _shift_count; | |
216 methodHandle mh; | |
217 | |
218 public: | |
219 | |
220 void do_bool() { _fingerprint |= (((uint64_t)bool_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
221 void do_char() { _fingerprint |= (((uint64_t)char_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
222 void do_byte() { _fingerprint |= (((uint64_t)byte_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
223 void do_short() { _fingerprint |= (((uint64_t)short_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
224 void do_int() { _fingerprint |= (((uint64_t)int_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
225 void do_long() { _fingerprint |= (((uint64_t)long_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
226 void do_float() { _fingerprint |= (((uint64_t)float_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
227 void do_double() { _fingerprint |= (((uint64_t)double_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
228 | |
229 void do_object(int begin, int end) { _fingerprint |= (((uint64_t)obj_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
230 void do_array (int begin, int end) { _fingerprint |= (((uint64_t)obj_parm) << _shift_count); _shift_count += parameter_feature_size; } | |
231 | |
232 void do_void() { ShouldNotReachHere(); } | |
233 | |
234 Fingerprinter(methodHandle method) : SignatureIterator(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: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
352 Symbol* _signature; |
0 | 353 int _begin; |
354 int _end; | |
355 BasicType _type; | |
356 bool _at_return_type; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
357 GrowableArray<Symbol*>* _names; // symbols created while parsing signature |
0 | 358 |
359 public: | |
360 bool at_return_type() const { return _at_return_type; } | |
361 bool is_done() const; | |
362 void next_non_primitive(int t); | |
363 void next() { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
364 Symbol* sig = _signature; |
0 | 365 int len = sig->utf8_length(); |
366 if (_end >= len) { | |
367 _end = len + 1; | |
368 return; | |
369 } | |
370 | |
371 _begin = _end; | |
372 int t = sig->byte_at(_begin); | |
373 switch (t) { | |
374 case 'B': _type = T_BYTE; break; | |
375 case 'C': _type = T_CHAR; break; | |
376 case 'D': _type = T_DOUBLE; break; | |
377 case 'F': _type = T_FLOAT; break; | |
378 case 'I': _type = T_INT; break; | |
379 case 'J': _type = T_LONG; break; | |
380 case 'S': _type = T_SHORT; break; | |
381 case 'Z': _type = T_BOOLEAN; break; | |
382 case 'V': _type = T_VOID; break; | |
383 default : next_non_primitive(t); | |
384 return; | |
385 } | |
386 _end++; | |
387 } | |
388 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
389 SignatureStream(Symbol* signature, bool is_method = true); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
390 ~SignatureStream(); |
0 | 391 |
392 bool is_object() const; // True if this argument is an object | |
393 bool is_array() const; // True if this argument is an array | |
394 BasicType type() const { return _type; } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
395 Symbol* as_symbol(TRAPS); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1010
diff
changeset
|
396 enum FailureMode { ReturnNull, CNFException, NCDFError }; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
397 Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1010
diff
changeset
|
398 oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
2426
diff
changeset
|
399 const jbyte* raw_bytes() { return _signature->bytes() + _begin; } |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
2426
diff
changeset
|
400 int raw_length() { return _end - _begin; } |
0 | 401 |
402 // return same as_symbol except allocation of new symbols is avoided. | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
403 Symbol* as_symbol_or_null(); |
0 | 404 }; |
405 | |
406 class SignatureVerifier : public StackObj { | |
407 public: | |
408 // Returns true if the symbol is valid method or type signature | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
409 static bool is_valid_signature(Symbol* sig); |
0 | 410 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
411 static bool is_valid_method_signature(Symbol* sig); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
412 static bool is_valid_type_signature(Symbol* sig); |
0 | 413 private: |
414 | |
415 static ssize_t is_valid_type(const char*, ssize_t); | |
416 static bool invalid_name_char(char); | |
417 }; | |
1972 | 418 |
419 #endif // SHARE_VM_RUNTIME_SIGNATURE_HPP |