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.algorithmic.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 */ 024 public abstract class BytecodeTrimmer { 025 026 /** Current instructions window. */ 027 private AbstractInsnNode[] currentWindow; 028 029 /** Simple constructor. 030 * @param lookahead number of lookahead instructions 031 */ 032 protected BytecodeTrimmer(final int lookahead) { 033 currentWindow = new AbstractInsnNode[lookahead]; 034 } 035 036 /** Trim a list of instructions. 037 * @param instructions list of instructions to optimize 038 */ 039 public void trim(final InsnList instructions) { 040 041 // set up lookahead instructions 042 currentWindow[0] = instructions.get(0); 043 for (int i = 1; (i < currentWindow.length) && (currentWindow[i - 1] != null); ++i) { 044 currentWindow[i] = currentWindow[i - 1].getNext(); 045 } 046 047 // trim the whole instructions set using a sliding window 048 while (currentWindow[currentWindow.length - 1] != null) { 049 050 // trim current window 051 final boolean updated = trimWindow(instructions, currentWindow); 052 053 if (!updated) { 054 // slide the window ourselves one instruction forward 055 for (int i = 1; i < currentWindow.length; ++i) { 056 currentWindow[i - 1] = currentWindow[i]; 057 } 058 if (currentWindow[currentWindow.length - 1] != null) { 059 currentWindow[currentWindow.length - 1] = currentWindow[currentWindow.length - 1].getNext(); 060 } 061 } 062 063 } 064 065 } 066 067 /** Trim the current window of lookahead instructions. 068 * @param instructions complete instructions list of instructions to trim 069 * @param window current instructions window (belongs to the list) 070 * @return true if instructions and window have been updated and are ready 071 * for next iteration 072 */ 073 protected abstract boolean trimWindow(InsnList instructions, 074 AbstractInsnNode[] window); 075 076 }