1 // $Id: segment.h,v 1.10 2002/12/11 00:55:04 ericb Exp $ -*- c++ -*-
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 1999, 2000, 2001, 2002 International Business
7 // Machines Corporation and others.  All Rights Reserved.
8 // You must accept the terms of that agreement to use this software.
9 //
10 
11 #ifndef segment_INCLUDED
12 #define segment_INCLUDED
13 
14 #include "platform.h"
15 #include "tuple.h"
16 
17 #ifdef HAVE_JIKES_NAMESPACE
18 namespace Jikes { // Open namespace Jikes block
19 #endif
20 
21 class SegmentPool;
22 
23 
24 //
25 // A portion of the implementation of Pair.
26 //
27 class PairSegment
28 {
29 public:
30     enum
31     {
32         LIST_LIMIT = 5,
33         LOG_BLKSIZE = 8,
34         BLKSIZE = 1 << LOG_BLKSIZE,
35         MASK = ~ (BLKSIZE - 1)
36     };
37 
38 private:
39     struct TargetValuePair
40     {
41         int target;
42         u2 value;
43     };
44 
45     TargetValuePair list[LIST_LIMIT];
46     unsigned top;
47     u2* array;
48 
49 public:
PairSegment()50     PairSegment() : top(0), array(NULL) {}
51 
~PairSegment()52     ~PairSegment()
53     {
54         if (array)
55         {
56             unsigned offset = ((unsigned) list[0].target) & MASK;
57             delete [] (array + offset);
58         }
59     }
60 
61     //
62     // Returns the modifiable value associated with the integer key.
63     //
64     u2& Image(int);
65 };
66 
67 
68 //
69 // A map of int -> u2 pairs.
70 //
71 class Pair
72 {
73 public:
74     Pair(SegmentPool& segment_pool_, unsigned estimate = 0)
segment_pool(segment_pool_)75         : segment_pool(segment_pool_)
76     {
77         //
78         // DO NOT PERFORM THESE INITIALIZATION IN THE METHOD DECLARATOR !!!
79         // There appears to be a bug in the xlC compiler that causes base to
80         // not be initialized properly !!!
81         //
82         base_size = estimate ? (estimate >> PairSegment::LOG_BLKSIZE) + 1 : 0;
83         base = (PairSegment**) (estimate
84                                 ? memset(new PairSegment*[base_size], 0,
85                                          base_size * sizeof(PairSegment*))
86                                 : NULL);
87     }
88 
~Pair()89     ~Pair() { delete [] base; }
90 
91     u2& operator[](const int);
92 
93 private:
94     SegmentPool& segment_pool;
95     PairSegment** base;
96     unsigned base_size;
97 };
98 
99 
100 //
101 // A portion of the implementation of Triplet.
102 //
103 class TripletSegment
104 {
105 public:
106     enum
107     {
108         LIST_LIMIT = 5,
109         LOG_BLKSIZE = 8,
110         BLKSIZE = 1 << LOG_BLKSIZE,
111         MASK = ~ (BLKSIZE - 1)
112     };
113 
114 private:
115     struct TargetValuePair
116     {
117         int target;
118         Pair* value;
119     };
120 
121     SegmentPool& segment_pool;
122 
123     TargetValuePair list[LIST_LIMIT];
124     unsigned top;
125     Pair** array;
126 
127 public:
TripletSegment(SegmentPool & segment_pool_)128     TripletSegment(SegmentPool& segment_pool_)
129         : segment_pool(segment_pool_),
130           top(0),
131           array(NULL)
132     {}
133 
~TripletSegment()134     ~TripletSegment()
135     {
136         if (array)
137         {
138             unsigned offset = ((unsigned) list[0].target) & MASK;
139             delete [] (array + offset);
140         }
141     }
142 
143     Pair& Image(int);
144 };
145 
146 
147 //
148 // A map of (int, int) -> u2 triplets.
149 //
150 class Triplet
151 {
152 public:
153     Triplet(SegmentPool& segment_pool_, unsigned estimate = 0)
segment_pool(segment_pool_)154         : segment_pool(segment_pool_)
155     {
156         //
157         // DO NOT PERFORM THESE INITIALIZATION IN THE METHOD DECLARATOR !!!
158         // There appears to be a bug in the xlC compiler that causes base to
159         // not be initialized properly !!!
160         //
161         base_size = estimate
162             ? (estimate >> TripletSegment::LOG_BLKSIZE) + 1 : 0;
163         base = (TripletSegment**)
164             (estimate ? memset(new TripletSegment*[base_size], 0,
165                                base_size * sizeof(TripletSegment*))
166              : NULL);
167     }
168 
~Triplet()169     ~Triplet() { delete [] base; }
170 
171     u2& Image(const int, const int);
172 
173 private:
174     SegmentPool& segment_pool;
175     TripletSegment** base;
176     unsigned base_size;
177 };
178 
179 
180 //
181 // Manages the memory used by Pairs and Triplets.
182 //
183 class SegmentPool
184 {
185     Tuple<TripletSegment*> triplet_segment_pool;
186     Tuple<PairSegment*> pair_segment_pool;
187     Tuple<Pair*> pair_pool;
188 
189 public:
190     SegmentPool();
191     ~SegmentPool();
192 
193     Pair* AllocatePair(unsigned estimate = 0)
194     {
195         return pair_pool.Next() = new Pair(*this, estimate);
196     }
AllocatePairSegment()197     PairSegment* AllocatePairSegment()
198     {
199         return pair_segment_pool.Next() = new PairSegment();
200     }
AllocateTripletSegment()201     TripletSegment* AllocateTripletSegment()
202     {
203         return triplet_segment_pool.Next() = new TripletSegment(*this);
204     }
205 };
206 
207 #ifdef HAVE_JIKES_NAMESPACE
208 } // Close namespace Jikes block
209 #endif
210 
211 #endif // segment_INCLUDED
212 
213