/* Sun-$Revision: 23.7 $ */ /* Copyright 1992-9 Sun Microsystems, Inc. and Stanford University. See the LICENSE file for license information. */ # pragma interface // bounded lists: approx. length is know at creation time; allow efficient // access to ith element. Not much more than a glorified growable array. template<class data_type> class BoundedListTemplate : public ResourceObj { protected: int32 len; /* current length */ int32 max; /* maximum length */ data_type* data; /* data array */ bool on_C_heap; /* allocated on C heap? */ void grow(); /* grow data array (double length) */ public: BoundedListTemplate(int32 maxLen); BoundedListTemplate(int32 maxLen, bool on_c_heap); ~BoundedListTemplate() { if (on_C_heap) selfs_free((char*)data); } void clear() { len = 0; } int32 length() { return len; } int32 capacity() { return max; } bool isEmpty() { return len == 0; } bool nonEmpty() { return len != 0; } bool isFull() { return len == max; } void append(data_type elem) { if (len == max) grow(); data[len++] = elem; } void appendList(BoundedListTemplate* l) { for (fint i = 0; i < l->length(); i++) append(l->nth(i)); } void push(data_type elem) { append(elem); } data_type nth(int32 i) { if (i < 0 || i >= len) fatal("accessing nonexisting list element"); return data[i]; } data_type first() { if (!len) fatal("list is empty"); return data[0]; } data_type last() { if (!len) fatal("list is empty"); return data[len-1]; } data_type pop() { if (len <= 0) fatal("popping from empty list"); return data[--len]; } data_type top() { if (len <= 0) fatal("empty list"); return data[len-1]; } void nthPut(int32 i, data_type elem, bool okGrow = true) { if (i < 0 || i > len || !okGrow && i == len) fatal("accessing nonexisting list element"); if (okGrow && i == len) { append(elem); /* data array needs to grow */ } else { data[i] = elem; } } bool contains(data_type elem); fint find(data_type elem); /* returns index or -1 */ fint find(data_type elem, bool (* f)(data_type, data_type)); void remove(data_type elem); /* preserves ordering */ void removeFast(data_type elem); /* doesnt preserve ordering */ void apply(void f(data_type)); data_type* data_addr() { return data; } void print_short() { lprintf("List %#lx", this); } virtual void print(); }; template<class data_type> BoundedListTemplate<data_type>::BoundedListTemplate(int32 maxLen) { len = 0; assert(maxLen >= 0, "awfully short list"); max = maxLen; data = NEW_RESOURCE_ARRAY( data_type, maxLen); on_C_heap = false; } template<class data_type> BoundedListTemplate<data_type>::BoundedListTemplate(int32 maxLen, bool c_heap) { // for static lists len = 0; max = maxLen; on_C_heap = c_heap; if (c_heap) { data = (data_type*)AllocateHeap(maxLen * sizeof(data_type), "bounded list"); } else { data = NEW_RESOURCE_ARRAY( data_type, maxLen); } } template<class data_type> void BoundedListTemplate<data_type>::grow() { data_type* newData; if (on_C_heap) { newData = (data_type*)AllocateHeap(2 * max * sizeof(data_type), "bounded list"); } else { newData = NEW_RESOURCE_ARRAY( data_type, max * 2); } for (fint i = 0; i < length(); i++) newData[i] = data[i]; if (on_C_heap) selfs_free(data); data = newData; max *= 2; } template<class data_type> bool BoundedListTemplate<data_type>::contains(data_type elem) { for (fint i = 0; i < length(); i++) { if (data[i] == elem) return true; } return false; } template<class data_type> fint BoundedListTemplate<data_type>::find(data_type elem) { for (fint i = 0; i < length(); i++) { if (data[i] == elem) return i; } return -1; } template<class data_type> fint BoundedListTemplate<data_type>::find(data_type token, bool (*f)(data_type, data_type)) { for (fint i = 0; i < length(); i++) { if (f(token, data[i])) return i; } return -1; } template<class data_type> void BoundedListTemplate<data_type>::remove(data_type elem) { for (fint i = 0; i < length(); i++) { if (data[i] == elem) { for (fint j = i + 1; j < length(); j++) data[j-1] = data[j]; --len; return; } } ShouldNotReachHere(); } template<class data_type> void BoundedListTemplate<data_type>::removeFast(data_type elem) { for (fint i = 0; i < length(); i++) { if (data[i] == elem) { if (len > 0) // don't need to preserve order- just replace with last elem data[i] = data[--len]; else --len; return; } } ShouldNotReachHere(); } template<class data_type> void BoundedListTemplate<data_type>::apply(void f(data_type)) { for (fint i = 0; i < length(); i++) f(data[i]); } template<class data_type> void BoundedListTemplate<data_type>::print() { print_short(); lprintf(": length %ld (max %ld) { ", (void*)len, (void*)max); for (fint i = 0; i < length(); i++) lprintf("%#lx ", (void*)nth(i)); lprintf("}\n"); } # if defined(FAST_COMPILER) || defined(SIC_COMPILER) typedef BoundedListTemplate<char*> AddressList; typedef BoundedListTemplate<Location> LocationList; typedef BoundedListTemplate<nmethod*> nmethodBList; # endif typedef BoundedListTemplate<bool> BoolBList; typedef BoundedListTemplate<oop> OopBList; typedef BoundedListTemplate<preservedVmObj*> preservedVmObjBList; typedef BoundedListTemplate<Token*> TokenList;