Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/signature.cpp @ 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 |
---|---|
26 #include "classfile/symbolTable.hpp" | 26 #include "classfile/symbolTable.hpp" |
27 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
28 #include "memory/oopFactory.hpp" | 28 #include "memory/oopFactory.hpp" |
29 #include "oops/instanceKlass.hpp" | 29 #include "oops/instanceKlass.hpp" |
30 #include "oops/oop.inline.hpp" | 30 #include "oops/oop.inline.hpp" |
31 #include "oops/symbolOop.hpp" | 31 #include "oops/symbol.hpp" |
32 #include "oops/typeArrayKlass.hpp" | 32 #include "oops/typeArrayKlass.hpp" |
33 #include "runtime/signature.hpp" | 33 #include "runtime/signature.hpp" |
34 | 34 |
35 | 35 |
36 // Implementation of SignatureIterator | 36 // Implementation of SignatureIterator |
42 // ReturnType = FieldType | "V". | 42 // ReturnType = FieldType | "V". |
43 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. | 43 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. |
44 // ClassName = string. | 44 // ClassName = string. |
45 | 45 |
46 | 46 |
47 SignatureIterator::SignatureIterator(symbolHandle signature) { | 47 SignatureIterator::SignatureIterator(Symbol* signature) { |
48 assert(signature->is_symbol(), "not a symbol"); | |
49 _signature = signature; | 48 _signature = signature; |
50 _parameter_index = 0; | |
51 } | |
52 | |
53 // Overloaded version called without handle | |
54 SignatureIterator::SignatureIterator(symbolOop signature) { | |
55 symbolHandle sh(Thread::current(), signature); | |
56 _signature = sh; | |
57 _parameter_index = 0; | |
58 } | |
59 | |
60 SignatureIterator::SignatureIterator(Thread *thread, symbolOop signature) { | |
61 symbolHandle sh(thread, signature); | |
62 _signature = sh; | |
63 _parameter_index = 0; | 49 _parameter_index = 0; |
64 } | 50 } |
65 | 51 |
66 void SignatureIterator::expect(char c) { | 52 void SignatureIterator::expect(char c) { |
67 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); | 53 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); |
68 _index++; | 54 _index++; |
69 } | 55 } |
70 | 56 |
71 | 57 |
72 void SignatureIterator::skip_optional_size() { | 58 void SignatureIterator::skip_optional_size() { |
73 symbolOop sig = _signature(); | 59 Symbol* sig = _signature; |
74 char c = sig->byte_at(_index); | 60 char c = sig->byte_at(_index); |
75 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); | 61 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); |
76 } | 62 } |
77 | 63 |
78 | 64 |
102 _index++; size = T_BOOLEAN_size; break; | 88 _index++; size = T_BOOLEAN_size; break; |
103 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; | 89 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; |
104 _index++; size = T_VOID_size; ; break; | 90 _index++; size = T_VOID_size; ; break; |
105 case 'L': | 91 case 'L': |
106 { int begin = ++_index; | 92 { int begin = ++_index; |
107 symbolOop sig = _signature(); | 93 Symbol* sig = _signature; |
108 while (sig->byte_at(_index++) != ';') ; | 94 while (sig->byte_at(_index++) != ';') ; |
109 do_object(begin, _index); | 95 do_object(begin, _index); |
110 } | 96 } |
111 if (_parameter_index < 0 ) _return_type = T_OBJECT; | 97 if (_parameter_index < 0 ) _return_type = T_OBJECT; |
112 size = T_OBJECT_size; | 98 size = T_OBJECT_size; |
113 break; | 99 break; |
114 case '[': | 100 case '[': |
115 { int begin = ++_index; | 101 { int begin = ++_index; |
116 skip_optional_size(); | 102 skip_optional_size(); |
117 symbolOop sig = _signature(); | 103 Symbol* sig = _signature; |
118 while (sig->byte_at(_index) == '[') { | 104 while (sig->byte_at(_index) == '[') { |
119 _index++; | 105 _index++; |
120 skip_optional_size(); | 106 skip_optional_size(); |
121 } | 107 } |
122 if (sig->byte_at(_index) == 'L') { | 108 if (sig->byte_at(_index) == 'L') { |
235 | 221 |
236 void SignatureIterator::iterate_returntype() { | 222 void SignatureIterator::iterate_returntype() { |
237 // Ignore parameters | 223 // Ignore parameters |
238 _index = 0; | 224 _index = 0; |
239 expect('('); | 225 expect('('); |
240 symbolOop sig = _signature(); | 226 Symbol* sig = _signature; |
241 while (sig->byte_at(_index) != ')') _index++; | 227 while (sig->byte_at(_index) != ')') _index++; |
242 expect(')'); | 228 expect(')'); |
243 // Parse return type | 229 // Parse return type |
244 _parameter_index = -1; | 230 _parameter_index = -1; |
245 parse_type(); | 231 parse_type(); |
262 _parameter_index = 0; | 248 _parameter_index = 0; |
263 } | 249 } |
264 | 250 |
265 | 251 |
266 // Implementation of SignatureStream | 252 // Implementation of SignatureStream |
253 SignatureStream::SignatureStream(Symbol* signature, bool is_method) : | |
254 _signature(signature), _at_return_type(false) { | |
255 _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures | |
256 _names = new GrowableArray<Symbol*>(10); | |
257 next(); | |
258 } | |
259 | |
260 SignatureStream::~SignatureStream() { | |
261 // decrement refcount for names created during signature parsing | |
262 for (int i = 0; i < _names->length(); i++) { | |
263 _names->at(i)->decrement_refcount(); | |
264 } | |
265 } | |
267 | 266 |
268 bool SignatureStream::is_done() const { | 267 bool SignatureStream::is_done() const { |
269 return _end > _signature()->utf8_length(); | 268 return _end > _signature->utf8_length(); |
270 } | 269 } |
271 | 270 |
272 | 271 |
273 void SignatureStream::next_non_primitive(int t) { | 272 void SignatureStream::next_non_primitive(int t) { |
274 switch (t) { | 273 switch (t) { |
275 case 'L': { | 274 case 'L': { |
276 _type = T_OBJECT; | 275 _type = T_OBJECT; |
277 symbolOop sig = _signature(); | 276 Symbol* sig = _signature; |
278 while (sig->byte_at(_end++) != ';'); | 277 while (sig->byte_at(_end++) != ';'); |
279 break; | 278 break; |
280 } | 279 } |
281 case '[': { | 280 case '[': { |
282 _type = T_ARRAY; | 281 _type = T_ARRAY; |
283 symbolOop sig = _signature(); | 282 Symbol* sig = _signature; |
284 char c = sig->byte_at(_end); | 283 char c = sig->byte_at(_end); |
285 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); | 284 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); |
286 while (sig->byte_at(_end) == '[') { | 285 while (sig->byte_at(_end) == '[') { |
287 _end++; | 286 _end++; |
288 c = sig->byte_at(_end); | 287 c = sig->byte_at(_end); |
317 | 316 |
318 bool SignatureStream::is_array() const { | 317 bool SignatureStream::is_array() const { |
319 return _type == T_ARRAY; | 318 return _type == T_ARRAY; |
320 } | 319 } |
321 | 320 |
322 symbolOop SignatureStream::as_symbol(TRAPS) { | 321 Symbol* SignatureStream::as_symbol(TRAPS) { |
323 // Create a symbol from for string _begin _end | 322 // Create a symbol from for string _begin _end |
324 int begin = _begin; | 323 int begin = _begin; |
325 int end = _end; | 324 int end = _end; |
326 | 325 |
327 if ( _signature()->byte_at(_begin) == 'L' | 326 if ( _signature->byte_at(_begin) == 'L' |
328 && _signature()->byte_at(_end-1) == ';') { | 327 && _signature->byte_at(_end-1) == ';') { |
329 begin++; | 328 begin++; |
330 end--; | 329 end--; |
331 } | 330 } |
332 | 331 |
333 symbolOop result = oopFactory::new_symbol(_signature, begin, end, CHECK_NULL); | 332 // Save names for cleaning up reference count at the end of |
334 return result; | 333 // SignatureStream scope. |
334 Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); | |
335 _names->push(name); // save new symbol for decrementing later | |
336 return name; | |
335 } | 337 } |
336 | 338 |
337 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, | 339 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, |
338 FailureMode failure_mode, TRAPS) { | 340 FailureMode failure_mode, TRAPS) { |
339 if (!is_object()) return NULL; | 341 if (!is_object()) return NULL; |
340 symbolOop name = as_symbol(CHECK_NULL); | 342 Symbol* name = as_symbol(CHECK_NULL); |
341 if (failure_mode == ReturnNull) { | 343 if (failure_mode == ReturnNull) { |
342 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); | 344 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); |
343 } else { | 345 } else { |
344 bool throw_error = (failure_mode == NCDFError); | 346 bool throw_error = (failure_mode == NCDFError); |
345 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); | 347 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); |
353 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); | 355 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); |
354 if (klass == NULL) return NULL; | 356 if (klass == NULL) return NULL; |
355 return Klass::cast(klass)->java_mirror(); | 357 return Klass::cast(klass)->java_mirror(); |
356 } | 358 } |
357 | 359 |
358 symbolOop SignatureStream::as_symbol_or_null() { | 360 Symbol* SignatureStream::as_symbol_or_null() { |
359 // Create a symbol from for string _begin _end | 361 // Create a symbol from for string _begin _end |
360 ResourceMark rm; | 362 ResourceMark rm; |
361 | 363 |
362 int begin = _begin; | 364 int begin = _begin; |
363 int end = _end; | 365 int end = _end; |
364 | 366 |
365 if ( _signature()->byte_at(_begin) == 'L' | 367 if ( _signature->byte_at(_begin) == 'L' |
366 && _signature()->byte_at(_end-1) == ';') { | 368 && _signature->byte_at(_end-1) == ';') { |
367 begin++; | 369 begin++; |
368 end--; | 370 end--; |
369 } | 371 } |
370 | 372 |
371 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); | 373 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); |
372 for (int index = begin; index < end; index++) { | 374 for (int index = begin; index < end; index++) { |
373 buffer[index - begin] = _signature()->byte_at(index); | 375 buffer[index - begin] = _signature->byte_at(index); |
374 } | 376 } |
375 symbolOop result = SymbolTable::probe(buffer, end - begin); | 377 Symbol* result = SymbolTable::probe(buffer, end - begin); |
376 return result; | 378 return result; |
377 } | 379 } |
378 | 380 |
379 bool SignatureVerifier::is_valid_signature(symbolHandle sig) { | 381 bool SignatureVerifier::is_valid_signature(Symbol* sig) { |
380 const char* signature = (const char*)sig->bytes(); | 382 const char* signature = (const char*)sig->bytes(); |
381 ssize_t len = sig->utf8_length(); | 383 ssize_t len = sig->utf8_length(); |
382 if (signature == NULL || signature[0] == '\0' || len < 1) { | 384 if (signature == NULL || signature[0] == '\0' || len < 1) { |
383 return false; | 385 return false; |
384 } else if (signature[0] == '(') { | 386 } else if (signature[0] == '(') { |
386 } else { | 388 } else { |
387 return is_valid_type_signature(sig); | 389 return is_valid_type_signature(sig); |
388 } | 390 } |
389 } | 391 } |
390 | 392 |
391 bool SignatureVerifier::is_valid_method_signature(symbolHandle sig) { | 393 bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { |
392 const char* method_sig = (const char*)sig->bytes(); | 394 const char* method_sig = (const char*)sig->bytes(); |
393 ssize_t len = sig->utf8_length(); | 395 ssize_t len = sig->utf8_length(); |
394 ssize_t index = 0; | 396 ssize_t index = 0; |
395 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { | 397 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { |
396 ++index; | 398 ++index; |
409 } | 411 } |
410 } | 412 } |
411 return false; | 413 return false; |
412 } | 414 } |
413 | 415 |
414 bool SignatureVerifier::is_valid_type_signature(symbolHandle sig) { | 416 bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { |
415 const char* type_sig = (const char*)sig->bytes(); | 417 const char* type_sig = (const char*)sig->bytes(); |
416 ssize_t len = sig->utf8_length(); | 418 ssize_t len = sig->utf8_length(); |
417 return (type_sig != NULL && len >= 1 && | 419 return (type_sig != NULL && len >= 1 && |
418 (is_valid_type(type_sig, len) == len)); | 420 (is_valid_type(type_sig, len) == len)); |
419 } | 421 } |