Mercurial > hg > truffle
view graal/com.oracle.max.asm/src/com/oracle/max/asm/Buffer.java @ 5563:6a2671066204
added NewInstanceSnippets for lowering NewInstanceNodes (currently disabled by default)
added Word type and WordTypeRewriterPhase to support programming against machine word values in snippets without duplicating the code for 32 and 64 bit platforms
added GraphUtil.approxSourceLocation() utility method for getting an approximate source code location for a node
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 11 Jun 2012 15:39:57 +0200 |
parents | bc8527f3071c |
children |
line wrap: on
line source
/* * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.max.asm; import java.util.*; /** * Code buffer management for the assembler. Support for little endian and big endian architectures is implemented using subclasses. */ public abstract class Buffer { protected byte[] data; protected int position; public Buffer() { data = new byte[AsmOptions.InitialCodeBufferSize]; } public void reset() { position = 0; } public int position() { return position; } public void setPosition(int position) { assert position >= 0 && position <= data.length; this.position = position; } /** * Closes this buffer. No extra data can be written to this buffer after * this call. * * @param trimmedCopy * if {@code true}, then a copy of the underlying byte array up * to (but not including) {@code position()} is returned * @return the data in this buffer or a trimmed copy if {@code trimmedCopy} * is {@code true} */ public byte[] close(boolean trimmedCopy) { byte[] result = trimmedCopy ? Arrays.copyOf(data, position()) : data; data = null; return result; } public byte[] copyData(int start, int end) { return Arrays.copyOfRange(data, start, end); } /** * Copies the data from this buffer into a given array. * * @param dst * the destination array * @param off * starting position in {@code dst} * @param len * number of bytes to copy */ public void copyInto(byte[] dst, int off, int len) { System.arraycopy(data, 0, dst, off, len); } protected void ensureSize(int length) { if (length >= data.length) { data = Arrays.copyOf(data, length * 4); } } public void emitBytes(byte[] arr, int off, int len) { ensureSize(position + len); System.arraycopy(arr, off, data, position, len); position += len; } public void emitByte(int b) { position = emitByte(b, position); } public void emitShort(int b) { position = emitShort(b, position); } public void emitInt(int b) { position = emitInt(b, position); } public void emitLong(long b) { position = emitLong(b, position); } public int emitByte(int b, int pos) { assert NumUtil.isUByte(b); int newPos = pos + 1; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); return newPos; } public abstract int emitShort(int b, int pos); public abstract int emitInt(int b, int pos); public abstract int emitLong(long b, int pos); public int getByte(int pos) { return data[pos] & 0xff; } public abstract int getShort(int pos); public abstract int getInt(int pos); public static final class BigEndian extends Buffer { @Override public int emitShort(int b, int pos) { assert NumUtil.isUShort(b); int newPos = pos + 2; ensureSize(pos + 2); data[pos] = (byte) ((b >> 8) & 0xFF); data[pos + 1] = (byte) (b & 0xFF); return newPos; } @Override public int emitInt(int b, int pos) { int newPos = pos + 4; ensureSize(newPos); data[pos] = (byte) ((b >> 24) & 0xFF); data[pos + 1] = (byte) ((b >> 16) & 0xFF); data[pos + 2] = (byte) ((b >> 8) & 0xFF); data[pos + 3] = (byte) (b & 0xFF); return newPos; } @Override public int emitLong(long b, int pos) { int newPos = pos + 8; ensureSize(newPos); data[pos] = (byte) ((b >> 56) & 0xFF); data[pos + 1] = (byte) ((b >> 48) & 0xFF); data[pos + 2] = (byte) ((b >> 40) & 0xFF); data[pos + 3] = (byte) ((b >> 32) & 0xFF); data[pos + 4] = (byte) ((b >> 24) & 0xFF); data[pos + 5] = (byte) ((b >> 16) & 0xFF); data[pos + 6] = (byte) ((b >> 8) & 0xFF); data[pos + 7] = (byte) (b & 0xFF); return newPos; } @Override public int getShort(int pos) { return (data[pos + 0] & 0xff) << 8 | (data[pos + 1] & 0xff) << 0; } @Override public int getInt(int pos) { return (data[pos + 0] & 0xff) << 24 | (data[pos + 1] & 0xff) << 16 | (data[pos + 2] & 0xff) << 8 | (data[pos + 3] & 0xff) << 0; } } public static final class LittleEndian extends Buffer { @Override public int emitShort(int b, int pos) { assert NumUtil.isUShort(b); int newPos = pos + 2; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); data[pos + 1] = (byte) ((b >> 8) & 0xFF); return newPos; } @Override public int emitInt(int b, int pos) { int newPos = pos + 4; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); data[pos + 1] = (byte) ((b >> 8) & 0xFF); data[pos + 2] = (byte) ((b >> 16) & 0xFF); data[pos + 3] = (byte) ((b >> 24) & 0xFF); return newPos; } @Override public int emitLong(long b, int pos) { int newPos = pos + 8; ensureSize(newPos); data[pos] = (byte) (b & 0xFF); data[pos + 1] = (byte) ((b >> 8) & 0xFF); data[pos + 2] = (byte) ((b >> 16) & 0xFF); data[pos + 3] = (byte) ((b >> 24) & 0xFF); data[pos + 4] = (byte) ((b >> 32) & 0xFF); data[pos + 5] = (byte) ((b >> 40) & 0xFF); data[pos + 6] = (byte) ((b >> 48) & 0xFF); data[pos + 7] = (byte) ((b >> 56) & 0xFF); return newPos; } @Override public int getShort(int pos) { return (data[pos + 1] & 0xff) << 8 | (data[pos + 0] & 0xff) << 0; } @Override public int getInt(int pos) { return (data[pos + 3] & 0xff) << 24 | (data[pos + 2] & 0xff) << 16 | (data[pos + 1] & 0xff) << 8 | (data[pos + 0] & 0xff) << 0; } } }