3261N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * Collection of relocatable constant pool references. 0N/A * It operates with respect to a particular byte array, 0N/A * and stores some of its state in the bytes themselves. 0N/A * As a Collection, it can be iterated over, but it is not a List, 0N/A * since it does not natively support indexed access. 0N/A byte[]
bytes;
// the subject of the relocations 0N/A int head;
// desc locating first reloc 0N/A int tail;
// desc locating last reloc 0N/A int[]
bigDescs;
// descs which cannot be stored in the bytes 0N/A // A "desc" (descriptor) is a bit-encoded pair of a location 0N/A // and format. Every fixup occurs at a "desc". Until final 0N/A // patching, bytes addressed by descs may also be used to 0N/A // link this data structure together. If the bytes are missing, 0N/A // or if the "desc" is too large to encode in the bytes, 0N/A // it is kept in the bigDescs array. 0N/A // If there are no bytes, all descs are kept in bigDescs. 0N/A // cleverly share empty bigDescs: 0N/A //System.out.println("clean "+fx); 0N/A // do not trim to size, however 0N/A // One or the other representations is deficient. 0N/A // Construct a checkpoint. 0N/A // assume newBytes is some sort of bitwise copy of the old bytes 0N/A // fill pointer of bigDescs array is in element [0] 0N/A // Special values for the static methods. 0N/A // Stored loc field is difference between its own loc and next loc. 0N/A default:
assert(
false);
0N/A // Failure. Caller must allocate a bigDesc. 0N/A default:
assert(
false);
0N/A /** Simple and necessary tuple to present each fixup. */ 0N/A int desc;
// location and format of reloc 0N/A // Ordering depends only on location. 0N/A if (!(x
instanceof Fixup))
return false;
0N/A // Fetch next desc eagerly, in case this fixup gets finalized. 0N/A // The unused extra byte is "asserted" to be equal to BI. 0N/A // This helps keep the overflow descs in sync. 0N/A // Use knowledge of Itr structure to avoid building little structs. 0N/A // Here is how things get added: 0N/A // Store new desc in previous tail. 0N/A // The collection must go in ascending order, and not overlap. 0N/A //System.out.println("bigDescs["+bigSize+"] = "+thisDesc); 0N/A /// Static methods that optimize the use of this class. 0N/A // Special convention: If the attribute has a 0N/A // U2 relocation at position zero, store the Entry 0N/A // rather than building a Fixups structure. 0N/A // Recognize the special convention: 0N/A // Iterate over all the references in this set of fixups. 0N/A // Special convention; see above. 0N/A // Clear out this set of fixups by replacing each reference 0N/A // by a hardcoded coding of its reference, drawn from ix. 0N/A // Special convention; see above. 0N/A //System.out.println("finish "+fx+" = "+index); 0N/A // Note that the iterator has already fetched the 0N/A // bytes we are about to overwrite. 0N/A // Further iterations should do nothing: 0N/A public static void main(String[] av) { 0N/A byte[] bytes = new byte[1 << 20]; 0N/A ConstantPool cp = new ConstantPool(); 0N/A Fixups f = new Fixups(bytes); 0N/A boolean isU1 = false; 0N/A int[] locs = new int[100]; 0N/A final int[] indexes = new int[100]; 0N/A for (int loc = 0; loc < bytes.length; loc++) { 0N/A if (loc == nextLoc && loc+1 < bytes.length) { 0N/A int fmt = (isU1 ? U1_FORMAT : U2_FORMAT); 0N/A Entry e = ConstantPool.getUtf8Entry("L"+loc); 0N/A // Make it close in. 0N/A nextLoc += fmtLen(fmt) + (iptr < 5 ? 0 : 1); 0N/A span = (int)(span * 1.77); 0N/A // Here are the bytes that would have gone here: 0N/A if (fmt == U1_FORMAT) { 0N/A indexes[iptr++] = (loc & 0xFF); 0N/A indexes[iptr++] = ((loc & 0xFF) << 8) | ((loc+1) & 0xFF); 0N/A ++loc; // skip a byte 0N/A bytes[loc] = (byte)loc; 0N/A System.out.println("size="+f.size() 0N/A +" overflow="+(f.bigDescs[BIGSIZE]-1)); 0N/A System.out.println("Fixups: "+f); 0N/A // Test collection contents. 0N/A assert(iptr == 1+f.size()); 0N/A List l = new ArrayList(f); 0N/A Collections.sort(l); // should not change the order 0N/A if (!l.equals(new ArrayList(f))) System.out.println("** disordered"); 0N/A if (!l.equals(new ArrayList(f))) System.out.println("** bad set 1"); 0N/A if (!l.equals(new ArrayList(f))) System.out.println("** bad set 2"); 0N/A Fixups f3 = new Fixups(f); 0N/A if (!l.equals(new ArrayList(f3))) System.out.println("** bad set 3"); 0N/A Iterator fi = f.iterator(); 0N/A for (int i = 1; i < iptr; i++) { 0N/A Fixup fx = (Fixup) fi.next(); 0N/A if (fx.location() != locs[i]) { 0N/A System.out.println("** "+fx+" != "+locs[i]); 0N/A if (fx.format() == U1_FORMAT) 0N/A System.out.println(fx+" -> "+bytes[locs[i]]); 0N/A System.out.println(fx+" -> "+bytes[locs[i]]+" "+bytes[locs[i]+1]); 0N/A assert(!fi.hasNext()); 0N/A indexes[0] = 1; // like iptr 0N/A Index ix = new Index("ix") { 0N/A public int indexOf(Entry e) { 0N/A return indexes[indexes[0]++]; 0N/A for (int loc = 0; loc < bytes.length; loc++) { 0N/A if (bytes[loc] != (byte)loc) { 0N/A System.out.println("** ["+loc+"] = "+bytes[loc]+" != "+(byte)loc);