JSR-282 SI 15.1 ------------------------------------------------ Summary --------------------- Improve the physical memory classes. Specification References --------------------- Add the new interface PhysicalMemoryName. Modify PhysicalMemoryManager, RawMemoryAccess, and RawMemoryFloatAccess. Problem being Addressed --------------------- This SI aims to address the following problems: 1 ImmortalPhysicalMemory does not rule out being allocated in scoped memory. This needs to be impossible, or the rules for handling it need to be specified. 2 Is it clear enough that raw memory does not contain objects and other physical memory is not designed to be shared outside the JVM? 3 The requirement to permit linking to specific virtual addresses is not very useful and it can be nearly impossible (or just impossible) to implement. And all addresses involved in linking should probably be page-aligned. 4 The interaction between multiple physical memory filters needs to be better specified. 5 We need a way to support things like I/O space. 6 Try to give better compile time error checking for memory types than is afforded by giving the memory type the type of Object. Proposed Solution Summary --------------------- 1.) If immortal physical memory is allocated in scoped memory, or it is allocated in heap and freed by GC, the backing physical memory is not freed. The objects in it remain accessible, but no further allocation is possible in that block of physical memory. That's enough. 2.) Yes. It says (modified in each appropriate class): "No provision is made for sharing object in ImmortalPhysicalMemory with entities outside the JVM that creates them, and, while the memory backing an instance of ImmortalPhysicalMemory could be shared by multiple JVMs, the class does not support such sharing." That's enough. 3.) First, deprecate the methods that permit linking physical memory at a specific virtual address. Second, copy the OutOfMemoryError exception doc from map(base) to map(base, size). Map/Unmap with no arguments is a harmless way to enable/disable use of a raw memory access class so it should remain un-deprecated. Deprecate getMappedAddress(), map(base), map(base, size) In map(base, size), add java.lang.OutOfMemoryError - Thrown if there is insufficient free virtual memory at the specified address. 4.) Now, all we say is: "If the required memory has more than one attribute, type may be an array of objects." Somewhere we need to add that the physical memory manager searches for free memory that the physical memory filters for each type accepts with its find() method. 5.) One option would be to add a full set of load/store methods to the memory type filter classes (that is, to a subclass of those classes, or an interface that those classes could optionally implement), but that would require the raw memory access objects to use methods in the filters to get at memory. That would generally be slower than adding factory methods to the raw memory access classes so they could generate instances that are optimized for the particular type of memory. 6.) Define an interface that tags the names used for physical memory types. Also, let those tags represent non-empty sets of physical memory types. That will keep the factory methods (see 5) from needing forms for multiple types. Semantics --------------------- PhysicalMemoryName -------------- New interface PhysicalMemoryName with no defined methods or fields. PhysicalMemoryManager -------------- Change the static Object fields: ALIGNED, BYTESWAP, DMA, IO_PAGE, and SHARED to references to PhysicalMemoryName. Add a new pre-defined name, DEVICE -- If access to memory mapped devices is supported by the implementation, specify DEVICE if physical memory is to be used to access a memory mapped device. Narrow the definition of IO_PAGE to IO_PAGE -- If access to a non-memory-mapped system I/O space is supported by the implementation specify IO_PAGE if I/O space should be used. New methods ------ --- static void registerFilter(PhysicalMemoryName name, PhysicalMemoryTypeFilter filter) Just like the existing registerFilter() method except that: 1.) The type of the name is PhysicalMemoryName instead of Object. 2.) The method does not throw DuplicateFilterException --- static void registerFilter(PhysicalMemoryName name, PhysicalMemoryName componentName, PhysicalMemoryTypeFilter filter) Register a new physical memory type name and possibly a new physical memory type filter with the physical memory manager. The new name represents the filters represented by componentName plus filter. ResourceLimitError - Thrown if the system is configured for a bounded number of filters and this filter exceeds the bound. java.lang.IllegalArgumentException - Thrown if the name and filter are not both in immortal memory, if either name, componentName, or filter is null, or if componentName is not registered with the physical memory manager. java.lang.SecurityException - Thrown if this operation is not permitted. --- static void registerFilter(PhysicalMemoryName name, PhysicalMemoryName componentName, PhysicalMemoryTypeFilter filterOne, PhysicalMemoryTypeFilter filterTwo) Register a new physical memory type name and possibly new physical memory type filters with the physical memory manager. The new name represents the filters represented by componentName plus filterOne and filterTwo. ResourceLimitError - Thrown if the system is configured for a bounded number of filters and this method would cause the system to exceed the bound. java.lang.IllegalArgumentException - Thrown if the name and filters are not in immortal memory, if name, componentName, filterOne or filterTwo is null, or if componentName is not registered with the physical memory manager. java.lang.SecurityException - Thrown if this operation is not permitted. --- static void registerFilter(PhysicalMemoryName name, PhysicalMemoryName componentName, PhysicalMemoryTypeFilter [] filters) Register a new physical memory type name and possibly new physical memory type filters with the physical memory manager. The new name represents the filters represented by componentName plus the PhysicalMemoryTypeFilters in filters. ResourceLimitError - Thrown if the system is configured for a bounded number of filters and this method would cause the system to exceed the bound. java.lang.IllegalArgumentException - Thrown if the name, and the entries in filters are not all in immortal memory, or if either name, componentName, the size of filters is zero, an entry in filters is null, or if componentName is not registered with the physical memory manager. java.lang.SecurityException - Thrown if this operation is not permitted. RawMemoryAccess -------------- Deprecate map(base) and map(base, size) New methods ------ New constructors that use PhysicalMemoryName instead of Object for the name parameter, factory methods to make name-specific raw memory access instances, and a method to register new sub-classes with the factory, and a method to let subclasses indicate whether they are suitable for a name. --- public RawMemoryAccess(PhysicalMemoryName type, long size) public RawMemoryAccess(java.lang.Object type, long base, long size) --- static public RawMemoryAccess createInstance(PhysicalMemoryName type, long size) static public RawMemoryAccess createInstance(PhysicalMemoryName type, long base, long size) These factory methods are analogous to the above constructors except that they may return an instance of a sub-class of RawMemoryAccess. --- static public void addAccessClass(PhysicalMemoryName type, RawMemoryAccess clazz) Make clazz known to the factory as the class that should be used to access type. Only at most one class per type is permitted (though one class may handle many types). An attempt to add another class will throw an illegal argument exception. RawMemoryFloatAccess -------------- Reflect the added methods from RawMemoryAccess. Discussion Points --------------------- The proposed factory method approach to permitting optimization of access to physical memory has two drawbacks: * Application subclasses of RawMemoryAccess don't seem useful unless the application sticks to the (old-form) raw memory access constructors. * Non-implementors can define new filter classes, but they will have to work harder to get raw memory access classes to make optimal use of them. * Maybe the raw memory access factory should be an instance method of something, not a static method. That would, however, mean defining another class just to be the factory. Compatibility Issues --------------------- Anyone who has defined a new physical memory filter will have to change the type of its "name" from whatever subclass of Object it is now (probably String) to something that implements the new tagging interface.