1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xalan.internal.xsltc.compiler.util; 23 24 import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; 25 import com.sun.org.apache.bcel.internal.generic.Type; 26 27 /** 28 * @author Jacek Ambroziak 29 */ 30 final class SlotAllocator { 31 32 private int _firstAvailableSlot; 33 private int _size = 8; 34 private int _free = 0; 35 private int[] _slotsTaken = new int[_size]; 36 37 public void initialize(LocalVariableGen[] vars) { 38 final int length = vars.length; 39 int slot = 0, size, index; 40 41 for (int i = 0; i < length; i++) { 42 size = vars[i].getType().getSize(); 43 index = vars[i].getIndex(); 44 slot = Math.max(slot, index + size); 45 } 46 _firstAvailableSlot = slot; 47 } 48 49 public int allocateSlot(Type type) { 50 final int size = type.getSize(); 51 final int limit = _free; 52 int slot = _firstAvailableSlot, where = 0; 53 54 if (_free + size > _size) { 55 final int[] array = new int[_size *= 2]; 56 for (int j = 0; j < limit; j++) 57 array[j] = _slotsTaken[j]; 58 _slotsTaken = array; 59 } 60 61 while (where < limit) { 62 if (slot + size <= _slotsTaken[where]) { 63 // insert 64 for (int j = limit - 1; j >= where; j--) 65 _slotsTaken[j + size] = _slotsTaken[j]; 66 break; 67 } 68 else { 69 slot = _slotsTaken[where++] + 1; 70 } 71 } 72 73 for (int j = 0; j < size; j++) 74 _slotsTaken[where + j] = slot + j; 75 76 _free += size; 77 return slot; 78 } 79 80 public void releaseSlot(LocalVariableGen lvg) { 81 final int size = lvg.getType().getSize(); 82 final int slot = lvg.getIndex(); 83 final int limit = _free; 84 85 for (int i = 0; i < limit; i++) { 86 if (_slotsTaken[i] == slot) { 87 int j = i + size; 88 while (j < limit) { 89 _slotsTaken[i++] = _slotsTaken[j++]; 90 } 91 _free -= size; 92 return; 93 } 94 } 95 String state = "Variable slot allocation error"+ 96 "(size="+size+", slot="+slot+", limit="+limit+")"; 97 ErrorMsg err = new ErrorMsg(ErrorMsg.INTERNAL_ERR, state); 98 throw new Error(err.toString()); 99 } 100 }