001/* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013package org.jikesrvm.classloader; 014 015import java.util.WeakHashMap; 016 017/** 018 * Lightweight implementation of a vector of Fields. 019 */ 020final class TypeReferenceVector { 021 //-----------// 022 // interface // 023 //-----------// 024 025 TypeReferenceVector() { 026 array = new TypeReference[10]; 027 } 028 029 // Add item. 030 // 031 void addElement(TypeReference item) { 032 if (cnt == array.length) { 033 adjustLength(cnt << 1); // double size of array 034 } 035 array[cnt++] = item; 036 } 037 038 // Add item if it is not already in the Vector. 039 // 040 public void addUniqueElement(TypeReference item) { 041 for (int i = 0; i < cnt; i++) { 042 if (array[i] == item) return; 043 } 044 addElement(item); 045 } 046 047 // Get item. 048 // 049 TypeReference elementAt(int index) { 050 return array[index]; 051 } 052 053 // Set item. 054 // 055 void setElementAt(TypeReference item, int index) { 056 array[index] = item; 057 } 058 059 // Get number of items added so far. 060 // 061 public int size() { 062 return cnt; 063 } 064 065 // Get array, trimmed to size. 066 // 067 public TypeReference[] finish() { 068 TypeReference[] result = popularTRVs.get(this); 069 if (result != null) { 070 array = result; 071 return result; 072 } else { 073 adjustLength(cnt); 074 popularTRVs.put(this, array); 075 return array; 076 } 077 } 078 079 @Override 080 public int hashCode() { 081 int val = 0; 082 for (int i = 0; i < cnt; i++) { 083 val ^= array[i].hashCode(); 084 } 085 return val; 086 } 087 088 @Override 089 public boolean equals(Object obj) { 090 if (obj instanceof TypeReferenceVector) { 091 TypeReferenceVector that = (TypeReferenceVector)obj; 092 if (cnt != that.cnt) return false; 093 for (int i = 0; i < cnt; i++) { 094 if (array[i] != that.array[i]) return false; 095 } 096 return true; 097 } else { 098 return false; 099 } 100 } 101 102 //----------------// 103 // implementation // 104 //----------------// 105 106 private TypeReference[] array; 107 private int cnt; 108 109 private static final TypeReference[] empty = new TypeReference[0]; 110 private static final WeakHashMap<TypeReferenceVector,TypeReference[]> 111 popularTRVs = new WeakHashMap<TypeReferenceVector,TypeReference[]>(); 112 113 private void adjustLength(int newLength) { 114 if (newLength == 0) { 115 array = empty; 116 } else { 117 TypeReference[] newElements = new TypeReference[newLength]; 118 int n = array.length; 119 if (n > newLength) { 120 n = newLength; 121 } 122 123 for (int i = 0; i < n; ++i) { 124 newElements[i] = array[i]; 125 } 126 127 array = newElements; 128 } 129 } 130}