1b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/*
2b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *             of Java bytecode.
4b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
7b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is free software; you can redistribute it and/or modify it
8b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * under the terms of the GNU General Public License as published by the Free
9b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Software Foundation; either version 2 of the License, or (at your option)
10b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * any later version.
11b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
12b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This program is distributed in the hope that it will be useful, but WITHOUT
13b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * more details.
16b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
17b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * You should have received a copy of the GNU General Public License along
18b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * with this program; if not, write to the Free Software Foundation, Inc.,
19b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */
21b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpackage proguard.optimize;
22b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
23b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.*;
242270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.attribute.BootstrapMethodInfo;
252270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.attribute.visitor.BootstrapMethodInfoVisitor;
26b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.constant.*;
27b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.constant.visitor.ConstantVisitor;
282270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.util.SimplifiedVisitor;
29b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.classfile.visitor.MemberVisitor;
30b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.optimize.info.*;
31b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimport proguard.optimize.peephole.VariableShrinker;
32b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
33b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang/**
34b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * This BootstrapMethodInfoVisitor removes unused constant arguments from
35b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * bootstrap method entries that it visits.
36b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang *
37b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @see ParameterUsageMarker
38b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @see VariableUsageMarker
39b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @see VariableShrinker
40b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * @author Eric Lafortune
41b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang */
42b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangpublic class BootstrapMethodArgumentShrinker
43b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangextends      SimplifiedVisitor
44b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wangimplements   BootstrapMethodInfoVisitor,
45b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang             ConstantVisitor,
46b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang             MemberVisitor
47b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang{
48b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    private long usedParameters;
49b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
50b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
51b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    // Implementations for BootstrapMethodInfoVisitor.
52b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
53b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
54b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
55b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Check which method parameters are used.
56b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        usedParameters = -1L;
57b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this);
58b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
59b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Remove the unused arguments.
60b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        int   methodArgumentCount = bootstrapMethodInfo.u2methodArgumentCount;
61b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        int[] methodArguments     = bootstrapMethodInfo.u2methodArguments;
62b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
63b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        int newArgumentIndex = 0;
64b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
65b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        for (int argumentIndex = 0; argumentIndex < methodArgumentCount; argumentIndex++)
66b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
67b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            if (argumentIndex >= 64 ||
68b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                (usedParameters & (1L << argumentIndex)) != 0L)
69b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
70b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                methodArguments[newArgumentIndex++] = methodArguments[argumentIndex];
71b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
72b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
73b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
74b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Update the number of arguments.
75b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        bootstrapMethodInfo.u2methodArgumentCount = newArgumentIndex;
76b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
77b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
78b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
79b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    // Implementations for ConstantVisitor.
80b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
81b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
82b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
83b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Check the referenced bootstrap method.
84b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
85b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
86b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
87b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
88b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
89b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
90b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        // Check the referenced class member itself.
91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        refConstant.referencedMemberAccept(this);
92b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
93b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
94b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
95b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    // Implementations for MemberVisitor.
96b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang
972270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod) {}
982270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
992270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
100b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
101b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    {
102b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        usedParameters = ParameterUsageMarker.getUsedParameters(programMethod);
103b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang    }
104b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang}
105