diff -r 4ebc2e2fb97c -r 71c04702a3d5 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/SignatureIterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/SignatureIterator.java Tue Sep 12 19:03:39 2017 +0200 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime; + +import sun.jvm.hotspot.oops.*; + +/**

SignatureIterators iterate over a Java signature (or parts of it). + (Syntax according to: "The Java Virtual Machine Specification" by + Tim Lindholm & Frank Yellin; section 4.3 Descriptors; p. 89ff.)

+ +

Example: Iterating over +

+([Lfoo;D)I
+0123456789
+
+ + using

+ +
+iterateParameters() calls: do_array(2, 7); do_double();
+iterateReturntype() calls:                              do_int();
+iterate()           calls: do_array(2, 7); do_double(); do_int();
+
+is_returnType()        is: false         ; false      ; true
+
+*/ + +public abstract class SignatureIterator { + protected Symbol _signature; // the signature to iterate over + protected int _index; // the current character index (only valid during iteration) + protected int _parameter_index; // the current parameter index (0 outside iteration phase) + + protected void expect(char c) { + if (_signature.getByteAt(_index) != (byte) c) { + throw new RuntimeException("expecting '" + c + "'"); + } + _index++; + } + protected void skipOptionalSize() { + byte c = _signature.getByteAt(_index); + while ('0' <= c && c <= '9') { + c = _signature.getByteAt(++_index); + } + } + // returns the parameter size in words (0 for void) + protected int parseType() { + switch(_signature.getByteAt(_index)) { + case 'B': doByte (); _index++; return BasicTypeSize.getTByteSize(); + case 'C': doChar (); _index++; return BasicTypeSize.getTCharSize(); + case 'D': doDouble(); _index++; return BasicTypeSize.getTDoubleSize(); + case 'F': doFloat (); _index++; return BasicTypeSize.getTFloatSize(); + case 'I': doInt (); _index++; return BasicTypeSize.getTIntSize(); + case 'J': doLong (); _index++; return BasicTypeSize.getTLongSize(); + case 'S': doShort (); _index++; return BasicTypeSize.getTShortSize(); + case 'Z': doBool (); _index++; return BasicTypeSize.getTBooleanSize(); + case 'V': + { + if (!isReturnType()) { + throw new RuntimeException("illegal parameter type V (void)"); + } + + doVoid(); _index++; + return BasicTypeSize.getTVoidSize(); + } + case 'L': + { + int begin = ++_index; + while (_signature.getByteAt(_index++) != ';') ; + doObject(begin, _index); + return BasicTypeSize.getTObjectSize(); + } + case '[': + { + int begin = ++_index; + skipOptionalSize(); + while (_signature.getByteAt(_index) == '[') { + _index++; + skipOptionalSize(); + } + if (_signature.getByteAt(_index) == 'L') { + while (_signature.getByteAt(_index++) != ';') ; + } else { + _index++; + } + doArray(begin, _index); + return BasicTypeSize.getTArraySize(); + } + } + throw new RuntimeException("Should not reach here: char " + (char)_signature.getByteAt(_index) + " @ " + _index + " in " + _signature.asString()); + } + protected void checkSignatureEnd() { + if (_index < _signature.getLength()) { + System.err.println("too many chars in signature"); + _signature.printValueOn(System.err); + System.err.println(" @ " + _index); + } + } + + public SignatureIterator(Symbol signature) { + _signature = signature; + _parameter_index = 0; + } + + // + // Iteration + // + + // dispatches once for field signatures + public void dispatchField() { + // no '(', just one (field) type + _index = 0; + _parameter_index = 0; + parseType(); + checkSignatureEnd(); + } + + // iterates over parameters only + public void iterateParameters() { + // Parse parameters + _index = 0; + _parameter_index = 0; + expect('('); + while (_signature.getByteAt(_index) != ')') { + _parameter_index += parseType(); + } + expect(')'); + _parameter_index = 0; // so isReturnType() is false outside iteration + } + + // iterates over returntype only + public void iterateReturntype() { + // Ignore parameters + _index = 0; + expect('('); + while (_signature.getByteAt(_index) != ')') { + _index++; + } + expect(')'); + // Parse return type + _parameter_index = -1; + parseType(); + checkSignatureEnd(); + _parameter_index = 0; // so isReturnType() is false outside iteration + } + + // iterates over whole signature + public void iterate() { + // Parse parameters + _index = 0; + _parameter_index = 0; + expect('('); + while (_signature.getByteAt(_index) != ')') { + _parameter_index += parseType(); + } + expect(')'); + // Parse return type + _parameter_index = -1; + parseType(); + checkSignatureEnd(); + _parameter_index = 0; // so isReturnType() is false outside iteration + } + + // Returns the word index of the current parameter; returns a negative value at the return type + public int parameterIndex() { return _parameter_index; } + public boolean isReturnType() { return (parameterIndex() < 0); } + + // Basic types + public abstract void doBool (); + public abstract void doChar (); + public abstract void doFloat (); + public abstract void doDouble(); + public abstract void doByte (); + public abstract void doShort (); + public abstract void doInt (); + public abstract void doLong (); + public abstract void doVoid (); + + // Object types (begin indexes the first character of the entry, end + // indexes the first character after the entry) + public abstract void doObject(int begin, int end); + public abstract void doArray (int begin, int end); +}