1 /*
  2  * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
  3  * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
  4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  5  *
  6  * This code is free software; you can redistribute it and/or modify it
  7  * under the terms of the GNU General Public License version 2 only, as
  8  * published by the Free Software Foundation.
  9  *
 10  * This code is distributed in the hope that it will be useful, but WITHOUT
 11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 13  * version 2 for more details (a copy is included in the LICENSE file that
 14  * accompanied this code).
 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef SHARE_RUNTIME_SIGNATURE_HPP
 27 #define SHARE_RUNTIME_SIGNATURE_HPP
 28 
 29 #include "memory/allocation.hpp"
 30 #include "oops/method.hpp"
 31 
 32 
 33 // Static routines and parsing loops for processing field and method
 34 // descriptors.  In the HotSpot sources we call them "signatures".
 35 //
 36 // A SignatureStream iterates over a Java descriptor (or parts of it).
 37 // The syntax is documented in the Java Virtual Machine Specification,
 38 // section 4.3.
 39 //
 40 // The syntax may be summarized as follows:
 41 //
 42 //     MethodType: '(' {FieldType}* ')' (FieldType | 'V')
 43 //     FieldType: PrimitiveType | ObjectType | ArrayType
 44 //     PrimitiveType: 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z'
 45 //     ObjectType: 'L' ClassName ';' | ArrayType
 46 //     ArrayType: '[' FieldType
 47 //     ClassName: {UnqualifiedName '/'}* UnqualifiedName
 48 //     UnqualifiedName: NameChar {NameChar}*
 49 //     NameChar: ANY_CHAR_EXCEPT('/' | '.' | ';' | '[')
 50 //
 51 // All of the concrete characters in the above grammar are given
 52 // standard manifest constant names of the form JVM_SIGNATURE_x.
 53 // Executable code uses these constant names in preference to raw
 54 // character constants.  Comments and assertion code sometimes use
 55 // the raw character constants for brevity.
 56 //
 57 // The primitive field types (like 'I') correspond 1-1 with type codes
 58 // (like T_INT) which form part of the specification of the 'newarray'
 59 // instruction (JVMS 6.5, section on newarray).  These type codes are
 60 // widely used in the HotSpot code.  They are joined by ad hoc codes
 61 // like T_OBJECT and T_ARRAY (defined in HotSpot but not in the JVMS)
 62 // so that each "basic type" of field descriptor (or void return type)
 63 // has a corresponding T_x code.  Thus, while T_x codes play a very
 64 // minor role in the JVMS, they play a major role in the HotSpot
 65 // sources.  There are fewer than 16 such "basic types", so they fit
 66 // nicely into bitfields.
 67 //
 68 // The syntax of ClassName overlaps slightly with the descriptor
 69 // syntaxes.  The strings "I" and "(I)V" are both class names
 70 // *and* descriptors.  If a class name contains any character other
 71 // than "BCDFIJSZ()V" it cannot be confused with a descriptor.
 72 // Class names inside of descriptors are always contained in an
 73 // "envelope" syntax which starts with 'L' and ends with ';'.
 74 //
 75 // As a confounding factor, array types report their type name strings
 76 // in descriptor format.  These name strings are easy to recognize,
 77 // since they begin with '['.  For this reason some API points on
 78 // HotSpot look for array descriptors as well as proper class names.
 79 //
 80 // For historical reasons some API points that accept class names and
 81 // array names also look for class names wrapped inside an envelope
 82 // (like "LFoo;") and unwrap them on the fly (to a name like "Foo").
 83 
 84 class Signature : AllStatic {
 85  private:
 86   static bool is_valid_array_signature(const Symbol* sig);
 87 
 88  public:
 89 
 90   // Returns the basic type of a field signature (or T_VOID for "V").
 91   // Assumes the signature is a valid field descriptor.
 92   // Do not apply this function to class names or method signatures.
 93   static BasicType basic_type(const Symbol* signature) {
 94     return basic_type(signature->char_at(0));
 95   }
 96 
 97   // Returns T_ILLEGAL for an illegal signature char.
 98   static BasicType basic_type(int ch);
 99 
100   // Assuming it is either a class name or signature,
101   // determine if it in fact cannot be a class name.
102   // This means it either starts with '[' or ends with ';'
103   static bool not_class_name(const Symbol* signature) {
104     return (signature->starts_with(JVM_SIGNATURE_ARRAY) ||
105             signature->ends_with(JVM_SIGNATURE_ENDCLASS));
106   }
107 
108   // Assuming it is either a class name or signature,
109   // determine if it in fact is an array descriptor.
110   static bool is_array(const Symbol* signature) {
111     return (signature->utf8_length() > 1 &&
112             signature->char_at(0) == JVM_SIGNATURE_ARRAY &&
113             is_valid_array_signature(signature));
114   }
115 
116   // Assuming it is either a class name or signature,
117   // determine if it contains a class name plus ';'.
118   static bool has_envelope(const Symbol* signature) {
119     return ((signature->utf8_length() > 0) &&
120             signature->ends_with(JVM_SIGNATURE_ENDCLASS) &&
121             has_envelope(signature->char_at(0)));
122   }
123 
124   // Determine if this signature char introduces an
125   // envelope, which is a class name plus ';'.
126   static bool has_envelope(char signature_char) {
127     return (signature_char == JVM_SIGNATURE_CLASS);
128   }
129 
130   // Assuming has_envelope is true, return the symbol
131   // inside the envelope, by stripping 'L' and ';'.
132   // Caller is responsible for decrementing the newly created
133   // Symbol's refcount, use TempNewSymbol.
134   static Symbol* strip_envelope(const Symbol* signature);
135 
136   // Assuming it's either a field or method descriptor, determine
137   // whether it is in fact a method descriptor:
138   static bool is_method(const Symbol* signature) {
139     return signature->starts_with(JVM_SIGNATURE_FUNC);
140   }
141 
142   // Assuming it's a method signature, determine if it must
143   // return void.
144   static bool is_void_method(const Symbol* signature) {
145     assert(is_method(signature), "signature is not for a method");
146     return signature->ends_with(JVM_SIGNATURE_VOID);
147   }
148 };
149 
150 // A SignatureIterator uses a SignatureStream to produce BasicType
151 // results, discarding class names.  This means it can be accelerated
152 // using a fingerprint mechanism, in many cases, without loss of type
153 // information.  The FingerPrinter class computes and caches this
154 // reduced information for faster iteration.
155 
156 class SignatureIterator: public ResourceObj {
157  public:
158   typedef uint64_t fingerprint_t;
159 
160  protected:
161   Symbol*      _signature;             // the signature to iterate over
162   BasicType    _return_type;
163   fingerprint_t _fingerprint;
164 
165  public:
166   // Definitions used in generating and iterating the
167   // bit field form of the signature generated by the
168   // Fingerprinter.
169   enum {
170     fp_static_feature_size    = 1,
171     fp_is_static_bit          = 1,
172 
173     fp_result_feature_size    = 4,
174     fp_result_feature_mask    = right_n_bits(fp_result_feature_size),
175     fp_parameter_feature_size = 4,
176     fp_parameter_feature_mask = right_n_bits(fp_parameter_feature_size),
177 
178     fp_parameters_done        = 0,  // marker for end of parameters (must be zero)
179 
180     // Parameters take up full wordsize, minus the result and static bit fields.
181     // Since fp_parameters_done is zero, termination field arises from shifting
182     // in zero bits, and therefore occupies no extra space.
183     // The sentinel value is all-zero-bits, which is impossible for a true
184     // fingerprint, since at least the result field will be non-zero.
185     fp_max_size_of_parameters = ((BitsPerLong
186                                   - (fp_result_feature_size + fp_static_feature_size))
187                                  / fp_parameter_feature_size)
188   };
189 
190   static bool fp_is_valid_type(BasicType type, bool for_return_type = false);
191 
192   // Sentinel values are zero and not-zero (-1).
193   // No need to protect the sign bit, since every valid return type is non-zero
194   // (even T_VOID), and there are no valid parameter fields which are 0xF (T_VOID).
195   static fingerprint_t zero_fingerprint() { return (fingerprint_t)0; }
196   static fingerprint_t overflow_fingerprint() { return ~(fingerprint_t)0; }
197   static bool fp_is_valid(fingerprint_t fingerprint) {
198     return (fingerprint != zero_fingerprint()) && (fingerprint != overflow_fingerprint());
199   }
200 
201   // Constructors
202   SignatureIterator(Symbol* signature, fingerprint_t fingerprint = zero_fingerprint()) {
203     _signature   = signature;
204     _return_type = T_ILLEGAL;  // sentinel value for uninitialized
205     _fingerprint = zero_fingerprint();
206     if (fingerprint != _fingerprint) {
207       set_fingerprint(fingerprint);
208     }
209   }
210 
211   // If the fingerprint is present, we can use an accelerated loop.
212   void set_fingerprint(fingerprint_t fingerprint);
213 
214   // Returns the set fingerprint, or zero_fingerprint()
215   // if none has been set already.
216   fingerprint_t fingerprint() const { return _fingerprint; }
217 
218   // Iteration
219   // Hey look:  There are no virtual methods in this class.
220   // So how is it customized?  By calling do_parameters_on
221   // an object which answers to "do_type(BasicType)".
222   // By convention, this object is in the subclass
223   // itself, so the call is "do_parameters_on(this)".
224   // The effect of this is to inline the parsing loop
225   // everywhere "do_parameters_on" is called.
226   // If there is a valid fingerprint in the object,
227   // an improved loop is called which just unpacks the
228   // bitfields from the fingerprint.  Otherwise, the
229   // symbol is parsed.
230   template<typename T> inline void do_parameters_on(T* callback); // iterates over parameters only
231   BasicType return_type();  // computes the value on the fly if necessary
232 
233   static bool fp_is_static(fingerprint_t fingerprint) {
234     assert(fp_is_valid(fingerprint), "invalid fingerprint");
235     return fingerprint & fp_is_static_bit;
236   }
237   static BasicType fp_return_type(fingerprint_t fingerprint) {
238     assert(fp_is_valid(fingerprint), "invalid fingerprint");
239     return (BasicType) ((fingerprint >> fp_static_feature_size) & fp_result_feature_mask);
240   }
241   static fingerprint_t fp_start_parameters(fingerprint_t fingerprint) {
242     assert(fp_is_valid(fingerprint), "invalid fingerprint");
243     return fingerprint >> (fp_static_feature_size + fp_result_feature_size);
244   }
245   static BasicType fp_next_parameter(fingerprint_t& mask) {
246     int result = (mask & fp_parameter_feature_mask);
247     mask >>= fp_parameter_feature_size;
248     return (BasicType) result;
249   }
250 };
251 
252 
253 // Specialized SignatureIterators: Used to compute signature specific values.
254 
255 class SignatureTypeNames : public SignatureIterator {
256  protected:
257   virtual void type_name(const char* name)   = 0;
258 
259   friend class SignatureIterator;  // so do_parameters_on can call do_type
260   void do_type(BasicType type) {
261     switch (type) {
262     case T_BOOLEAN: type_name("jboolean"); break;
263     case T_CHAR:    type_name("jchar"   ); break;
264     case T_FLOAT:   type_name("jfloat"  ); break;
265     case T_DOUBLE:  type_name("jdouble" ); break;
266     case T_BYTE:    type_name("jbyte"   ); break;
267     case T_SHORT:   type_name("jshort"  ); break;
268     case T_INT:     type_name("jint"    ); break;
269     case T_LONG:    type_name("jlong"   ); break;
270     case T_VOID:    type_name("void"    ); break;
271     case T_ARRAY:
272     case T_OBJECT:  type_name("jobject" ); break;
273     default: ShouldNotReachHere();
274     }
275   }
276 
277  public:
278   SignatureTypeNames(Symbol* signature) : SignatureIterator(signature) {}
279 };
280 
281 
282 // Specialized SignatureIterator: Used to compute the argument size.
283 
284 class ArgumentSizeComputer: public SignatureIterator {
285  private:
286   int _size;
287   friend class SignatureIterator;  // so do_parameters_on can call do_type
288   void do_type(BasicType type) { _size += parameter_type_word_count(type); }
289  public:
290   ArgumentSizeComputer(Symbol* signature);
291   int size() { return _size; }
292 };
293 
294 
295 class ArgumentCount: public SignatureIterator {
296  private:
297   int _size;
298   friend class SignatureIterator;  // so do_parameters_on can call do_type
299   void do_type(BasicType type) { _size++; }
300  public:
301   ArgumentCount(Symbol* signature);
302   int size() { return _size; }
303 };
304 
305 
306 class ReferenceArgumentCount: public SignatureIterator {
307  private:
308   int _refs;
309   friend class SignatureIterator;  // so do_parameters_on can call do_type
310   void do_type(BasicType type) { if (is_reference_type(type)) _refs++; }
311  public:
312   ReferenceArgumentCount(Symbol* signature);
313   int count() { return _refs; }
314 };
315 
316 
317 // Specialized SignatureIterator: Used to compute the result type.
318 
319 class ResultTypeFinder: public SignatureIterator {
320  public:
321   BasicType type() { return return_type(); }
322   ResultTypeFinder(Symbol* signature) : SignatureIterator(signature) { }
323 };
324 
325 
326 // Fingerprinter computes a unique ID for a given method. The ID
327 // is a bitvector characterizing the methods signature (incl. the receiver).
328 class Fingerprinter: public SignatureIterator {
329  private:
330   fingerprint_t _accumulator;
331   int _param_size;
332   int _shift_count;
333   const Method* _method;
334 
335   void initialize_accumulator() {
336     _accumulator = 0;
337     _shift_count = fp_result_feature_size + fp_static_feature_size;
338     _param_size = 0;
339   }
340 
341   // Out-of-line method does it all in constructor:
342   void compute_fingerprint_and_return_type(bool static_flag = false);
343 
344   friend class SignatureIterator;  // so do_parameters_on can call do_type
345   void do_type(BasicType type) {
346     assert(fp_is_valid_type(type), "bad parameter type");
347     _accumulator |= ((fingerprint_t)type << _shift_count);
348     _shift_count += fp_parameter_feature_size;
349     _param_size += (is_double_word_type(type) ? 2 : 1);
350   }
351 
352  public:
353   int size_of_parameters() const { return _param_size; }
354   // fingerprint() and return_type() are in super class
355 
356   Fingerprinter(const methodHandle& method)
357     : SignatureIterator(method->signature()),
358       _method(method()) {
359     compute_fingerprint_and_return_type();
360   }
361   Fingerprinter(Symbol* signature, bool is_static)
362     : SignatureIterator(signature),
363       _method(NULL) {
364     compute_fingerprint_and_return_type(is_static);
365   }
366 };
367 
368 
369 // Specialized SignatureIterator: Used for native call purposes
370 
371 class NativeSignatureIterator: public SignatureIterator {
372  private:
373   methodHandle _method;
374 // We need separate JNI and Java offset values because in 64 bit mode,
375 // the argument offsets are not in sync with the Java stack.
376 // For example a long takes up 1 "C" stack entry but 2 Java stack entries.
377   int          _offset;                // The java stack offset
378   int          _prepended;             // number of prepended JNI parameters (1 JNIEnv, plus 1 mirror if static)
379   int          _jni_offset;            // the current parameter offset, starting with 0
380 
381   friend class SignatureIterator;  // so do_parameters_on can call do_type
382   void do_type(BasicType type) {
383     switch (type) {
384     case T_BYTE:
385     case T_BOOLEAN:
386       pass_byte();  _jni_offset++; _offset++;
387       break;
388     case T_CHAR:
389     case T_SHORT:
390       pass_short();  _jni_offset++; _offset++;
391       break;
392     case T_INT:
393       pass_int();    _jni_offset++; _offset++;
394       break;
395     case T_FLOAT:
396       pass_float();  _jni_offset++; _offset++;
397       break;
398     case T_DOUBLE: {
399       int jni_offset = LP64_ONLY(1) NOT_LP64(2);
400       pass_double(); _jni_offset += jni_offset; _offset += 2;
401       break;
402     }
403     case T_LONG: {
404       int jni_offset = LP64_ONLY(1) NOT_LP64(2);
405       pass_long();   _jni_offset += jni_offset; _offset += 2;
406       break;
407     }
408     case T_ARRAY:
409     case T_OBJECT:
410       pass_object(); _jni_offset++; _offset++;
411       break;
412     default:
413       ShouldNotReachHere();
414     }
415   }
416 
417  public:
418   methodHandle method() const          { return _method; }
419   int          offset() const          { return _offset; }
420   int      jni_offset() const          { return _jni_offset + _prepended; }
421   bool      is_static() const          { return method()->is_static(); }
422   virtual void pass_int()              = 0;
423   virtual void pass_long()             = 0;
424   virtual void pass_object()           = 0;  // objects, arrays, inlines
425   virtual void pass_float()            = 0;
426   virtual void pass_byte()             { pass_int(); };
427   virtual void pass_short()            { pass_int(); };
428 #ifdef _LP64
429   virtual void pass_double()           = 0;
430 #else
431   virtual void pass_double()           { pass_long(); }  // may be same as long
432 #endif
433 
434   NativeSignatureIterator(const methodHandle& method) : SignatureIterator(method->signature()) {
435     _method = method;
436     _offset = 0;
437     _jni_offset = 0;
438 
439     const int JNIEnv_words = 1;
440     const int mirror_words = 1;
441     _prepended = !is_static() ? JNIEnv_words : JNIEnv_words + mirror_words;
442   }
443 
444   void iterate() { iterate(Fingerprinter(method()).fingerprint()); }
445 
446   // iterate() calls the 3 virtual methods according to the following invocation syntax:
447   //
448   // {pass_int | pass_long | pass_object}
449   //
450   // Arguments are handled from left to right (receiver first, if any).
451   // The offset() values refer to the Java stack offsets but are 0 based and increasing.
452   // The java_offset() values count down to 0, and refer to the Java TOS.
453   // The jni_offset() values increase from 1 or 2, and refer to C arguments.
454   // The method's return type is ignored.
455 
456   void iterate(fingerprint_t fingerprint) {
457     set_fingerprint(fingerprint);
458     if (!is_static()) {
459       // handle receiver (not handled by iterate because not in signature)
460       pass_object(); _jni_offset++; _offset++;
461     }
462     do_parameters_on(this);
463   }
464 };
465 
466 
467 // This is the core parsing logic for iterating over signatures.
468 // All of the previous classes use this for doing their work.
469 
470 class SignatureStream : public StackObj {
471  private:
472   const Symbol* _signature;
473   int          _begin;
474   int          _end;
475   int          _limit;
476   int          _array_prefix;  // count of '[' before the array element descr
477   BasicType    _type;
478   int          _state;
479   Symbol*      _previous_name;    // cache the previously looked up symbol to avoid lookups
480   GrowableArray<Symbol*>* _names; // symbols created while parsing that need to be dereferenced
481 
482   Symbol* find_symbol();
483 
484   enum { _s_field = 0, _s_method = 1, _s_method_return = 3 };
485   void set_done() {
486     _state |= -2;   // preserve s_method bit
487     assert(is_done(), "Unable to set state to done");
488   }
489   int scan_type(BasicType bt);
490 
491  public:
492   bool at_return_type() const                    { return _state == (int)_s_method_return; }
493   bool is_done() const                           { return _state < 0; }
494   void next();
495 
496   SignatureStream(const Symbol* signature, bool is_method = true);
497   ~SignatureStream();
498 
499   bool is_reference() const { return is_reference_type(_type); }
500   bool is_array() const     { return _type == T_ARRAY; }
501   bool is_primitive() const { return is_java_primitive(_type); }
502   BasicType type() const    { return _type; }
503 
504   const u1* raw_bytes() const  { return _signature->bytes() + _begin; }
505   int       raw_length() const { return _end - _begin; }
506   int raw_symbol_begin() const { return _begin + (has_envelope() ? 1 : 0); }
507   int raw_symbol_end() const   { return _end  -  (has_envelope() ? 1 : 0); }
508   char raw_char_at(int i) const {
509     assert(i < _limit, "index for raw_char_at is over the limit");
510     return _signature->char_at(i);
511   }
512 
513   // True if there is an embedded class name in this type,
514   // followed by ';'.
515   bool has_envelope() const {
516     if (!Signature::has_envelope(_signature->char_at(_begin)))
517       return false;
518     // this should always be true, but let's test it:
519     assert(_signature->char_at(_end-1) == JVM_SIGNATURE_ENDCLASS, "signature envelope has no semi-colon at end");
520     return true;
521   }
522 
523   // return the symbol for chars in symbol_begin()..symbol_end()
524   Symbol* as_symbol() {
525     return find_symbol();
526   }
527 
528   // in case you want only the return type:
529   void skip_to_return_type();
530 
531   // number of '[' in array prefix
532   int array_prefix_length() {
533     return _type == T_ARRAY ? _array_prefix : 0;
534   }
535 
536   // In case you want only the array base type,
537   // reset the stream after skipping some brackets '['.
538   // (The argument is clipped to array_prefix_length(),
539   // and if it ends up as zero this call is a nop.
540   // The default is value skips all brackets '['.)
541  private:
542   int skip_whole_array_prefix();
543  public:
544   int skip_array_prefix(int max_skip_length) {
545     if (_type != T_ARRAY) {
546       return 0;
547     }
548      if (_array_prefix > max_skip_length) {
549       // strip some but not all levels of T_ARRAY
550       _array_prefix -= max_skip_length;
551       _begin += max_skip_length;
552       return max_skip_length;
553     }
554     return skip_whole_array_prefix();
555   }
556   int skip_array_prefix() {
557     if (_type != T_ARRAY) {
558       return 0;
559     }
560     return skip_whole_array_prefix();
561   }
562 
563   // free-standing lookups (bring your own CL/PD pair)
564   enum FailureMode { ReturnNull, NCDFError, CachedOrNull };
565   Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
566   oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
567 };
568 
569 // Specialized SignatureStream: used for invoking SystemDictionary to either find
570 //                              or resolve the underlying type when iterating over a
571 //                              Java descriptor (or parts of it).
572 class ResolvingSignatureStream : public SignatureStream {
573   Klass*       _load_origin;
574   bool         _handles_cached;
575   Handle       _class_loader;       // cached when needed
576   Handle       _protection_domain;  // cached when needed
577 
578   void initialize_load_origin(Klass* load_origin) {
579     _load_origin = load_origin;
580     _handles_cached = (load_origin == NULL);
581   }
582   void need_handles() {
583     if (!_handles_cached) {
584       cache_handles();
585       _handles_cached = true;
586     }
587   }
588   void cache_handles();
589 
590  public:
591   ResolvingSignatureStream(Symbol* signature, Klass* load_origin, bool is_method = true);
592   ResolvingSignatureStream(Symbol* signature, Handle class_loader, Handle protection_domain, bool is_method = true);
593   ResolvingSignatureStream(const Method* method);
594   ResolvingSignatureStream(fieldDescriptor& field);
595 
596   Klass* load_origin()       { return _load_origin; }
597   Handle class_loader()      { need_handles(); return _class_loader; }
598   Handle protection_domain() { need_handles(); return _protection_domain; }
599 
600   Klass* as_klass_if_loaded(TRAPS);
601   Klass* as_klass(FailureMode failure_mode, TRAPS) {
602     need_handles();
603     return SignatureStream::as_klass(_class_loader, _protection_domain,
604                                      failure_mode, THREAD);
605   }
606   oop as_java_mirror(FailureMode failure_mode, TRAPS) {
607     if (is_reference()) {
608       need_handles();
609     }
610     return SignatureStream::as_java_mirror(_class_loader, _protection_domain,
611                                            failure_mode, THREAD);
612   }
613 };
614 
615 // Here is how all the SignatureIterator classes invoke the
616 // SignatureStream engine to do their parsing.
617 template<typename T> inline
618 void SignatureIterator::do_parameters_on(T* callback) {
619   fingerprint_t unaccumulator = _fingerprint;
620 
621   // Check for too many arguments, or missing fingerprint:
622   if (!fp_is_valid(unaccumulator)) {
623     SignatureStream ss(_signature);
624     for (; !ss.at_return_type(); ss.next()) {
625       callback->do_type(ss.type());
626     }
627     // while we are here, capture the return type
628     _return_type = ss.type();
629   } else {
630     // Optimized version of do_parameters when fingerprint is known
631     assert(_return_type != T_ILLEGAL, "return type already captured from fp");
632     unaccumulator = fp_start_parameters(unaccumulator);
633     for (BasicType type; (type = fp_next_parameter(unaccumulator)) != (BasicType)fp_parameters_done; ) {
634       assert(fp_is_valid_type(type), "garbled fingerprint");
635       callback->do_type(type);
636     }
637   }
638 }
639 
640  #ifdef ASSERT
641  class SignatureVerifier : public StackObj {
642   public:
643     static bool is_valid_method_signature(Symbol* sig);
644     static bool is_valid_type_signature(Symbol* sig);
645   private:
646     static ssize_t is_valid_type(const char*, ssize_t);
647 };
648 #endif
649 #endif // SHARE_RUNTIME_SIGNATURE_HPP