Mercurial > hg > truffle
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(); |