src/hotspot/share/runtime/signature.cpp
changeset 54133 829bf950287e
parent 54124 5d48ae032588
child 54786 ebf733a324d4
--- a/src/hotspot/share/runtime/signature.cpp	Wed Mar 13 22:05:09 2019 -0700
+++ b/src/hotspot/share/runtime/signature.cpp	Thu Mar 14 18:56:25 2019 +0100
@@ -123,15 +123,6 @@
 }
 
 
-void SignatureIterator::dispatch_field() {
-  // no '(', just one (field) type
-  _index = 0;
-  _parameter_index = 0;
-  parse_type();
-  check_signature_end();
-}
-
-
 void SignatureIterator::iterate_parameters() {
   // Parse parameters
   _index = 0;
@@ -196,7 +187,6 @@
         break;
       case done_parm:
         return;
-        break;
       default:
         tty->print_cr("*** parameter is " UINT64_FORMAT, fingerprint & parameter_feature_mask);
         tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint);
@@ -205,7 +195,6 @@
     }
     fingerprint >>= parameter_feature_size;
   }
-  _parameter_index = 0;
 }
 
 
@@ -239,10 +228,7 @@
         break;
       case '[':
         {
-          int begin = ++_index;
-          while (sig->char_at(_index) == '[') {
-            _index++;
-          }
+          while (sig->char_at(++_index) == '[') ;
           if (sig->char_at(_index) == 'L') {
             while (sig->char_at(_index++) != ';') ;
           } else {
@@ -281,16 +267,17 @@
 
 // Implementation of SignatureStream
 SignatureStream::SignatureStream(Symbol* signature, bool is_method) :
-                   _signature(signature), _at_return_type(false) {
+                   _signature(signature), _at_return_type(false), _previous_name(NULL), _names(NULL) {
   _begin = _end = (is_method ? 1 : 0);  // skip first '(' in method signatures
-  _names = new GrowableArray<Symbol*>(10);
   next();
 }
 
 SignatureStream::~SignatureStream() {
   // decrement refcount for names created during signature parsing
-  for (int i = 0; i < _names->length(); i++) {
-    _names->at(i)->decrement_refcount();
+  if (_names != NULL) {
+    for (int i = 0; i < _names->length(); i++) {
+      _names->at(i)->decrement_refcount();
+    }
   }
 }
 
@@ -359,10 +346,35 @@
     end--;
   }
 
+  const char* symbol_chars = (const char*)_signature->base() + begin;
+  int len = end - begin;
+
+  // Quick check for common symbols in signatures
+  assert((vmSymbols::java_lang_String()->utf8_length() == 16 && vmSymbols::java_lang_Object()->utf8_length() == 16), "sanity");
+  if (len == 16 &&
+      strncmp(symbol_chars, "java/lang/", 10) == 0) {
+    if (strncmp("String", symbol_chars + 10, 6) == 0) {
+      return vmSymbols::java_lang_String();
+    } else if (strncmp("Object", symbol_chars + 10, 6) == 0) {
+      return vmSymbols::java_lang_Object();
+    }
+  }
+
+  Symbol* name = _previous_name;
+  if (name != NULL && name->equals(symbol_chars, len)) {
+    return name;
+  }
+
   // Save names for cleaning up reference count at the end of
   // SignatureStream scope.
-  Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL);
-  _names->push(name);  // save new symbol for decrementing later
+  name = SymbolTable::new_symbol(symbol_chars, len, CHECK_NULL);
+  if (!name->is_permanent()) {
+    if (_names == NULL) {
+      _names = new GrowableArray<Symbol*>(10);
+    }
+    _names->push(name);  // save new symbol for decrementing later
+  }
+  _previous_name = name;
   return name;
 }
 
@@ -467,11 +479,12 @@
     case 'L':
       for (index = index + 1; index < limit; ++index) {
         char c = type[index];
-        if (c == ';') {
-          return index + 1;
-        }
-        if (invalid_name_char(c)) {
-          return -1;
+        switch (c) {
+          case ';':
+            return index + 1;
+          case '\0': case '.': case '[':
+            return -1;
+          default: ; // fall through
         }
       }
       // fall through
@@ -479,13 +492,4 @@
   }
   return -1;
 }
-
-bool SignatureVerifier::invalid_name_char(char c) {
-  switch (c) {
-    case '\0': case '.': case ';': case '[':
-      return true;
-    default:
-      return false;
-  }
-}
 #endif // ASSERT