memoryresourceimpl.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,009 行 · 第 1/2 页

JAVA
1,009
字号
/*
 * $Id: MemoryResourceImpl.java,v 1.1 2003/11/25 11:41:17 epr Exp $
 */
package org.jnode.vm;

import org.jnode.system.MemoryResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.system.ResourceOwner;
import org.jnode.system.SimpleResourceOwner;
import org.jnode.vm.classmgr.VmArray;

/**
 * Default implementation of MemoryResource.
 * 
 * @author Ewout Prangsma (epr@users.sourceforge.net)
 */
final class MemoryResourceImpl extends Region implements MemoryResource {

	/** Start address */
	private final Address start;
	/** Exclusive end address */
	private final Address end;
	/** Size in bytes */
	private final long size;
	/** Has this resource been released? */
	private boolean released;
	/** First active memory-resource */
	private static Region resources;
	/** Data for mapping over byte arrays */
	private final Object data;
	/** Resource owner for byte arrays */
	private static final ResourceOwner BYTE_ARRAY_OWNER = new SimpleResourceOwner("byte-array");
	/** Size of an object reference */
	private final int slotSize;

	/**
	 * Create a new instance
	 * 
	 * @param owner
	 * @param start
	 * @param size
	 */
	private MemoryResourceImpl(ResourceOwner owner, Address start, long size) {
		super(owner);
		this.start = start;
		this.end = Unsafe.add(start, Unsafe.longToAddress(size));
		this.size = size;
		this.released = false;
		this.data = null;
		this.slotSize = Unsafe.getCurrentProcessor().getArchitecture().getReferenceSize();
	}

	public MemoryResourceImpl(Object arrayData, int length, int elementSize) {
		super(BYTE_ARRAY_OWNER);
		this.data = arrayData;
		this.size = length * elementSize;
		this.start = Address.addressOfArrayData(arrayData);
		this.end = Unsafe.add(start, length * elementSize);
		this.released = false;
		this.slotSize = Unsafe.getCurrentProcessor().getArchitecture().getReferenceSize();
	}

	/**
	 * Claim a memory region
	 * 
	 * @param owner
	 * @param start
	 * @param size
	 * @param mode
	 * @return The claimed resource
	 * @throws ResourceNotFreeException
	 */
	protected static synchronized MemoryResource claimMemoryResource(ResourceOwner owner, Address start, long size, int mode) throws ResourceNotFreeException {
		if (start != null) {
			final MemoryResourceImpl res = new MemoryResourceImpl(owner, start, size);
			if (isFree(resources, res)) {
				resources = add(resources, res);
				return res;
			} else {
				throw new ResourceNotFreeException();
			}
		} else {
			// Find a range
			Address ptr;
			if (mode == ResourceManager.MEMMODE_ALLOC_DMA) {
				ptr = Unsafe.getMinAddress();
			} else {
				ptr = Unsafe.getMemoryEnd();
			}
			MemoryResourceImpl res = new MemoryResourceImpl(owner, ptr, size);
			while (!isFree(resources, res)) {
				ptr = Unsafe.add(ptr, 64 * 1024);
				res = new MemoryResourceImpl(owner, ptr, size);
			}
			resources = add(resources, res);
			return res;
		}
	}

	/**
	 * Gets a 8-bit signed byte at the given memory address
	 * 
	 * @param memPtr
	 * @return byte
	 */
	public byte getByte(int memPtr) {
		testMemPtr(memPtr, 1);
		return Unsafe.getByte(start, memPtr);
	}

	/**
	 * Gets multiple 8-bit signed bytes from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getBytes(int memPtr, byte[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + dstOfs);
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length);
	}

	/**
	 * Gets a 16-bit signed short at the given memory address
	 * 
	 * @param memPtr
	 * @return short
	 */
	public short getShort(int memPtr) {
		testMemPtr(memPtr, 2);
		return Unsafe.getShort(start, memPtr);
	}

	/**
	 * Gets multiple 16-bit signed bytes from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getShorts(int memPtr, short[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 2);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 2));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 2);
	}

	/**
	 * Gets a 16-bit unsigned char at the given memory address
	 * 
	 * @param memPtr
	 * @return char
	 */
	public char getChar(int memPtr) {
		testMemPtr(memPtr, 2);
		return Unsafe.getChar(start, memPtr);
	}

	/**
	 * Gets multiple 16-bit unsigned chars from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getChars(int memPtr, char[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 2);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 2));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 2);
	}

	/**
	 * Gets a 32-bit signed int at the given memory address
	 * 
	 * @param memPtr
	 * @return int
	 */
	public int getInt(int memPtr) {
		testMemPtr(memPtr, 4);
		return Unsafe.getInt(start, memPtr);
	}

	/**
	 * Gets multiple 32-bit signed ints from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getInts(int memPtr, char[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 4);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 4));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 4);
	}

	/**
	 * Gets a 64-bit signed long at the given memory address
	 * 
	 * @param memPtr
	 * @return long
	 */
	public long getLong(int memPtr) {
		testMemPtr(memPtr, 8);
		return Unsafe.getLong(start, memPtr);
	}

	/**
	 * Gets multiple 64-bit signed longs from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getLongs(int memPtr, long[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 8);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 8));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 8);
	}

	/**
	 * Gets a float at the given memory address
	 * 
	 * @param memPtr
	 * @return float
	 */
	public float getFloat(int memPtr) {
		testMemPtr(memPtr, 4);
		return Unsafe.getFloat(start, memPtr);
	}

	/**
	 * Gets multiple 32-bit floats from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getChars(int memPtr, float[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 4);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 4));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 4);
	}

	/**
	 * Gets a double at the given memory address
	 * 
	 * @param memPtr
	 * @return double
	 */
	public double getDouble(int memPtr) {
		testMemPtr(memPtr, 8);
		return Unsafe.getDouble(start, memPtr);
	}

	/**
	 * Gets multiple 64-bit doubles from the given memory address
	 * 
	 * @param memPtr
	 * @param dst
	 * @param dstOfs
	 * @param length
	 */
	public void getDoubles(int memPtr, double[] dst, int dstOfs, int length) {
		if (dstOfs < 0) {
			throw new IndexOutOfBoundsException("dstOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (dstOfs + length > dst.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(memPtr, length * 8);
		Address dstPtr = Unsafe.add(Unsafe.addressOf(dst), (VmArray.DATA_OFFSET * slotSize) + (dstOfs * 8));
		Unsafe.copy(Unsafe.add(start, memPtr), dstPtr, length * 8);
	}

	/**
	 * Gets a object reference at the given memory address
	 * 
	 * @param memPtr
	 * @return Object
	 */
	public Object getObject(int memPtr) {
		if (this.data != null) {
			throw new SecurityException("Cannot get an Object from a byte-array");
		}
		testMemPtr(memPtr, 4);
		return Unsafe.getObject(start, memPtr);
	}

	/**
	 * Sets a byte at a given memory address
	 * 
	 * @param memPtr
	 * @param value
	 */
	public void setByte(int memPtr, byte value) {
		testMemPtr(memPtr, 1);
		Unsafe.setByte(start, memPtr, value);
	}

	/**
	 * Sets multiple 8-bit signed bytes at the given memory address
	 * 
	 * @param src
	 * @param srcOfs
	 * @param dstPtr
	 * @param length
	 */
	public void setBytes(byte[] src, int srcOfs, int dstPtr, int length) {
		if (srcOfs < 0) {
			throw new IndexOutOfBoundsException("srcOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (srcOfs + length > src.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(dstPtr, length);
		Address srcPtr = Unsafe.add(Unsafe.addressOf(src), (VmArray.DATA_OFFSET * slotSize) + srcOfs);
		Unsafe.copy(srcPtr, Unsafe.add(start, dstPtr), length);
	}

	/**
	 * Sets a char at a given memory address
	 * 
	 * @param memPtr
	 * @param value
	 */
	public void setChar(int memPtr, char value) {
		testMemPtr(memPtr, 2);
		Unsafe.setChar(start, memPtr, value);
	}

	/**
	 * Sets multiple 16-bit unsigned chars at the given memory address
	 * 
	 * @param src
	 * @param srcOfs
	 * @param dstPtr
	 * @param length
	 */
	public void setChars(char[] src, int srcOfs, int dstPtr, int length) {
		if (srcOfs < 0) {
			throw new IndexOutOfBoundsException("srcOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (srcOfs + length > src.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(dstPtr, length * 2);
		Address srcPtr = Unsafe.add(Unsafe.addressOf(src), (VmArray.DATA_OFFSET * slotSize) + (srcOfs * 2));
		Unsafe.copy(srcPtr, Unsafe.add(start, dstPtr), length * 2);
	}

	/**
	 * Sets a short at a given memory address
	 * 
	 * @param memPtr
	 * @param value
	 */
	public void setShort(int memPtr, short value) {
		testMemPtr(memPtr, 2);
		Unsafe.setShort(start, memPtr, value);
	}

	/**
	 * Sets multiple 16-bit signed shorts at the given memory address
	 * 
	 * @param src
	 * @param srcOfs
	 * @param dstPtr
	 * @param length
	 */
	public void setShorts(short[] src, int srcOfs, int dstPtr, int length) {
		if (srcOfs < 0) {
			throw new IndexOutOfBoundsException("srcOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (srcOfs + length > src.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(dstPtr, length * 2);
		Address srcPtr = Unsafe.add(Unsafe.addressOf(src), (VmArray.DATA_OFFSET * slotSize) + (srcOfs * 2));
		Unsafe.copy(srcPtr, Unsafe.add(start, dstPtr), length * 2);
	}

	/**
	 * Sets an int at a given memory address
	 * 
	 * @param memPtr
	 * @param value
	 */
	public void setInt(int memPtr, int value) {
		testMemPtr(memPtr, 4);
		Unsafe.setInt(start, memPtr, value);
	}

	/**
	 * Sets multiple 32-bit signed ints at the given memory address
	 * 
	 * @param src
	 * @param srcOfs
	 * @param dstPtr
	 * @param length
	 */
	public void setInts(int[] src, int srcOfs, int dstPtr, int length) {
		if (srcOfs < 0) {
			throw new IndexOutOfBoundsException("srcOfs < 0");
		}
		if (length < 0) {
			throw new IndexOutOfBoundsException("length < 0");
		}
		if (srcOfs + length > src.length) {
			throw new IndexOutOfBoundsException("dstOfs + length > dst.length");
		}
		testMemPtr(dstPtr, length * 4);
		Address srcPtr = Unsafe.add(Unsafe.addressOf(src), (VmArray.DATA_OFFSET * slotSize) + (srcOfs * 4));
		Unsafe.copy(srcPtr, Unsafe.add(start, dstPtr), length * 4);
	}

	/**
	 * Sets a float at a given memory address
	 * 
	 * @param memPtr
	 * @param value
	 */
	public void setFloat(int memPtr, float value) {
		testMemPtr(memPtr, 4);
		Unsafe.setFloat(start, memPtr, value);
	}

	/**
	 * Sets multiple 32-bit floats at the given memory address
	 * 
	 * @param src
	 * @param srcOfs
	 * @param dstPtr

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?