vm$ mkdir gc_copying +build descriptor on the Windows/IA-32 architecture. +
Index: gc-howto.html =================================================================== --- gc-howto.html (revision 454321) +++ gc-howto.html (working copy) @@ -36,7 +36,7 @@ -
+ + How to Write DRL GC ++ | |||||||||||||||||
|
-
-
-
-
-
-
-
-
-
-How to write DRL GC-version 1.0, -2006-07-20 -
-
-
-
-This document provides instructions on creating a custom garbage collector implementation -in C++ and configuring the DRL virtual machine to use it. The document describes -the major steps of this procedure, namely: -
Note
-Plugging-in a user-designed garbage collector presupposes an operating DRL -virtual machine built according to the instructions of the README.txt file -supplied with the VM source package. -1. Establishing the build infrastructure-
+
+ | + Contents ++
+
+
+
+ |
+ | + 1. About This Document ++This document provides instructions on creating a custom garbage + collector implementation (GC, version 1.0, 2006-07-20) in C++ and + configuring the DRL virtual machine to use it. The document + describes the major steps of this procedure, namely: establishing + the build infrastructure, implementing the GC interface, implementing + the GC algorithm, and running the VM with the custom GC. +Note +Plugging-in a user-designed garbage collector presupposes
+an operating DRL virtual machine built according to the instructions of the
+
+ | + 2. Establishing the Build Infrastructure ++ +At this stage, you create the directory and set up the build infrastructure to build the dynamic library. At the end of this stage, you will be fully set for adding the garbage collector code and building it. DRLVM can load a custom garbage collector from a dynamic library. It is recommended that you build your dynamic library using a DRLVM build infrastructure. Below is an example of creating of a -build descriptor on the Windows* / IA-32 architecture. -1.1. Create a directory for a new GC module, for example:-
-
- vm$ mkdir gc_copying +build descriptor on the Windows/IA-32 architecture. +
+ | + 2.1 Creating a Directory for a New GC Module ++The example below shows how to create a directory for a new GC module: +vm$ mkdir gc_copying vm$ mkdir gc_copying/src -vm$ cd gc_copying/src- - That is where you will put the source code, see Section 3, -Implementing the garbage collector algorithm. -1.2. Create a build descriptor file-Create the build descriptor file build/make/components/vm/gc_copying.xml +vm$ cd gc_copying/src + + In the newly created directory you will store the source code. For more information, refer to the +Implementing the GC Algorithm section. +
+ | + 2.2 Creating a Build Descriptor File ++ +Create the build descriptor file
-
+</project>
+
- <project name="vm.gc_copying">
+
+
-You can add other macro definitions, include directories or compiler-specific command-line options to match your needs. -1.3. Create a C++ file with essential includes, namely:-
-
- #include "open/gc.h" +
+ | + + 2.3 Creating a C++ file with essential include files ++Create a C++ file with essential include files, namely: + +#include "open/gc.h" #include "open/vm_gc.h" #include "open/vm.h" #define LOG_DOMAIN "gc" -#include "cxxlog.h"- - These include files are located in directories vm/include/open and -vm/port/include. Consult their content for documentation and details of the +#include "cxxlog.h" + + These include files are located in directories 1.4. Test the configuration+
+ | + 2.4 Testing the Configuration ++Run the build system to test whether the infrastructure is set up correctly: -
-
-
- build$ build.bat -DCOMPONENTS=vm.gc_copying- On a successful build, the .dll file is placed to the VM build directory -build/win_ia32_icl_debug/deploy/jre/bin/. The name of the directory may differ -depending on your system and the compiler used. This empty library will not -work, you have to write your GC first! - -2. Implementing the GC interface-
+
+ build$ build.bat -DCOMPONENTS=vm.gc_copying+ + On a successful build, the Note +This empty library will not +work, you have to write your GC first. +
+ | + 3. Implementing the GC interface ++This section lists the functions that a garbage collector interface must -implement. Declarations of these functions are in gc.h. For details, consult -the Developer's Guide and documentation in gc.h and vm_gc.h. -2.1. GC lifecycle+implement. Declarations of these functions are ingc.h. For details, consult
+the Developer's Guide and documentation in gc.h and vm_gc.h.
+
+ | + 3.1 GC Lifecycle ++
2.2. Object allocation+
+ | + 3.2. Object allocation ++
See the Root set enumeration section in the Developer's Guide for details. -2.3. Miscellaneous+See the +Root Set Enumeration section in the +Developer's Guide for details. +
+ | + 3.3. Miscellaneous +
2.4. Optional+
+ | + 3.4. Optional ++The virtual machine can operate without the functions listed below, but certain features will be unavailable.
2.5. The VM_GC interface+
+ |
+ 3.5. The
+
| |||
+ + 4. Implementing the GC Algorithm ++This section gives step-by-step instructions on how to implement the garbage collection algorithm. The example shows a semispace copying collector. -Note
-This example does not implement object finalization and weak references. -3.1. Algorithm Overview+Note +This example does not implement object finalization and weak references. + | |||||||||||||||||
+ + 4.1. Algorithm Overview ++The heap is divided into two equally sized contiguous semispaces. -During normal operation, only one semispace is used (current semispace), -and the other one is reserved for garbage collection. +During normal operation, only one semispace is used (current semispace), +and the other one is reserved for garbage collection. Allocation requests are satisfied by contiguous allocation from the current semispace. Each application thread reserves a thread-local -allocation buffer (TLAB) under a global lock, and serves most of the allocation +allocation buffer (TLAB) under a global lock, and serves most of the allocation requests without locking, by incrementing the allocation pointer local to the buffer. When the application requests an allocation that does not fit into the remaining free space of the current semispace, a garbage collection is initiated. The current -semispace becomes the evacuation space (fromspace), and the reserved semispace -becomes the destination space (tospace). The VM suspends all application threads and +semispace becomes the evacuation space (fromspace), and the reserved semispace +becomes the destination space (tospace). The VM suspends all application threads and enumerates root references. The GC copies the objects reachable from root references to the destination space. When an object is copied from evacuation space to destination space, the GC installs @@ -827,32 +595,30 @@ evacuated to the destination space, and the evacuation space can be safely reclaimed. The GC then changes the semispace roles: it uses the destination space for further allocation and reserves the evacuation space for the next garbage collection. The change of -the semispace roles is commonly referred to as flip. +the semispace roles is commonly referred to as flip.After the semispace flip, the GC resumes user threads. Please refer to the excellent survey for detailed description of this algorithm and other basic garbage collection techniques, "Uniprocessor Garbage Collection Techniques", Paul R. Wilson. 3.2. Source code explained-The full source code of the collector is available in gc_copying.cpp. -The structure TLS (thread-local storage) + The full source code of the collector is available in The structure
-
+};
+
- // This structure is allocated for each user thread.
+
+
-Define the main GC structure to contain the Java heap and the data necessary for GC operation, as shown below. -
-
+};
+
- // Encapsulates all GC data.
+
+
-The following structure stores object information: the object field layout and the object size. -
-
-
- // Structure OI (from "object information")
+
+
-The data stored in the OI structure is initialized and accessed by the GC only. +}; + +The data stored in the The following structures convey the static assumptions that GC makes about object layout. The VM must use the same object layout assumptions for the correct GC operation. -The VTable structure contains the virtual table of the object methods, + The
-
-
- // The VTable structure has 4 bytes reserved +to the object information structure- The GC assumes that each Java* object has a fixed header: (1) a pointer -to the VTable structure, and then a (2) 32 bit word with flags. +}; + + The GC assumes that each Java object has a fixed header: (1) a pointer
+to the
-
+};
+
- // Describes the object header format assumed by GC.
+
+
-The array objects have the same header, and a 4 byte length field at the offset 8. -
-
-
- // Describes the array header format assumed by GC.
+
+
-Note
-The layout described is valid for the IA-32 platform only. +}; +Note +The layout described is valid for the IA-32 platform only. A number of convenience functions use object layout knowledge to perform
-various data manipulations. The function init_vt() writes the VTable pointer
+various data manipulations. The function
-
-
- void init_vt(Managed_Object_Handle p, Allocation_Handle ah) {
+
+
-The function obj_oi() retrieves object information structure +} + + The function
-
-
- OI* obj_oi(Managed_Object_Handle p) {
+
+
-The function array_length() retrieves the length of an array +} + + The function
-
-
- int array_length(Managed_Object_Handle p) {
+
+
-The function vt_oi() retrieves the OI structure pointer +} + + The function
-
-
- OI* vt_oi(VTable_Handle p) {
+
+
-The function ah_oi() retrieves the OI structure pointer -using Allocation_Handle. On 32-bit architectures, the +} + + The function
-
-
- OI* ah_oi(Allocation_Handle ah) {
+
+
-The object_size() function computes the size of an object. Array size is +} + + The
-
+}
+
- int object_size (Managed_Object_Handle obj) {
+
+
-In this example, the garbage collector is created statically as a global instance of structure GC: -
-
-
- GC gc;- The function init() statically configures size parameters. Normally, this -function uses the function vm_get_property() to read configuration options + + GC gc;+ + The function
-
-
- void GC::init() {
+
+
-As the next step, the init() function allocates space for the heap, divides it + chunk_size = 64*1024; + + As the next step, the
-
+}
+
- space = (byte*) malloc(semisize*2);
+
+
-The global allocation function uses a lock to protect the heap from simultaneous access from multiple threads. The locking mechanism -is trivially implemented in a platform-dependent way. See the full source code in gc_copying.cpp. -
-
+}
+
- byte* GC::galloc(unsigned size) {
+is trivially implemented in a platform-dependent way. See the full source code in
-The local allocation function uses the thread-local allocation area for object
-allocation, and uses galloc() to allocate a new chunk for a thread-local
+allocation, and uses
-
+}
+
- byte* GC::alloc(unsigned size, TLS* tls) {
+
-The forwarding pointers are installed in the lockword structure, the second word of an object. -
-
-
- byte* GC::forwarded (void* obj) {
+
+
-The function move() copies the object data to the evacuation semispace and +} + + The function
-
-
- byte* GC::move (void* obj) {
+
+
-The function root() handles one root during root set enumeration. If the root +} + + The function
-
-
- void GC::root(void** root) {
+
+
-The function trace() scans one object. -
-
-
- void GC::trace (byte* obj) {
+}
+
+The function void GC::trace (byte* obj) {
OI* oi = obj_oi(obj);
TRACE2("gc.trace", "trace " << (void*)obj
<< " (" << (void*)object_size(obj) << ", " << oi->name << ")");
@@ -1206,22 +953,22 @@
*field = nobj;
}
}
-}
-The function collect_alloc() is the main function controlling garbage +} + + The function Note
-The thread is starving when it gets no resources for a long time + Note ++The thread is starving when it gets no resources for a long time because other threads grab the resource before it can even try. If the garbage collector resumes user threads before retrying the allocation, these threads may use all available space quickly before the allocation succeeds. In this case, the allocation will fail for an indefinite number of times. -
-
- byte* GC::collect_alloc(unsigned size, TLS* tls) {
+
+}
The exported GC interface is mostly implemented by delegating the task to the -method of the structure GC. The GC initialization function init() is called -from gc_init(). +method of the structureGC. The GC initialization function init() is called
+from gc_init().
- void gc_init() {
+
+}
Thread local allocation areas are reset on thread creation and thread termination events.
- void gc_thread_init(void* tp) {
+
-The slow path allocation function gc_alloc() checks whether the allocation space is +} + + The slow path allocation function
-
+}
+
- Managed_Object_Handle gc_alloc (unsigned size, Allocation_Handle ah, void *tp) {
+
+
-If the memory is exhausted, the no-collection allocation function -gc_alloc_fast() returns NULL, and does not start garbage collection. -
-
-
- Managed_Object_Handle gc_alloc_fast (unsigned size, Allocation_Handle ah, void *tp) {
+
-The root set enumeration function passes the root reference to the root() +} + + The root set enumeration function passes the root reference to the
-
-
- void gc_add_root_set_entry(Managed_Object_Handle *ref, Boolean is_pinned) {
+
+
-The function build_slot_offset_array() is used to construct a NULL-terminated +} + + The function
-
-
- static int *build_slot_offset_array(Class_Handle ch)
+
+
-The GC caches object layout information when the function gc_class_prepared() +} + + The GC caches object layout information when the function
-
-
- void gc_class_prepared (Class_Handle ch, VTable_Handle vth) {
+
+
-The function gc_force_gc() starts a forced garbage collection using the global +} + + The function
-
+}
+
- void gc_force_gc () {
+
+
-Other functions of the GC interface are empty or trivial, and not described in -this document. You can see the full listing in the gc_copying.cpp file. +this document. You can see the full listing in thegc_copying.cpp file.
After you completed coding the garbage collector, you can build a GC dynamic library, as described above, by typing -
-
-
-
- build$ build.bat -DCOMPONENTS=vm.gc_copying- 4. Running VM with the custom GC-
+
+ build$ build.bat -DCOMPONENTS=vm.gc_copying+ + | |||||||||||||||||
+ + 5. Running the VM with the Custom GC ++This section describes how to run the DRL virtual machine with the custom garbage collector library. You can specify the name of the dynamic library on the command line. For -example, to load a GC gc_copying.dll, execute the following: -
-
-
- ij -Dvm.dlls=gc_copying Hello- The virtual machine searches for a dynamic library gc_copying.dll in the
+example, to load a GC ij -Dvm.dlls=gc_copying Hello+ + The virtual machine searches for a dynamic library |
+executable