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 }