001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: SlotAllocator.java 468649 2006-10-28 07:00:55Z minchau $ 020 */ 021 022 package org.apache.xalan.xsltc.compiler.util; 023 024 import org.apache.bcel.generic.LocalVariableGen; 025 import org.apache.bcel.generic.Type; 026 027 /** 028 * @author Jacek Ambroziak 029 */ 030 final class SlotAllocator { 031 032 private int _firstAvailableSlot; 033 private int _size = 8; 034 private int _free = 0; 035 private int[] _slotsTaken = new int[_size]; 036 037 public void initialize(LocalVariableGen[] vars) { 038 final int length = vars.length; 039 int slot = 0, size, index; 040 041 for (int i = 0; i < length; i++) { 042 size = vars[i].getType().getSize(); 043 index = vars[i].getIndex(); 044 slot = Math.max(slot, index + size); 045 } 046 _firstAvailableSlot = slot; 047 } 048 049 public int allocateSlot(Type type) { 050 final int size = type.getSize(); 051 final int limit = _free; 052 int slot = _firstAvailableSlot, where = 0; 053 054 if (_free + size > _size) { 055 final int[] array = new int[_size *= 2]; 056 for (int j = 0; j < limit; j++) 057 array[j] = _slotsTaken[j]; 058 _slotsTaken = array; 059 } 060 061 while (where < limit) { 062 if (slot + size <= _slotsTaken[where]) { 063 // insert 064 for (int j = limit - 1; j >= where; j--) 065 _slotsTaken[j + size] = _slotsTaken[j]; 066 break; 067 } 068 else { 069 slot = _slotsTaken[where++] + 1; 070 } 071 } 072 073 for (int j = 0; j < size; j++) 074 _slotsTaken[where + j] = slot + j; 075 076 _free += size; 077 return slot; 078 } 079 080 public void releaseSlot(LocalVariableGen lvg) { 081 final int size = lvg.getType().getSize(); 082 final int slot = lvg.getIndex(); 083 final int limit = _free; 084 085 for (int i = 0; i < limit; i++) { 086 if (_slotsTaken[i] == slot) { 087 int j = i + size; 088 while (j < limit) { 089 _slotsTaken[i++] = _slotsTaken[j++]; 090 } 091 _free -= size; 092 return; 093 } 094 } 095 String state = "Variable slot allocation error"+ 096 "(size="+size+", slot="+slot+", limit="+limit+")"; 097 ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, state); 098 throw new Error(err.toString()); 099 } 100 }