comparison graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/util/UnsafeArrayTypeWriter.java @ 20892:2818f2862a0d

Use increasingly big arrays to avoid wasting space when writing few bytes
author Christian Wimmer <christian.wimmer@oracle.com>
date Sat, 11 Apr 2015 00:12:10 -0700
parents 220ecaa0cc9b
children acc86d08e1cc
comparison
equal deleted inserted replaced
20891:129a09815063 20892:2818f2862a0d
35 * size 1, 2, 4, and 8 bytes. To avoid copying an array when the buffer size is no longer 35 * size 1, 2, 4, and 8 bytes. To avoid copying an array when the buffer size is no longer
36 * sufficient, the buffer is split into chunks of a fixed size. 36 * sufficient, the buffer is split into chunks of a fixed size.
37 */ 37 */
38 public class UnsafeArrayTypeWriter implements TypeWriter { 38 public class UnsafeArrayTypeWriter implements TypeWriter {
39 39
40 private static final int CHUNK_SIZE = 4000; 40 private static final int MIN_CHUNK_LENGTH = 200;
41 private static final int MAX_CHUNK_LENGTH = 16000;
41 42
42 static class Chunk { 43 static class Chunk {
43 protected final byte[] data = new byte[CHUNK_SIZE]; 44 protected final byte[] data;
44 protected int size; 45 protected int size;
45 protected Chunk next; 46 protected Chunk next;
47
48 protected Chunk(int arrayLength) {
49 data = new byte[arrayLength];
50 }
46 } 51 }
47 52
48 private Chunk firstChunk; 53 private Chunk firstChunk;
49 private Chunk writeChunk; 54 private Chunk writeChunk;
50 private int totalSize; 55 private int totalSize;
51 56
52 public UnsafeArrayTypeWriter() { 57 public UnsafeArrayTypeWriter() {
53 firstChunk = new Chunk(); 58 firstChunk = new Chunk(MIN_CHUNK_LENGTH);
54 writeChunk = firstChunk; 59 writeChunk = firstChunk;
55 } 60 }
56 61
57 @Override 62 @Override
58 public long getBytesWritten() { 63 public long getBytesWritten() {
151 } 156 }
152 } 157 }
153 158
154 private long writeOffset(int writeBytes) { 159 private long writeOffset(int writeBytes) {
155 if (writeChunk.size + writeBytes >= writeChunk.data.length) { 160 if (writeChunk.size + writeBytes >= writeChunk.data.length) {
156 Chunk newChunk = new Chunk(); 161 Chunk newChunk = new Chunk(Math.min(writeChunk.data.length * 2, MAX_CHUNK_LENGTH));
157 writeChunk.next = newChunk; 162 writeChunk.next = newChunk;
158 writeChunk = newChunk; 163 writeChunk = newChunk;
159 } 164 }
160 165
161 assert Unsafe.ARRAY_BYTE_INDEX_SCALE == 1; 166 assert Unsafe.ARRAY_BYTE_INDEX_SCALE == 1;