1 // $Id: segment.cpp,v 1.13 2002/12/11 00:55:04 ericb Exp $
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 #include "segment.h"
12 
13 #ifdef HAVE_JIKES_NAMESPACE
14 namespace Jikes { // Open namespace Jikes block
15 #endif
16 
Image(int target)17 u2& PairSegment::Image(int target)
18 {
19     if (array == NULL)
20     {
21         for (unsigned i = 0; i < top; i++)
22         {
23             if (list[i].target == target)
24                 return list[i].value;
25         }
26 
27         if (top < (unsigned) LIST_LIMIT)
28         {
29             unsigned j = top++;
30             list[j].target = target;
31             list[j].value = 0;
32             return list[j].value;
33         }
34 
35         unsigned offset = ((unsigned) target) & MASK;
36         array = (u2*) memset(new u2[BLKSIZE], 0, BLKSIZE * sizeof(u2));
37         array -= offset;
38 
39         for (unsigned j = 0; j < top; j++)
40             array[list[j].target] = list[j].value;
41     }
42     return array[target];
43 }
44 
45 
operator [](const int target)46 u2& Pair::operator[](const int target)
47 {
48     unsigned k = ((unsigned) target) >> PairSegment::LOG_BLKSIZE;
49 
50     if (k >= base_size)
51     {
52         unsigned old_base_size = base_size;
53         PairSegment** old_base = base;
54 
55         //
56         // For the first allocation, assume that there won't be that many more.
57         // If there are others add a much bigger margin.
58         //
59         base_size = k + (old_base_size == 0 ? 2 : 16);
60         base = new PairSegment*[base_size];
61 
62         if (old_base != NULL)
63         {
64             memcpy(base, old_base, old_base_size * sizeof(PairSegment*));
65             delete [] old_base;
66         }
67 
68         memset(&base[old_base_size], 0,
69                (base_size - old_base_size) * sizeof(PairSegment*));
70     }
71     if (! base[k])
72         base[k] = segment_pool.AllocatePairSegment();
73     return base[k] -> Image(target);
74 }
75 
76 
Image(int target)77 Pair& TripletSegment::Image(int target)
78 {
79     if (array == NULL)
80     {
81         for (unsigned i = 0; i < top; i++)
82         {
83             if (list[i].target == target)
84                 return *list[i].value;
85         }
86 
87         if (top < (unsigned) LIST_LIMIT)
88         {
89             unsigned j = top++;
90             list[j].target = target;
91             return *(list[j].value = segment_pool.AllocatePair());
92         }
93 
94         unsigned offset = ((unsigned) target) & MASK;
95         array = (Pair**) memset(new Pair*[BLKSIZE], 0,
96                                 BLKSIZE * sizeof(Pair*));
97         array -= offset;
98 
99         for (unsigned j = 0; j < top; j++)
100             array[list[j].target] = list[j].value;
101     }
102     return *(array[target] ? array[target]
103              : array[target] = segment_pool.AllocatePair());
104 }
105 
106 
Image(const int target,const int target2)107 u2& Triplet::Image(const int target, const int target2)
108 {
109     unsigned k = ((unsigned) target) >> TripletSegment::LOG_BLKSIZE;
110 
111     if (k >= base_size)
112     {
113         unsigned old_base_size = base_size;
114         TripletSegment** old_base = base;
115 
116         base_size = k + 4;
117         base = new TripletSegment*[base_size];
118 
119         if (old_base)
120         {
121             memcpy(base, old_base, old_base_size * sizeof(TripletSegment*));
122             delete [] old_base;
123         }
124         memset(&base[old_base_size], 0,
125                (base_size - old_base_size) * sizeof(TripletSegment *));
126     }
127 
128     if (! base[k])
129         base[k] = segment_pool.AllocateTripletSegment();
130     return base[k] -> Image(target)[target2];
131 }
132 
133 
SegmentPool()134 SegmentPool::SegmentPool()
135     : triplet_segment_pool(1024),
136       pair_segment_pool(4096),
137       pair_pool(4096)
138 {}
139 
140 
~SegmentPool()141 SegmentPool::~SegmentPool()
142 {
143     unsigned i;
144     for (i = 0; i < triplet_segment_pool.Length(); i++)
145         delete triplet_segment_pool[i];
146     for (i = 0; i < pair_segment_pool.Length(); i++)
147         delete pair_segment_pool[i];
148     for (i = 0; i < pair_pool.Length(); i++)
149         delete pair_pool[i];
150 }
151 
152 #ifdef HAVE_JIKES_NAMESPACE
153 } // Close namespace Jikes block
154 #endif
155 
156