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 }