// $Id: segment.h,v 1.10 2002/12/11 00:55:04 ericb Exp $ -*- c++ -*- // // This software is subject to the terms of the IBM Jikes Compiler // License Agreement available at the following URL: // http://ibm.com/developerworks/opensource/jikes. // Copyright (C) 1996, 1999, 2000, 2001, 2002 International Business // Machines Corporation and others. All Rights Reserved. // You must accept the terms of that agreement to use this software. // #ifndef segment_INCLUDED #define segment_INCLUDED #include "platform.h" #include "tuple.h" #ifdef HAVE_JIKES_NAMESPACE namespace Jikes { // Open namespace Jikes block #endif class SegmentPool; // // A portion of the implementation of Pair. // class PairSegment { public: enum { LIST_LIMIT = 5, LOG_BLKSIZE = 8, BLKSIZE = 1 << LOG_BLKSIZE, MASK = ~ (BLKSIZE - 1) }; private: struct TargetValuePair { int target; u2 value; }; TargetValuePair list[LIST_LIMIT]; unsigned top; u2* array; public: PairSegment() : top(0), array(NULL) {} ~PairSegment() { if (array) { unsigned offset = ((unsigned) list[0].target) & MASK; delete [] (array + offset); } } // // Returns the modifiable value associated with the integer key. // u2& Image(int); }; // // A map of int -> u2 pairs. // class Pair { public: Pair(SegmentPool& segment_pool_, unsigned estimate = 0) : segment_pool(segment_pool_) { // // DO NOT PERFORM THESE INITIALIZATION IN THE METHOD DECLARATOR !!! // There appears to be a bug in the xlC compiler that causes base to // not be initialized properly !!! // base_size = estimate ? (estimate >> PairSegment::LOG_BLKSIZE) + 1 : 0; base = (PairSegment**) (estimate ? memset(new PairSegment*[base_size], 0, base_size * sizeof(PairSegment*)) : NULL); } ~Pair() { delete [] base; } u2& operator[](const int); private: SegmentPool& segment_pool; PairSegment** base; unsigned base_size; }; // // A portion of the implementation of Triplet. // class TripletSegment { public: enum { LIST_LIMIT = 5, LOG_BLKSIZE = 8, BLKSIZE = 1 << LOG_BLKSIZE, MASK = ~ (BLKSIZE - 1) }; private: struct TargetValuePair { int target; Pair* value; }; SegmentPool& segment_pool; TargetValuePair list[LIST_LIMIT]; unsigned top; Pair** array; public: TripletSegment(SegmentPool& segment_pool_) : segment_pool(segment_pool_), top(0), array(NULL) {} ~TripletSegment() { if (array) { unsigned offset = ((unsigned) list[0].target) & MASK; delete [] (array + offset); } } Pair& Image(int); }; // // A map of (int, int) -> u2 triplets. // class Triplet { public: Triplet(SegmentPool& segment_pool_, unsigned estimate = 0) : segment_pool(segment_pool_) { // // DO NOT PERFORM THESE INITIALIZATION IN THE METHOD DECLARATOR !!! // There appears to be a bug in the xlC compiler that causes base to // not be initialized properly !!! // base_size = estimate ? (estimate >> TripletSegment::LOG_BLKSIZE) + 1 : 0; base = (TripletSegment**) (estimate ? memset(new TripletSegment*[base_size], 0, base_size * sizeof(TripletSegment*)) : NULL); } ~Triplet() { delete [] base; } u2& Image(const int, const int); private: SegmentPool& segment_pool; TripletSegment** base; unsigned base_size; }; // // Manages the memory used by Pairs and Triplets. // class SegmentPool { Tuple triplet_segment_pool; Tuple pair_segment_pool; Tuple pair_pool; public: SegmentPool(); ~SegmentPool(); Pair* AllocatePair(unsigned estimate = 0) { return pair_pool.Next() = new Pair(*this, estimate); } PairSegment* AllocatePairSegment() { return pair_segment_pool.Next() = new PairSegment(); } TripletSegment* AllocateTripletSegment() { return triplet_segment_pool.Next() = new TripletSegment(*this); } }; #ifdef HAVE_JIKES_NAMESPACE } // Close namespace Jikes block #endif #endif // segment_INCLUDED