001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.nabla.forward.trimming; 018 019 import org.objectweb.asm.tree.AbstractInsnNode; 020 import org.objectweb.asm.tree.InsnList; 021 022 /** Base class for code trimmers. 023 * @version $Id$ 024 */ 025 public abstract class BytecodeTrimmer { 026 027 /** Current instructions window. */ 028 private AbstractInsnNode[] currentWindow; 029 030 /** Simple constructor. 031 * @param lookahead number of lookahead instructions 032 */ 033 protected BytecodeTrimmer(final int lookahead) { 034 currentWindow = new AbstractInsnNode[lookahead]; 035 } 036 037 /** Trim a list of instructions. 038 * @param instructions list of instructions to optimize 039 */ 040 public void trim(final InsnList instructions) { 041 042 // set up lookahead instructions 043 currentWindow[0] = instructions.get(0); 044 for (int i = 1; (i < currentWindow.length) && (currentWindow[i - 1] != null); ++i) { 045 currentWindow[i] = currentWindow[i - 1].getNext(); 046 } 047 048 // trim the whole instructions set using a sliding window 049 while (currentWindow[currentWindow.length - 1] != null) { 050 051 // trim current window 052 final boolean updated = trimWindow(instructions, currentWindow); 053 054 if (!updated) { 055 // slide the window ourselves one instruction forward 056 for (int i = 1; i < currentWindow.length; ++i) { 057 currentWindow[i - 1] = currentWindow[i]; 058 } 059 if (currentWindow[currentWindow.length - 1] != null) { 060 currentWindow[currentWindow.length - 1] = currentWindow[currentWindow.length - 1].getNext(); 061 } 062 } 063 064 } 065 066 } 067 068 /** Trim the current window of lookahead instructions. 069 * @param instructions complete instructions list of instructions to trim 070 * @param window current instructions window (belongs to the list) 071 * @return true if instructions and window have been updated and are ready 072 * for next iteration 073 */ 074 protected abstract boolean trimWindow(InsnList instructions, 075 AbstractInsnNode[] window); 076 077 }