comparison src/share/vm/classfile/verifier.hpp @ 2177:3582bf76420e

6990754: Use native memory and reference counting to implement SymbolTable Summary: move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
author coleenp
date Thu, 27 Jan 2011 16:11:27 -0800
parents f95d63e2154a
children 1d1603768966
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
57 // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2. 57 // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
58 static bool relax_verify_for(oop class_loader); 58 static bool relax_verify_for(oop class_loader);
59 59
60 private: 60 private:
61 static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class); 61 static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
62 static symbolHandle inference_verify( 62 static Symbol* inference_verify(
63 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS); 63 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
64 }; 64 };
65 65
66 class RawBytecodeStream; 66 class RawBytecodeStream;
67 class StackMapFrame; 67 class StackMapFrame;
68 class StackMapTable; 68 class StackMapTable;
69 69
70 // Summary of verifier's memory usage: 70 // Summary of verifier's memory usage:
71 // StackMapTable is stack allocated. 71 // StackMapTable is stack allocated.
72 // StackMapFrame are resource allocated. There is one ResourceMark 72 // StackMapFrame are resource allocated. There is only one ResourceMark
73 // for each method. 73 // for each class verification, which is created at the top level.
74 // There is one mutable StackMapFrame (current_frame) which is updated 74 // There is one mutable StackMapFrame (current_frame) which is updated
75 // by abstract bytecode interpretation. frame_in_exception_handler() returns 75 // by abstract bytecode interpretation. frame_in_exception_handler() returns
76 // a frame that has a mutable one-item stack (ready for pushing the 76 // a frame that has a mutable one-item stack (ready for pushing the
77 // catch type exception object). All the other StackMapFrame's 77 // catch type exception object). All the other StackMapFrame's
78 // are immutable (including their locals and stack arrays) after 78 // are immutable (including their locals and stack arrays) after
79 // their constructions. 79 // their constructions.
80 // locals/stack arrays in StackMapFrame are resource allocated. 80 // locals/stack arrays in StackMapFrame are resource allocated.
81 // locals/stack arrays can be shared between StackMapFrame's, except 81 // locals/stack arrays can be shared between StackMapFrame's, except
82 // the mutable StackMapFrame (current_frame). 82 // the mutable StackMapFrame (current_frame).
83 // Care needs to be taken to make sure resource objects don't outlive
84 // the lifetime of their ResourceMark.
85 83
86 // These macros are used similarly to CHECK macros but also check 84 // These macros are used similarly to CHECK macros but also check
87 // the status of the verifier and return if that has an error. 85 // the status of the verifier and return if that has an error.
88 #define CHECK_VERIFY(verifier) \ 86 #define CHECK_VERIFY(verifier) \
89 CHECK); if ((verifier)->has_error()) return; (0 87 CHECK); if ((verifier)->has_error()) return; (0
92 90
93 // A new instance of this class is created for each class being verified 91 // A new instance of this class is created for each class being verified
94 class ClassVerifier : public StackObj { 92 class ClassVerifier : public StackObj {
95 private: 93 private:
96 Thread* _thread; 94 Thread* _thread;
97 symbolHandle _exception_type; 95 Symbol* _exception_type;
98 char* _message; 96 char* _message;
99 size_t _message_buffer_len; 97 size_t _message_buffer_len;
98 GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
100 99
101 void verify_method(methodHandle method, TRAPS); 100 void verify_method(methodHandle method, TRAPS);
102 char* generate_code_data(methodHandle m, u4 code_length, TRAPS); 101 char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
103 void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS); 102 void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS);
104 void verify_local_variable_table(u4 code_length, char* code_data, TRAPS); 103 void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
108 return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD); 107 return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD);
109 } 108 }
110 109
111 bool is_protected_access( 110 bool is_protected_access(
112 instanceKlassHandle this_class, klassOop target_class, 111 instanceKlassHandle this_class, klassOop target_class,
113 symbolOop field_name, symbolOop field_sig, bool is_method); 112 Symbol* field_name, Symbol* field_sig, bool is_method);
114 113
115 void verify_cp_index(constantPoolHandle cp, int index, TRAPS); 114 void verify_cp_index(constantPoolHandle cp, int index, TRAPS);
116 void verify_cp_type( 115 void verify_cp_type(
117 int index, constantPoolHandle cp, unsigned int types, TRAPS); 116 int index, constantPoolHandle cp, unsigned int types, TRAPS);
118 void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS); 117 void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS);
163 void verify_fstore(u2 index, StackMapFrame* current_frame, TRAPS); 162 void verify_fstore(u2 index, StackMapFrame* current_frame, TRAPS);
164 void verify_dstore(u2 index, StackMapFrame* current_frame, TRAPS); 163 void verify_dstore(u2 index, StackMapFrame* current_frame, TRAPS);
165 void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS); 164 void verify_astore(u2 index, StackMapFrame* current_frame, TRAPS);
166 void verify_iinc (u2 index, StackMapFrame* current_frame, TRAPS); 165 void verify_iinc (u2 index, StackMapFrame* current_frame, TRAPS);
167 166
168 bool name_in_supers(symbolOop ref_name, instanceKlassHandle current); 167 bool name_in_supers(Symbol* ref_name, instanceKlassHandle current);
169 168
170 VerificationType object_type() const; 169 VerificationType object_type() const;
171 170
172 instanceKlassHandle _klass; // the class being verified 171 instanceKlassHandle _klass; // the class being verified
173 methodHandle _method; // current method being verified 172 methodHandle _method; // current method being verified
204 // the '_exception_name' symbols will set to the exception name and 203 // the '_exception_name' symbols will set to the exception name and
205 // the message_buffer will be filled in with the exception message. 204 // the message_buffer will be filled in with the exception message.
206 void verify_class(TRAPS); 205 void verify_class(TRAPS);
207 206
208 // Return status modes 207 // Return status modes
209 symbolHandle result() const { return _exception_type; } 208 Symbol* result() const { return _exception_type; }
210 bool has_error() const { return !(result().is_null()); } 209 bool has_error() const { return result() != NULL; }
211 210
212 // Called when verify or class format errors are encountered. 211 // Called when verify or class format errors are encountered.
213 // May throw an exception based upon the mode. 212 // May throw an exception based upon the mode.
214 void verify_error(u2 offset, const char* fmt, ...); 213 void verify_error(u2 offset, const char* fmt, ...);
215 void verify_error(const char* fmt, ...); 214 void verify_error(const char* fmt, ...);
216 void class_format_error(const char* fmt, ...); 215 void class_format_error(const char* fmt, ...);
217 void format_error_message(const char* fmt, int offset, va_list args); 216 void format_error_message(const char* fmt, int offset, va_list args);
218 217
219 klassOop load_class(symbolHandle name, TRAPS); 218 klassOop load_class(Symbol* name, TRAPS);
220 219
221 int change_sig_to_verificationType( 220 int change_sig_to_verificationType(
222 SignatureStream* sig_type, VerificationType* inference_type, TRAPS); 221 SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
223 222
224 VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) { 223 VerificationType cp_index_to_type(int index, constantPoolHandle cp, TRAPS) {
225 return VerificationType::reference_type( 224 return VerificationType::reference_type(cp->klass_name_at(index));
226 symbolHandle(THREAD, cp->klass_name_at(index)));
227 } 225 }
226
227 // Keep a list of temporary symbols created during verification because
228 // their reference counts need to be decrememented when the verifier object
229 // goes out of scope. Since these symbols escape the scope in which they're
230 // created, we can't use a TempNewSymbol.
231 Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
232 Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
228 233
229 static bool _verify_verbose; // for debugging 234 static bool _verify_verbose; // for debugging
230 }; 235 };
231 236
232 inline int ClassVerifier::change_sig_to_verificationType( 237 inline int ClassVerifier::change_sig_to_verificationType(
234 BasicType bt = sig_type->type(); 239 BasicType bt = sig_type->type();
235 switch (bt) { 240 switch (bt) {
236 case T_OBJECT: 241 case T_OBJECT:
237 case T_ARRAY: 242 case T_ARRAY:
238 { 243 {
239 symbolOop name = sig_type->as_symbol(CHECK_0); 244 Symbol* name = sig_type->as_symbol(CHECK_0);
245 // Create another symbol to save as signature stream unreferences
246 // this symbol.
247 Symbol* name_copy =
248 create_temporary_symbol(name, 0, name->utf8_length(), CHECK_0);
249 assert(name_copy == name, "symbols don't match");
240 *inference_type = 250 *inference_type =
241 VerificationType::reference_type(symbolHandle(THREAD, name)); 251 VerificationType::reference_type(name_copy);
242 return 1; 252 return 1;
243 } 253 }
244 case T_LONG: 254 case T_LONG:
245 *inference_type = VerificationType::long_type(); 255 *inference_type = VerificationType::long_type();
246 *++inference_type = VerificationType::long2_type(); 256 *++inference_type = VerificationType::long2_type();