1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.nabla.forward.trimming;
18
19 import org.objectweb.asm.tree.AbstractInsnNode;
20 import org.objectweb.asm.tree.InsnList;
21
22 /** Base class for code trimmers.
23 * @version $Id$
24 */
25 public abstract class BytecodeTrimmer {
26
27 /** Current instructions window. */
28 private AbstractInsnNode[] currentWindow;
29
30 /** Simple constructor.
31 * @param lookahead number of lookahead instructions
32 */
33 protected BytecodeTrimmer(final int lookahead) {
34 currentWindow = new AbstractInsnNode[lookahead];
35 }
36
37 /** Trim a list of instructions.
38 * @param instructions list of instructions to optimize
39 */
40 public void trim(final InsnList instructions) {
41
42 // set up lookahead instructions
43 currentWindow[0] = instructions.get(0);
44 for (int i = 1; (i < currentWindow.length) && (currentWindow[i - 1] != null); ++i) {
45 currentWindow[i] = currentWindow[i - 1].getNext();
46 }
47
48 // trim the whole instructions set using a sliding window
49 while (currentWindow[currentWindow.length - 1] != null) {
50
51 // trim current window
52 final boolean updated = trimWindow(instructions, currentWindow);
53
54 if (!updated) {
55 // slide the window ourselves one instruction forward
56 for (int i = 1; i < currentWindow.length; ++i) {
57 currentWindow[i - 1] = currentWindow[i];
58 }
59 if (currentWindow[currentWindow.length - 1] != null) {
60 currentWindow[currentWindow.length - 1] = currentWindow[currentWindow.length - 1].getNext();
61 }
62 }
63
64 }
65
66 }
67
68 /** Trim the current window of lookahead instructions.
69 * @param instructions complete instructions list of instructions to trim
70 * @param window current instructions window (belongs to the list)
71 * @return true if instructions and window have been updated and are ready
72 * for next iteration
73 */
74 protected abstract boolean trimWindow(InsnList instructions,
75 AbstractInsnNode[] window);
76
77 }