Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/com/sun/tools/jdi/MethodImpl.java
38920 views
/*1* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.jdi;2627import com.sun.jdi.*;2829import java.util.List;30import java.util.Iterator;31import java.util.ArrayList;32import java.util.Comparator;3334public abstract class MethodImpl extends TypeComponentImpl35implements Method {36private JNITypeParser signatureParser;37abstract int argSlotCount() throws AbsentInformationException;3839abstract List<Location> allLineLocations(SDE.Stratum stratum,40String sourceName)41throws AbsentInformationException;4243abstract List<Location> locationsOfLine(SDE.Stratum stratum,44String sourceName,45int lineNumber)46throws AbsentInformationException;4748MethodImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,49long ref,50String name, String signature,51String genericSignature, int modifiers) {52super(vm, declaringType, ref, name, signature,53genericSignature, modifiers);54signatureParser = new JNITypeParser(signature);55}5657static MethodImpl createMethodImpl(VirtualMachine vm,58ReferenceTypeImpl declaringType,59long ref,60String name,61String signature,62String genericSignature,63int modifiers) {64if ((modifiers &65(VMModifiers.NATIVE | VMModifiers.ABSTRACT)) != 0) {66return new NonConcreteMethodImpl(vm, declaringType, ref,67name, signature,68genericSignature,69modifiers);70} else {71return new ConcreteMethodImpl(vm, declaringType, ref,72name, signature,73genericSignature,74modifiers);75}76}7778public boolean equals(Object obj) {79if ((obj != null) && (obj instanceof MethodImpl)) {80MethodImpl other = (MethodImpl)obj;81return (declaringType().equals(other.declaringType())) &&82(ref() == other.ref()) &&83super.equals(obj);84} else {85return false;86}87}8889public int hashCode() {90return (int)ref();91}9293public final List<Location> allLineLocations()94throws AbsentInformationException {95return allLineLocations(vm.getDefaultStratum(), null);96}9798public List<Location> allLineLocations(String stratumID,99String sourceName)100throws AbsentInformationException {101return allLineLocations(declaringType.stratum(stratumID),102sourceName);103}104105public final List<Location> locationsOfLine(int lineNumber)106throws AbsentInformationException {107return locationsOfLine(vm.getDefaultStratum(),108null, lineNumber);109}110111public List<Location> locationsOfLine(String stratumID,112String sourceName,113int lineNumber)114throws AbsentInformationException {115return locationsOfLine(declaringType.stratum(stratumID),116sourceName, lineNumber);117}118119LineInfo codeIndexToLineInfo(SDE.Stratum stratum,120long codeIndex) {121if (stratum.isJava()) {122return new BaseLineInfo(-1, declaringType);123} else {124return new StratumLineInfo(stratum.id(), -1,125null, null);126}127}128129/**130* @return a text representation of the declared return type131* of this method.132*/133public String returnTypeName() {134return signatureParser.typeName();135}136137private String returnSignature() {138return signatureParser.signature();139}140141public Type returnType() throws ClassNotLoadedException {142return findType(returnSignature());143}144145public Type findType(String signature) throws ClassNotLoadedException {146ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();147return enclosing.findType(signature);148}149150public List<String> argumentTypeNames() {151return signatureParser.argumentTypeNames();152}153154public List<String> argumentSignatures() {155return signatureParser.argumentSignatures();156}157158Type argumentType(int index) throws ClassNotLoadedException {159ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();160String signature = argumentSignatures().get(index);161return enclosing.findType(signature);162}163164public List<Type> argumentTypes() throws ClassNotLoadedException {165int size = argumentSignatures().size();166ArrayList<Type> types = new ArrayList<Type>(size);167for (int i = 0; i < size; i++) {168Type type = argumentType(i);169types.add(type);170}171172return types;173}174175public int compareTo(Method method) {176ReferenceTypeImpl declaringType = (ReferenceTypeImpl)declaringType();177int rc = declaringType.compareTo(method.declaringType());178if (rc == 0) {179rc = declaringType.indexOf(this) -180declaringType.indexOf(method);181}182return rc;183}184185public boolean isAbstract() {186return isModifierSet(VMModifiers.ABSTRACT);187}188189public boolean isDefault() {190return !isModifierSet(VMModifiers.ABSTRACT) &&191!isModifierSet(VMModifiers.STATIC) &&192!isModifierSet(VMModifiers.PRIVATE) &&193declaringType() instanceof InterfaceType;194}195196public boolean isSynchronized() {197return isModifierSet(VMModifiers.SYNCHRONIZED);198}199200public boolean isNative() {201return isModifierSet(VMModifiers.NATIVE);202}203204public boolean isVarArgs() {205return isModifierSet(VMModifiers.VARARGS);206}207208public boolean isBridge() {209return isModifierSet(VMModifiers.BRIDGE);210}211212public boolean isConstructor() {213return name().equals("<init>");214}215216public boolean isStaticInitializer() {217return name().equals("<clinit>");218}219220public boolean isObsolete() {221try {222return JDWP.Method.IsObsolete.process(vm,223declaringType, ref).isObsolete;224} catch (JDWPException exc) {225throw exc.toJDIException();226}227}228229230/*231* A container class for the return value to allow232* proper type-checking.233*/234class ReturnContainer implements ValueContainer {235ReturnContainer() {236}237public Type type() throws ClassNotLoadedException {238return returnType();239}240public String typeName(){241return returnTypeName();242}243public String signature() {244return returnSignature(); //type().signature();245}246public Type findType(String signature) throws ClassNotLoadedException {247return MethodImpl.this.findType(signature);248}249}250ReturnContainer retValContainer = null;251ReturnContainer getReturnValueContainer() {252if (retValContainer == null) {253retValContainer = new ReturnContainer();254}255return retValContainer;256}257258/*259* A container class for the argument to allow260* proper type-checking.261*/262class ArgumentContainer implements ValueContainer {263int index;264265ArgumentContainer(int index) {266this.index = index;267}268public Type type() throws ClassNotLoadedException {269return argumentType(index);270}271public String typeName(){272return argumentTypeNames().get(index);273}274public String signature() {275return argumentSignatures().get(index);276}277public Type findType(String signature) throws ClassNotLoadedException {278return MethodImpl.this.findType(signature);279}280}281282/*283* This is a var args method. Thus, its last param is an284* array. If the method has n params, then:285* 1. If there are n args and the last is the same type as the type of286* the last param, do nothing. IE, a String[]287* can be passed to a String...288* 2. If there are >= n arguments and for each arg whose number is >= n,289* the arg type is 'compatible' with the component type of290* the last param, then do291* - create an array of the type of the last param292* - put the n, ... args into this array.293* We might have to do conversions here.294* - put this array into arguments(n)295* - delete arguments(n+1), ...296* NOTE that this might modify the input list.297*/298void handleVarArgs(List<Value> arguments)299throws ClassNotLoadedException, InvalidTypeException {300List<Type> paramTypes = this.argumentTypes();301ArrayType lastParamType = (ArrayType)paramTypes.get(paramTypes.size() - 1);302Type componentType = lastParamType.componentType();303int argCount = arguments.size();304int paramCount = paramTypes.size();305if (argCount < paramCount - 1) {306// Error; will be caught later.307return;308}309if (argCount == paramCount - 1) {310// It is ok to pass 0 args to the var arg.311// We have to gen a 0 length array.312ArrayReference argArray = lastParamType.newInstance(0);313arguments.add(argArray);314return;315}316Value nthArgValue = arguments.get(paramCount - 1);317if (nthArgValue == null && argCount == paramCount) {318// We have one varargs parameter and it is null319// so we don't have to do anything.320return;321}322// If the first varargs parameter is null, then don't323// access its type since it can't be an array.324Type nthArgType = (nthArgValue == null) ? null : nthArgValue.type();325if (nthArgType instanceof ArrayTypeImpl) {326if (argCount == paramCount &&327((ArrayTypeImpl)nthArgType).isAssignableTo(lastParamType)) {328/*329* This is case 1. A compatible array is being passed to the330* var args array param. We don't have to do anything.331*/332return;333}334}335336/*337* Case 2. We have to verify that the n, n+1, ... args are compatible338* with componentType, and do conversions if necessary and create339* an array of componentType to hold these possibly converted values.340*/341int count = argCount - paramCount + 1;342ArrayReference argArray = lastParamType.newInstance(count);343344/*345* This will copy arguments(paramCount - 1) ... to argArray(0) ...346* doing whatever conversions are needed! It will throw an347* exception if an incompatible arg is encountered348*/349argArray.setValues(0, arguments, paramCount - 1, count);350arguments.set(paramCount - 1, argArray);351352/*353* Remove the excess args354*/355for (int ii = paramCount; ii < argCount; ii++) {356arguments.remove(paramCount);357}358return;359}360361/*362* The output list will be different than the input list.363*/364List<Value> validateAndPrepareArgumentsForInvoke(List<? extends Value> origArguments)365throws ClassNotLoadedException, InvalidTypeException {366367List<Value> arguments = new ArrayList<Value>(origArguments);368if (isVarArgs()) {369handleVarArgs(arguments);370}371372int argSize = arguments.size();373374JNITypeParser parser = new JNITypeParser(signature());375List<String> signatures = parser.argumentSignatures();376377if (signatures.size() != argSize) {378throw new IllegalArgumentException("Invalid argument count: expected " +379signatures.size() + ", received " +380arguments.size());381}382383for (int i = 0; i < argSize; i++) {384Value value = arguments.get(i);385value = ValueImpl.prepareForAssignment(value,386new ArgumentContainer(i));387arguments.set(i, value);388}389return arguments;390}391392public String toString() {393StringBuffer sb = new StringBuffer();394sb.append(declaringType().name());395sb.append(".");396sb.append(name());397sb.append("(");398boolean first = true;399for (String name : argumentTypeNames()) {400if (!first) {401sb.append(", ");402}403sb.append(name);404first = false;405}406sb.append(")");407return sb.toString();408}409}410411412