Buffer.java revision 12968:4d8a004e5c6d
1/* 2 * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.graalvm.compiler.asm; 24 25import org.graalvm.compiler.core.common.NumUtil; 26 27import java.nio.ByteBuffer; 28import java.nio.ByteOrder; 29import java.util.Arrays; 30 31/** 32 * Code buffer management for the assembler. 33 */ 34final class Buffer { 35 36 protected ByteBuffer data; 37 38 Buffer(ByteOrder order) { 39 data = ByteBuffer.allocate(AsmOptions.InitialCodeBufferSize); 40 data.order(order); 41 } 42 43 public int position() { 44 return data.position(); 45 } 46 47 public void setPosition(int position) { 48 assert position >= 0 && position <= data.limit(); 49 data.position(position); 50 } 51 52 /** 53 * Closes this buffer. Any further operations on a closed buffer will result in a 54 * {@link NullPointerException}. 55 * 56 * @param trimmedCopy if {@code true}, then a copy of the underlying byte array up to (but not 57 * including) {@code position()} is returned 58 * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} is {@code true} 59 */ 60 public byte[] close(boolean trimmedCopy) { 61 byte[] result = data.array(); 62 if (trimmedCopy) { 63 // Make a copy even if result.length == data.position() since 64 // the API for trimmedCopy states a copy is always made 65 result = Arrays.copyOf(result, data.position()); 66 } 67 data = null; 68 return result; 69 } 70 71 public byte[] copyData(int start, int end) { 72 if (data == null) { 73 return null; 74 } 75 return Arrays.copyOfRange(data.array(), start, end); 76 } 77 78 /** 79 * Copies the data from this buffer into a given array. 80 * 81 * @param dst the destination array 82 * @param off starting position in {@code dst} 83 * @param len number of bytes to copy 84 */ 85 public void copyInto(byte[] dst, int off, int len) { 86 System.arraycopy(data.array(), 0, dst, off, len); 87 } 88 89 protected void ensureSize(int length) { 90 if (length >= data.limit()) { 91 byte[] newBuf = Arrays.copyOf(data.array(), length * 4); 92 ByteBuffer newData = ByteBuffer.wrap(newBuf); 93 newData.order(data.order()); 94 newData.position(data.position()); 95 data = newData; 96 } 97 } 98 99 public void emitBytes(byte[] arr, int off, int len) { 100 ensureSize(data.position() + len); 101 data.put(arr, off, len); 102 } 103 104 public void emitByte(int b) { 105 assert NumUtil.isUByte(b) || NumUtil.isByte(b); 106 ensureSize(data.position() + 1); 107 data.put((byte) (b & 0xFF)); 108 } 109 110 public void emitShort(int b) { 111 assert NumUtil.isUShort(b) || NumUtil.isShort(b); 112 ensureSize(data.position() + 2); 113 data.putShort((short) b); 114 } 115 116 public void emitInt(int b) { 117 ensureSize(data.position() + 4); 118 data.putInt(b); 119 } 120 121 public void emitLong(long b) { 122 ensureSize(data.position() + 8); 123 data.putLong(b); 124 } 125 126 public void emitBytes(byte[] arr, int pos) { 127 final int len = arr.length; 128 ensureSize(pos + len); 129 // Write directly into the underlying array so as to not 130 // change the ByteBuffer's position 131 System.arraycopy(arr, 0, data.array(), pos, len); 132 } 133 134 public void emitByte(int b, int pos) { 135 assert NumUtil.isUByte(b) || NumUtil.isByte(b); 136 ensureSize(pos + 1); 137 data.put(pos, (byte) (b & 0xFF)); 138 } 139 140 public void emitShort(int b, int pos) { 141 assert NumUtil.isUShort(b) || NumUtil.isShort(b); 142 ensureSize(pos + 2); 143 data.putShort(pos, (short) b).position(); 144 } 145 146 public void emitInt(int b, int pos) { 147 ensureSize(pos + 4); 148 data.putInt(pos, b).position(); 149 } 150 151 public void emitLong(long b, int pos) { 152 ensureSize(pos + 8); 153 data.putLong(pos, b).position(); 154 } 155 156 public int getByte(int pos) { 157 int b = data.get(pos); 158 return b & 0xff; 159 } 160 161 public int getShort(int pos) { 162 short s = data.getShort(pos); 163 return s & 0xffff; 164 } 165 166 public int getInt(int pos) { 167 return data.getInt(pos); 168 } 169 170 public void reset() { 171 data.clear(); 172 } 173} 174