< prev index next >

src/hotspot/share/classfile/verifier.hpp

Print this page

 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  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_CLASSFILE_VERIFIER_HPP
 26 #define SHARE_CLASSFILE_VERIFIER_HPP
 27 
 28 #include "classfile/verificationType.hpp"
 29 #include "oops/klass.hpp"
 30 #include "oops/method.hpp"
 31 #include "runtime/handles.hpp"
 32 #include "utilities/exceptions.hpp"
 33 #include "utilities/growableArray.hpp"
 34 #include "utilities/hashTable.hpp"
 35 







 36 // The verifier class
 37 class Verifier : AllStatic {
 38  public:
 39   enum {
 40     STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
 41     INVOKEDYNAMIC_MAJOR_VERSION         = 51,
 42     NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52,
 43     DYNAMICCONSTANT_MAJOR_VERSION       = 55


 44   };
 45 
 46   // Verify the bytecodes for a class.
 47   static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
 48 
 49   static void log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name,
 50                                     oop pending_exception);
 51 
 52   // Return false if the class is loaded by the bootstrap loader,
 53   // or if defineClass was called requesting skipping verification
 54   // -Xverify:all overrides this value
 55   static bool should_verify_for(oop class_loader);
 56 
 57   // Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
 58   static bool relax_access_for(oop class_loader);
 59 
 60   // Print output for class+resolve
 61   static void trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class);
 62 
 63  private:

131   void reset_frame();
132   void details(outputStream* ss) const;
133   void print_frame(outputStream* ss) const;
134   const StackMapFrame* frame() const { return _frame; }
135   bool is_valid() const { return _origin != NONE; }
136   int index() const { return _index; }
137 
138 #ifdef ASSERT
139   void print_on(outputStream* str) const;
140 #endif
141 };
142 
143 class ErrorContext {
144  private:
145   typedef enum {
146     INVALID_BYTECODE,     // There was a problem with the bytecode
147     WRONG_TYPE,           // Type value was not as expected
148     FLAGS_MISMATCH,       // Frame flags are not assignable
149     BAD_CP_INDEX,         // Invalid constant pool index
150     BAD_LOCAL_INDEX,      // Invalid local index

151     LOCALS_SIZE_MISMATCH, // Frames have differing local counts
152     STACK_SIZE_MISMATCH,  // Frames have different stack sizes

153     STACK_OVERFLOW,       // Attempt to push onto a full expression stack
154     STACK_UNDERFLOW,      // Attempt to pop and empty expression stack
155     MISSING_STACKMAP,     // No stackmap for this location and there should be
156     BAD_STACKMAP,         // Format error in stackmap

157     NO_FAULT,             // No error
158     UNKNOWN
159   } FaultType;
160 
161   int _bci;
162   FaultType _fault;
163   TypeOrigin _type;
164   TypeOrigin _expected;
165 
166   ErrorContext(int bci, FaultType fault) :
167       _bci(bci), _fault(fault)  {}
168   ErrorContext(int bci, FaultType fault, TypeOrigin type) :
169       _bci(bci), _fault(fault), _type(type)  {}
170   ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
171       _bci(bci), _fault(fault), _type(type), _expected(exp)  {}
172 
173  public:
174   ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
175 
176   static ErrorContext bad_code(int bci) {

178   }
179   static ErrorContext bad_type(int bci, TypeOrigin type) {
180     return ErrorContext(bci, WRONG_TYPE, type);
181   }
182   static ErrorContext bad_type(int bci, TypeOrigin type, TypeOrigin exp) {
183     return ErrorContext(bci, WRONG_TYPE, type, exp);
184   }
185   static ErrorContext bad_flags(int bci, StackMapFrame* frame) {
186     return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
187   }
188   static ErrorContext bad_flags(int bci, StackMapFrame* cur, StackMapFrame* sm) {
189     return ErrorContext(bci, FLAGS_MISMATCH,
190                         TypeOrigin::frame(cur), TypeOrigin::frame(sm));
191   }
192   static ErrorContext bad_cp_index(int bci, int index) {
193     return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
194   }
195   static ErrorContext bad_local_index(int bci, int index) {
196     return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
197   }



198   static ErrorContext locals_size_mismatch(
199       int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
200     return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
201         TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
202   }
203   static ErrorContext stack_size_mismatch(
204       int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
205     return ErrorContext(bci, STACK_SIZE_MISMATCH,
206         TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
207   }





208   static ErrorContext stack_overflow(int bci, StackMapFrame* frame) {
209     return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
210   }
211   static ErrorContext stack_underflow(int bci, StackMapFrame* frame) {
212     return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
213   }
214   static ErrorContext missing_stackmap(int bci) {
215     return ErrorContext(bci, MISSING_STACKMAP);
216   }
217   static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
218     return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
219   }



220 
221   bool is_valid() const { return _fault != NO_FAULT; }
222   int bci() const { return _bci; }
223 
224   void reset_frames() {
225     _type.reset_frame();
226     _expected.reset_frame();
227   }
228 
229   void details(outputStream* ss, const Method* method) const;
230 
231 #ifdef ASSERT
232   void print_on(outputStream* str) const {
233     str->print("error_context(%d, %d,", _bci, _fault);
234     _type.print_on(str);
235     str->print(",");
236     _expected.print_on(str);
237     str->print(")");
238   }
239 #endif

319   void verify_ldc(
320     int opcode, u2 index, StackMapFrame *current_frame,
321     const constantPoolHandle& cp, int bci, TRAPS);
322 
323   void verify_switch(
324     RawBytecodeStream* bcs, u4 code_length, char* code_data,
325     StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS);
326 
327   void verify_field_instructions(
328     RawBytecodeStream* bcs, StackMapFrame* current_frame,
329     const constantPoolHandle& cp, bool allow_arrays, TRAPS);
330 
331   void verify_invoke_init(
332     RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
333     StackMapFrame* current_frame, u4 code_length, bool in_try_block,
334     bool* this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table,
335     TRAPS);
336 
337   void verify_invoke_instructions(
338     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
339     bool in_try_block, bool* this_uninit, VerificationType return_type,
340     const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS);
341 
342   VerificationType get_newarray_type(u2 index, int bci, TRAPS);
343   void verify_anewarray(int bci, u2 index, const constantPoolHandle& cp,
344       StackMapFrame* current_frame, TRAPS);
345   void verify_return_value(
346       VerificationType return_type, VerificationType type, int bci,
347       StackMapFrame* current_frame, TRAPS);
348 
349   void verify_iload (int index, StackMapFrame* current_frame, TRAPS);
350   void verify_lload (int index, StackMapFrame* current_frame, TRAPS);
351   void verify_fload (int index, StackMapFrame* current_frame, TRAPS);
352   void verify_dload (int index, StackMapFrame* current_frame, TRAPS);
353   void verify_aload (int index, StackMapFrame* current_frame, TRAPS);
354   void verify_istore(int index, StackMapFrame* current_frame, TRAPS);
355   void verify_lstore(int index, StackMapFrame* current_frame, TRAPS);
356   void verify_fstore(int index, StackMapFrame* current_frame, TRAPS);
357   void verify_dstore(int index, StackMapFrame* current_frame, TRAPS);
358   void verify_astore(int index, StackMapFrame* current_frame, TRAPS);
359   void verify_iinc  (int index, StackMapFrame* current_frame, TRAPS);

416     ss.print("%s", _message);
417     _error_context.details(&ss, _method());
418     return ss.as_string();
419   }
420 
421   // Called when verify or class format errors are encountered.
422   // May throw an exception based upon the mode.
423   void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
424   void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
425 
426   Klass* load_class(Symbol* name, TRAPS);
427 
428   method_signatures_table_type* method_signatures_table() {
429     return &_method_signatures_table;
430   }
431 
432   int change_sig_to_verificationType(
433     SignatureStream* sig_type, VerificationType* inference_type);
434 
435   VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
436     return VerificationType::reference_type(cp->klass_name_at(index));

437   }
438 
439   // Keep a list of temporary symbols created during verification because
440   // their reference counts need to be decremented when the verifier object
441   // goes out of scope.  Since these symbols escape the scope in which they're
442   // created, we can't use a TempNewSymbol.
443   Symbol* create_temporary_symbol(const char *s, int length);
444   Symbol* create_temporary_symbol(Symbol* s) {
445     if (s == _previous_symbol) {
446       return s;
447     }
448     if (!s->is_permanent()) {
449       s->increment_refcount();
450       if (_symbols == nullptr) {
451         _symbols = new GrowableArray<Symbol*>(50, 0, nullptr);
452       }
453       _symbols->push(s);
454     }
455     _previous_symbol = s;
456     return s;
457   }
458 
459   TypeOrigin ref_ctx(const char* str);
460 
461 };
462 
463 inline int ClassVerifier::change_sig_to_verificationType(
464     SignatureStream* sig_type, VerificationType* inference_type) {
465   BasicType bt = sig_type->type();
466   switch (bt) {
467     case T_OBJECT:
468     case T_ARRAY:
469       {
470         Symbol* name = sig_type->as_symbol();
471         // Create another symbol to save as signature stream unreferences this symbol.
472         Symbol* name_copy = create_temporary_symbol(name);
473         assert(name_copy == name, "symbols don't match");
474         *inference_type =
475           VerificationType::reference_type(name_copy);
476         return 1;
477       }
478     case T_LONG:
479       *inference_type = VerificationType::long_type();
480       *++inference_type = VerificationType::long2_type();
481       return 2;
482     case T_DOUBLE:
483       *inference_type = VerificationType::double_type();
484       *++inference_type = VerificationType::double2_type();
485       return 2;
486     case T_INT:
487     case T_BOOLEAN:
488     case T_BYTE:
489     case T_CHAR:
490     case T_SHORT:
491       *inference_type = VerificationType::integer_type();
492       return 1;
493     case T_FLOAT:
494       *inference_type = VerificationType::float_type();
495       return 1;

 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  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_CLASSFILE_VERIFIER_HPP
 26 #define SHARE_CLASSFILE_VERIFIER_HPP
 27 
 28 #include "classfile/verificationType.hpp"
 29 #include "oops/klass.hpp"
 30 #include "oops/method.hpp"
 31 #include "runtime/handles.hpp"
 32 #include "utilities/exceptions.hpp"
 33 #include "utilities/growableArray.hpp"
 34 #include "utilities/hashTable.hpp"
 35 
 36 struct NameAndSig {
 37   Symbol* _name;
 38   Symbol* _signature;
 39 
 40   NameAndSig(Symbol* n, Symbol* s) : _name(n), _signature(s) {}
 41 };
 42 
 43 // The verifier class
 44 class Verifier : AllStatic {
 45  public:
 46   enum {
 47     STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
 48     INVOKEDYNAMIC_MAJOR_VERSION         = 51,
 49     NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52,
 50     DYNAMICCONSTANT_MAJOR_VERSION       = 55,
 51     VALUE_TYPES_MAJOR_VERSION           = 70,
 52     JAVA_PREVIEW_MINOR_VERSION          = 65535,
 53   };
 54 
 55   // Verify the bytecodes for a class.
 56   static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
 57 
 58   static void log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name,
 59                                     oop pending_exception);
 60 
 61   // Return false if the class is loaded by the bootstrap loader,
 62   // or if defineClass was called requesting skipping verification
 63   // -Xverify:all overrides this value
 64   static bool should_verify_for(oop class_loader);
 65 
 66   // Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
 67   static bool relax_access_for(oop class_loader);
 68 
 69   // Print output for class+resolve
 70   static void trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class);
 71 
 72  private:

140   void reset_frame();
141   void details(outputStream* ss) const;
142   void print_frame(outputStream* ss) const;
143   const StackMapFrame* frame() const { return _frame; }
144   bool is_valid() const { return _origin != NONE; }
145   int index() const { return _index; }
146 
147 #ifdef ASSERT
148   void print_on(outputStream* str) const;
149 #endif
150 };
151 
152 class ErrorContext {
153  private:
154   typedef enum {
155     INVALID_BYTECODE,     // There was a problem with the bytecode
156     WRONG_TYPE,           // Type value was not as expected
157     FLAGS_MISMATCH,       // Frame flags are not assignable
158     BAD_CP_INDEX,         // Invalid constant pool index
159     BAD_LOCAL_INDEX,      // Invalid local index
160     BAD_STRICT_FIELDS,    // Strict instance fields must be initialized before super constructor
161     LOCALS_SIZE_MISMATCH, // Frames have differing local counts
162     STACK_SIZE_MISMATCH,  // Frames have different stack sizes
163     STRICT_FIELDS_MISMATCH, // Frames have incompatible uninitialized strict instance fields
164     STACK_OVERFLOW,       // Attempt to push onto a full expression stack
165     STACK_UNDERFLOW,      // Attempt to pop and empty expression stack
166     MISSING_STACKMAP,     // No stackmap for this location and there should be
167     BAD_STACKMAP,         // Format error in stackmap
168     WRONG_INLINE_TYPE,    // Mismatched inline type
169     NO_FAULT,             // No error
170     UNKNOWN
171   } FaultType;
172 
173   int _bci;
174   FaultType _fault;
175   TypeOrigin _type;
176   TypeOrigin _expected;
177 
178   ErrorContext(int bci, FaultType fault) :
179       _bci(bci), _fault(fault)  {}
180   ErrorContext(int bci, FaultType fault, TypeOrigin type) :
181       _bci(bci), _fault(fault), _type(type)  {}
182   ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
183       _bci(bci), _fault(fault), _type(type), _expected(exp)  {}
184 
185  public:
186   ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
187 
188   static ErrorContext bad_code(int bci) {

190   }
191   static ErrorContext bad_type(int bci, TypeOrigin type) {
192     return ErrorContext(bci, WRONG_TYPE, type);
193   }
194   static ErrorContext bad_type(int bci, TypeOrigin type, TypeOrigin exp) {
195     return ErrorContext(bci, WRONG_TYPE, type, exp);
196   }
197   static ErrorContext bad_flags(int bci, StackMapFrame* frame) {
198     return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
199   }
200   static ErrorContext bad_flags(int bci, StackMapFrame* cur, StackMapFrame* sm) {
201     return ErrorContext(bci, FLAGS_MISMATCH,
202                         TypeOrigin::frame(cur), TypeOrigin::frame(sm));
203   }
204   static ErrorContext bad_cp_index(int bci, int index) {
205     return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
206   }
207   static ErrorContext bad_local_index(int bci, int index) {
208     return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
209   }
210   static ErrorContext bad_strict_fields(int bci, StackMapFrame* cur) {
211     return ErrorContext(bci, BAD_STRICT_FIELDS, TypeOrigin::frame(cur));
212   }
213   static ErrorContext locals_size_mismatch(
214       int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
215     return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
216         TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
217   }
218   static ErrorContext stack_size_mismatch(
219       int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
220     return ErrorContext(bci, STACK_SIZE_MISMATCH,
221         TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
222   }
223   static ErrorContext strict_fields_mismatch(
224       int bci, StackMapFrame* frame0, StackMapFrame* frame1) {
225         return ErrorContext(bci, STRICT_FIELDS_MISMATCH,
226           TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
227   }
228   static ErrorContext stack_overflow(int bci, StackMapFrame* frame) {
229     return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
230   }
231   static ErrorContext stack_underflow(int bci, StackMapFrame* frame) {
232     return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
233   }
234   static ErrorContext missing_stackmap(int bci) {
235     return ErrorContext(bci, MISSING_STACKMAP);
236   }
237   static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
238     return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
239   }
240   static ErrorContext bad_inline_type(int bci, TypeOrigin type, TypeOrigin exp) {
241     return ErrorContext(bci, WRONG_INLINE_TYPE, type, exp);
242   }
243 
244   bool is_valid() const { return _fault != NO_FAULT; }
245   int bci() const { return _bci; }
246 
247   void reset_frames() {
248     _type.reset_frame();
249     _expected.reset_frame();
250   }
251 
252   void details(outputStream* ss, const Method* method) const;
253 
254 #ifdef ASSERT
255   void print_on(outputStream* str) const {
256     str->print("error_context(%d, %d,", _bci, _fault);
257     _type.print_on(str);
258     str->print(",");
259     _expected.print_on(str);
260     str->print(")");
261   }
262 #endif

342   void verify_ldc(
343     int opcode, u2 index, StackMapFrame *current_frame,
344     const constantPoolHandle& cp, int bci, TRAPS);
345 
346   void verify_switch(
347     RawBytecodeStream* bcs, u4 code_length, char* code_data,
348     StackMapFrame* current_frame, StackMapTable* stackmap_table, TRAPS);
349 
350   void verify_field_instructions(
351     RawBytecodeStream* bcs, StackMapFrame* current_frame,
352     const constantPoolHandle& cp, bool allow_arrays, TRAPS);
353 
354   void verify_invoke_init(
355     RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
356     StackMapFrame* current_frame, u4 code_length, bool in_try_block,
357     bool* this_uninit, const constantPoolHandle& cp, StackMapTable* stackmap_table,
358     TRAPS);
359 
360   void verify_invoke_instructions(
361     RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
362     bool in_try_block, bool* this_uninit,
363     const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS);
364 
365   VerificationType get_newarray_type(u2 index, int bci, TRAPS);
366   void verify_anewarray(int bci, u2 index, const constantPoolHandle& cp,
367       StackMapFrame* current_frame, TRAPS);
368   void verify_return_value(
369       VerificationType return_type, VerificationType type, int bci,
370       StackMapFrame* current_frame, TRAPS);
371 
372   void verify_iload (int index, StackMapFrame* current_frame, TRAPS);
373   void verify_lload (int index, StackMapFrame* current_frame, TRAPS);
374   void verify_fload (int index, StackMapFrame* current_frame, TRAPS);
375   void verify_dload (int index, StackMapFrame* current_frame, TRAPS);
376   void verify_aload (int index, StackMapFrame* current_frame, TRAPS);
377   void verify_istore(int index, StackMapFrame* current_frame, TRAPS);
378   void verify_lstore(int index, StackMapFrame* current_frame, TRAPS);
379   void verify_fstore(int index, StackMapFrame* current_frame, TRAPS);
380   void verify_dstore(int index, StackMapFrame* current_frame, TRAPS);
381   void verify_astore(int index, StackMapFrame* current_frame, TRAPS);
382   void verify_iinc  (int index, StackMapFrame* current_frame, TRAPS);

439     ss.print("%s", _message);
440     _error_context.details(&ss, _method());
441     return ss.as_string();
442   }
443 
444   // Called when verify or class format errors are encountered.
445   // May throw an exception based upon the mode.
446   void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
447   void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
448 
449   Klass* load_class(Symbol* name, TRAPS);
450 
451   method_signatures_table_type* method_signatures_table() {
452     return &_method_signatures_table;
453   }
454 
455   int change_sig_to_verificationType(
456     SignatureStream* sig_type, VerificationType* inference_type);
457 
458   VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
459     Symbol* name = cp->klass_name_at(index);
460     return VerificationType::reference_type(name);
461   }
462 
463   // Keep a list of temporary symbols created during verification because
464   // their reference counts need to be decremented when the verifier object
465   // goes out of scope.  Since these symbols escape the scope in which they're
466   // created, we can't use a TempNewSymbol.
467   Symbol* create_temporary_symbol(const char *s, int length);
468   Symbol* create_temporary_symbol(Symbol* s) {
469     if (s == _previous_symbol) {
470       return s;
471     }
472     if (!s->is_permanent()) {
473       s->increment_refcount();
474       if (_symbols == nullptr) {
475         _symbols = new GrowableArray<Symbol*>(50, 0, nullptr);
476       }
477       _symbols->push(s);
478     }
479     _previous_symbol = s;
480     return s;
481   }
482 
483   TypeOrigin ref_ctx(const char* str);
484 
485 };
486 
487 inline int ClassVerifier::change_sig_to_verificationType(
488     SignatureStream* sig_type, VerificationType* inference_type) {
489   BasicType bt = sig_type->type();
490   switch (bt) {
491     case T_OBJECT:
492     case T_ARRAY:
493       {
494         Symbol* name = sig_type->as_symbol();
495         // Create another symbol to save as signature stream unreferences this symbol.
496         Symbol* name_copy = create_temporary_symbol(name);
497         assert(name_copy == name, "symbols don't match");
498         *inference_type = VerificationType::reference_type(name_copy);

499         return 1;
500       }
501     case T_LONG:
502       *inference_type = VerificationType::long_type();
503       *++inference_type = VerificationType::long2_type();
504       return 2;
505     case T_DOUBLE:
506       *inference_type = VerificationType::double_type();
507       *++inference_type = VerificationType::double2_type();
508       return 2;
509     case T_INT:
510     case T_BOOLEAN:
511     case T_BYTE:
512     case T_CHAR:
513     case T_SHORT:
514       *inference_type = VerificationType::integer_type();
515       return 1;
516     case T_FLOAT:
517       *inference_type = VerificationType::float_type();
518       return 1;
< prev index next >