View Javadoc

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  }