Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: Bootstrap/BootstrapCodeAllocator.java


1   // BootstrapCodeAllocator.java, created Tue Feb 27  3:00:22 2001 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package Bootstrap;
5   
6   import java.io.DataOutput;
7   import java.io.IOException;
8   import java.util.LinkedList;
9   import java.util.List;
10  import java.util.Vector;
11  
12  import Allocator.CodeAllocator;
13  import Clazz.jq_BytecodeMap;
14  import Clazz.jq_CompiledCode;
15  import Clazz.jq_Method;
16  import Clazz.jq_TryCatch;
17  import Memory.Address;
18  import Memory.CodeAddress;
19  import Run_Time.ExceptionDeliverer;
20  import Util.Assert;
21  import Util.Convert;
22  
23  /**
24   * BootstrapCodeAllocator
25   *
26   * @author  John Whaley <jwhaley@alum.mit.edu>
27   * @version $Id: BootstrapCodeAllocator.java,v 1.13 2003/05/12 10:04:52 joewhaley Exp $
28   */
29  public class BootstrapCodeAllocator extends CodeAllocator {
30  
31      public static final BootstrapCodeAllocator DEFAULT = new BootstrapCodeAllocator();
32      
33      /** Creates new BootstrapCodeAllocator */
34      public BootstrapCodeAllocator() {}
35  
36      private static final int bundle_shift = 12;
37      private static final int bundle_size = 1 << bundle_shift;
38      private static final int bundle_mask = bundle_size-1;
39      private Vector bundles;
40      private byte[] current_bundle;
41      private int bundle_idx;
42      private int idx;
43      
44      private List all_code_relocs, all_data_relocs;
45      
46      public void init() {
47          if (TRACE) System.out.println("Initializing "+this);
48          bundles = new Vector();
49          bundles.addElement(current_bundle = new byte[bundle_size]);
50          bundle_idx = 0;
51          idx = -1;
52          all_code_relocs = new LinkedList();
53          all_data_relocs = new LinkedList();
54      }
55      
56      /** Allocate a code buffer of the given estimated size, such that the given
57       * offset will have the given alignment.
58       * In this allocator, the memory is allocated in chunks, so exceeding the
59       * estimated size doesn't cost extra.
60       *
61       * @param estimatedSize  estimated size, in bytes, of desired code buffer
62       * @param offset  desired offset to align to
63       * @param alignment  desired alignment, or 0 if don't care
64       * @return  the new code buffer
65       */
66      public x86CodeBuffer getCodeBuffer(int estimatedSize,
67                                         int offset,
68                                         int alignment) {
69          // align pointer first
70          int entrypoint = size() + offset;
71          if (alignment > 1) {
72              entrypoint += alignment-1;
73              entrypoint &= ~(alignment-1);
74          }
75          idx += (entrypoint-offset) - size();
76          return new Bootstrapx86CodeBuffer(entrypoint-offset, estimatedSize);
77      }
78      
79      public int size() { return bundle_size*bundle_idx+idx+1; }
80      public void ensureCapacity(int size) {
81          int i = size >> bundle_shift;
82          while (i+1 >= bundles.size()) {
83              bundles.addElement(new byte[bundle_size]);
84          }
85      }
86  
87      public List getAllCodeRelocs() { return all_code_relocs; }
88      public List getAllDataRelocs() { return all_data_relocs; }
89  
90      public void dump(DataOutput out)
91      throws IOException {
92          for (int i=0; i<bundle_idx; ++i) {
93              byte[] bundle = (byte[]) bundles.elementAt(i);
94              out.write(bundle);
95          }
96          out.write(current_bundle, 0, idx+1);
97      }
98      
99      public void patchAbsolute(Address code, Address heap) {
100         poke((CodeAddress) code, heap);
101     }
102     
103     public void patchRelativeOffset(CodeAddress code, CodeAddress target) {
104         poke4(code, target.difference(code)-4);
105     }
106     
107     public void poke(CodeAddress k, Address v) {
108         poke4(k, v.to32BitValue());
109     }
110     public void poke1(CodeAddress k, byte v) {
111         int a = k.to32BitValue();
112         int i = a >> bundle_shift;
113         int j = a & bundle_mask;
114         byte[] b = (byte[])bundles.elementAt(i);
115         b[j] = v;
116     }
117     public void poke2(CodeAddress k, short v) {
118         poke1(k, (byte)(v));
119         poke1((CodeAddress) k.offset(1), (byte)(v>>8));
120     }
121     public void poke4(CodeAddress k, int v) {
122         poke2(k, (short)(v));
123         poke2((CodeAddress) k.offset(2), (short)(v>>16));
124     }
125     public void poke8(CodeAddress k, long v) {
126         poke4(k, (int)(v));
127         poke4((CodeAddress) k.offset(4), (int)(v>>32));
128     }
129     
130     public Address peek(CodeAddress k) {
131         return new BootstrapCodeAddress(peek4(k));
132     }
133     public byte peek1(CodeAddress k) {
134         int a = k.to32BitValue();
135         int i = a >> bundle_shift;
136         int j = a & bundle_mask;
137         byte[] b = (byte[])bundles.elementAt(i);
138         return b[j];
139     }
140     public short peek2(CodeAddress k) {
141         return Convert.twoBytesToShort(peek1(k), peek1((CodeAddress) k.offset(1)));
142     }
143     public int peek4(CodeAddress k) {
144         return Convert.fourBytesToInt(peek1(k), peek1((CodeAddress) k.offset(1)), peek1((CodeAddress) k.offset(2)), peek1((CodeAddress) k.offset(3)));
145     }
146     public long peek8(CodeAddress k) {
147         return Convert.twoIntsToLong(peek4(k), peek4((CodeAddress) k.offset(4)));
148     }
149     
150     public class Bootstrapx86CodeBuffer extends CodeAllocator.x86CodeBuffer {
151 
152         private int startIndex;
153         private int entryIndex;
154         
155         Bootstrapx86CodeBuffer(int startIndex, int estSize) {
156             this.startIndex = startIndex;
157             ensureCapacity(startIndex+estSize);
158         }
159         
160         public int getStartIndex() { return startIndex; }
161         public int getEntryIndex() { return entryIndex; }
162         
163         public int getCurrentOffset() { return size()-startIndex; }
164         public CodeAddress getStartAddress() { return new BootstrapCodeAddress(getStartIndex()); }
165         public CodeAddress getCurrentAddress() { return new BootstrapCodeAddress(size()); }
166         
167         public void setEntrypoint() { entryIndex = size(); }
168 
169         public void checkSize() {
170             if (idx >= bundle_size-1) {
171                 if (bundle_idx < bundles.size()-1) {
172                     if (TRACE) System.out.println("getting next bundle idx "+(bundle_idx+1));
173                     current_bundle = (byte[])bundles.get(++bundle_idx);
174                     idx -= bundle_size;
175                 } else {
176                     if (TRACE) System.out.println("allocing new bundle idx "+(bundle_idx+1));
177                     bundles.addElement(current_bundle = new byte[bundle_size]);
178                     ++bundle_idx; idx -= bundle_size;
179                 }
180             }
181         }
182 
183         public void add1(byte i) {
184             checkSize(); current_bundle[++idx] = i;
185         }
186         public void add2_endian(int i) {
187             checkSize(); current_bundle[++idx] = (byte)(i);
188             checkSize(); current_bundle[++idx] = (byte)(i >> 8);
189         }
190         public void add2(int i) {
191             checkSize(); current_bundle[++idx] = (byte)(i >> 8);
192             checkSize(); current_bundle[++idx] = (byte)(i);
193         }
194         public void add3(int i) {
195             checkSize(); current_bundle[++idx] = (byte)(i >> 16);
196             checkSize(); current_bundle[++idx] = (byte)(i >> 8);
197             checkSize(); current_bundle[++idx] = (byte)(i);
198         }
199         public void add4_endian(int i) {
200             checkSize(); current_bundle[++idx] = (byte)(i);
201             checkSize(); current_bundle[++idx] = (byte)(i >> 8);
202             checkSize(); current_bundle[++idx] = (byte)(i >> 16);
203             checkSize(); current_bundle[++idx] = (byte)(i >> 24);
204         }
205 
206         public byte get1(int k) {
207             return peek1(new BootstrapCodeAddress(k+startIndex));
208         }
209 
210         public int get4_endian(int k) {
211             return peek4(new BootstrapCodeAddress(k+startIndex));
212         }
213 
214         public void put1(int k, byte instr) {
215             poke1(new BootstrapCodeAddress(k+startIndex), instr);
216         }
217 
218         public void put4_endian(int k, int instr) {
219             poke4(new BootstrapCodeAddress(k+startIndex), instr);
220         }
221 
222         public void skip(int nbytes) {
223             Assert._assert(nbytes < bundle_size);
224             idx += nbytes;
225             //checkSize();
226         }
227 
228         public jq_CompiledCode allocateCodeBlock(jq_Method m, jq_TryCatch[] ex, jq_BytecodeMap bcm,
229                                                  ExceptionDeliverer exd, int stackframesize,
230                                                  List code_relocs, List data_relocs) {
231             int total = getCurrentOffset();
232             int start = getStartIndex();
233             int entry = getEntryIndex();
234             if (code_relocs != null)
235                 all_code_relocs.addAll(code_relocs);
236             if (data_relocs != null)
237                 all_data_relocs.addAll(data_relocs);
238             jq_CompiledCode cc = new jq_CompiledCode(m, new BootstrapCodeAddress(start),
239                                                      total, new BootstrapCodeAddress(entry),
240                                                      ex, bcm, exd, stackframesize,
241                                                      code_relocs, data_relocs);
242             CodeAllocator.registerCode(cc);
243             return cc;
244         }
245     
246     }
247     
248 }