8157176: Improved classfile parsing
authorhseigel
Mon, 27 Jun 2016 15:26:08 -0400
changeset 41545 45a3f587a838
parent 41544 d77997d3a28b
child 41546 357406d17607
8157176: Improved classfile parsing Reviewed-by: acorn, mschoene, ctornqvi, bmoloden Contributed-by: harold.seigel@oracle.com
hotspot/src/share/vm/runtime/sharedRuntime.cpp
hotspot/src/share/vm/runtime/signature.cpp
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Fri Jul 01 15:11:38 2016 -0400
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp	Mon Jun 27 15:26:08 2016 -0400
@@ -2881,8 +2881,6 @@
   char *s = sig->as_C_string();
   int len = (int)strlen(s);
   s++; len--;                   // Skip opening paren
-  char *t = s+len;
-  while (*(--t) != ')');      // Find close paren
 
   BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
   VMRegPair *regs = NEW_RESOURCE_ARRAY(VMRegPair, 256);
@@ -2891,7 +2889,7 @@
     sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
   }
 
-  while (s < t) {
+  while (*s != ')') {          // Find closing right paren
     switch (*s++) {            // Switch on signature character
     case 'B': sig_bt[cnt++] = T_BYTE;    break;
     case 'C': sig_bt[cnt++] = T_CHAR;    break;
--- a/hotspot/src/share/vm/runtime/signature.cpp	Fri Jul 01 15:11:38 2016 -0400
+++ b/hotspot/src/share/vm/runtime/signature.cpp	Mon Jun 27 15:26:08 2016 -0400
@@ -224,7 +224,49 @@
   _index = 0;
   expect('(');
   Symbol* sig = _signature;
-  while (sig->byte_at(_index) != ')') _index++;
+  // Need to skip over each type in the signature's argument list until a
+  // closing ')' is found., then get the return type.  We cannot just scan
+  // for the first ')' because ')' is a legal character in a type name.
+  while (sig->byte_at(_index) != ')') {
+    switch(sig->byte_at(_index)) {
+      case 'B':
+      case 'C':
+      case 'D':
+      case 'F':
+      case 'I':
+      case 'J':
+      case 'S':
+      case 'Z':
+      case 'V':
+        {
+          _index++;
+        }
+        break;
+      case 'L':
+        {
+          while (sig->byte_at(_index++) != ';') ;
+        }
+        break;
+      case '[':
+        {
+          int begin = ++_index;
+          skip_optional_size();
+          while (sig->byte_at(_index) == '[') {
+            _index++;
+            skip_optional_size();
+          }
+          if (sig->byte_at(_index) == 'L') {
+            while (sig->byte_at(_index++) != ';') ;
+          } else {
+            _index++;
+          }
+        }
+        break;
+      default:
+        ShouldNotReachHere();
+        break;
+    }
+  }
   expect(')');
   // Parse return type
   _parameter_index = -1;