[llvm-commits] CVS: poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp PoolAllocator.h

John Criswell criswell at cs.uiuc.edu
Mon Nov 10 21:46:01 PST 2003


Changes in directory poolalloc/runtime/FreeListAllocator:

PoolAllocator.cpp updated: 1.4 -> 1.5
PoolAllocator.h updated: 1.2 -> 1.3

---
Log message:

Modified the slab structure so that it looks like this:
  Slab Header
  Array of Links pointing to the next data block
  Array of data blocks with 1-1 correspondence with Array of Links.
So, for example, Link[n] points to the data block that is after data block[n]
in this slab.
This had to be done to provide array support (where I need contiguous
data blocks).  Data blocks with headers are not contiguous data blocks. :(


---
Diffs of the changes:  (+66 -42)

Index: poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp
diff -u poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.4 poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.5
--- poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.4	Mon Nov 10 17:12:02 2003
+++ poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp	Mon Nov 10 21:45:37 2003
@@ -16,17 +16,10 @@
 #include "PageManager.h"
 #include <assert.h>
 #include <stdlib.h>
-#include <stdio.h>
 
 #undef assert
 #define assert(X)
 
-typedef union
-{
-  unsigned char * header;
-  unsigned char ** next;
-} NodePointer;
-
 //===----------------------------------------------------------------------===//
 //
 //  PoolSlab implementation
@@ -46,8 +39,11 @@
   // Pointer to the next slab
   struct SlabHeader * Next;
 
+  // Pointer to the data area (will be in the same page)
+  unsigned char * Data;
+
   // Pointer to the list of nodes
-  unsigned char Data [];
+  NodePointer BlockList [];
 };
 
 //
@@ -64,6 +60,7 @@
 
   // Pointers and index for initializing memory
   NodePointer p;
+  unsigned int index;
 
   //
   // Determine how many nodes should exist within a slab.
@@ -94,34 +91,48 @@
   NewSlab->NodesPerSlab = NodesPerSlab;
   NewSlab->LiveNodes = 0;
   NewSlab->Next = NULL;
+  NewSlab->Data = (unsigned char *)NewSlab + sizeof (struct SlabHeader) + ((NodesPerSlab) * sizeof (NodePointer));
 
   //
   // Initialize each node in the list.
   //
-  p.header = &(NewSlab->Data[0]);
-  while (p.header < (&(NewSlab->Data[0]) + slab_size - sizeof (struct SlabHeader)))
+  for (index = 0; index < NodesPerSlab - 1; index++)
   {
-    //
-    // Calculate the position of the next header and put its address in
-    // this current header.
-    //
-    *(p.next) = p.header + (sizeof (unsigned char *) + NodeSize);
-
-    //
-    // Move on to the next header.
-    //
-    p.header = *(p.next);
+    NewSlab->BlockList[index].Next = &(NewSlab->BlockList[index + 1]);
   }
-
-  p.header = (&(NewSlab->Data[0]) + slab_size - sizeof (struct SlabHeader)
-                                     - sizeof (unsigned char *)
-                                     - NodeSize);
-  *(p.next) = NULL;
+  NewSlab->BlockList[NodesPerSlab - 1].Next = NULL;
 
   return NewSlab;
 }
 
 //
+// Function: BlockOwner ()
+//
+// Description:
+//  Find the slab that owns this block.
+//
+struct SlabHeader *
+BlockOwner (NodePointer p)
+{
+  //
+  // Convert the node pointer into a slab pointer.
+  //
+  return reinterpret_cast<struct SlabHeader *>(reinterpret_cast<unsigned int>(p.Next) & ~(PageSize - 1));
+}
+
+//
+// Function: DataOwner ()
+//
+// Description:
+//  This function finds the slab that owns this data block.
+//
+struct SlabHeader *
+DataOwner (void * p)
+{
+  return reinterpret_cast<struct SlabHeader *>(reinterpret_cast<unsigned int>(p) & ~(PageSize - 1));
+}
+
+//
 // Function: slabAlloc()
 //
 // Description:
@@ -162,7 +173,7 @@
   // We must alway return unique pointers, even if they asked for 0 bytes
   Pool->NodeSize = NodeSize ? NodeSize : 1;
   Pool->Slabs = NULL;
-  Pool->FreeList = NULL;
+  Pool->FreeList.Next = NULL;
   Pool->FreeablePool = 1;
 
   //
@@ -173,7 +184,8 @@
   return;
 }
 
-void poolmakeunfreeable(PoolTy *Pool)
+void
+poolmakeunfreeable(PoolTy *Pool)
 {
   assert(Pool && "Null pool pointer passed in to poolmakeunfreeable!\n");
   Pool->FreeablePool = 0;
@@ -181,7 +193,8 @@
 
 // pooldestroy - Release all memory allocated for a pool
 //
-void pooldestroy(PoolTy *Pool)
+void
+pooldestroy(PoolTy *Pool)
 {
   // Pointer to scan Slab list
   struct SlabHeader * Slabp;
@@ -203,7 +216,7 @@
   //
   // If there isn't an available block, we need a new slab.
   //
-  if (Pool->FreeList == NULL)
+  if (Pool->FreeList.Next == NULL)
   {
     //
     // Create a new slab and add it to the list.
@@ -223,7 +236,7 @@
     // Take the linked list of nodes inside the slab and add them to the
     // free list.
     //
-    Pool->FreeList = &(Pool->Slabs->Data[0]);
+    Pool->FreeList.Next = &(NewSlab->BlockList[0]);
   }
 
   //
@@ -234,13 +247,21 @@
 #endif /* 0 */
 
   //
-  // Grab the first element from the free list and return it.
+  // Determine which slab owns this block.
   //
-  NodePointer MemoryBlock;
+  struct SlabHeader * slabp = BlockOwner (Pool->FreeList);
 
-  MemoryBlock.header = Pool->FreeList;
-  Pool->FreeList=*(MemoryBlock.next);
-  return (MemoryBlock.header += sizeof (unsigned char *));
+  //
+  // Find the data block that corresponds with this pointer.
+  //
+  void * Data = (slabp->Data + (Pool->NodeSize * (Pool->FreeList.Next - &(slabp->BlockList[0]))));
+
+  //
+  // Unlink the first block.
+  //
+  Pool->FreeList.Next = Pool->FreeList.Next->Next;
+
+  return Data;
 }
 
 //
@@ -288,13 +309,12 @@
   assert(Pool && "Null pool pointer passed in to poolfree!\n");
   assert(Block && "Null pool pointer passed in to poolfree!\n");
 
-  // Pointer to the node corresponding to this memory block
-  NodePointer Node;
-
   //
   // Find the header of the memory block.
   //
-  Node.header = (unsigned char *)(Block) - (sizeof (unsigned char *));
+  struct SlabHeader * slabp = DataOwner (Block);
+  NodePointer Node;
+  Node.Next = &(slabp->BlockList[((unsigned char *)Block - slabp->Data)/Pool->NodeSize]);
 
 #if 0
   //
@@ -306,8 +326,8 @@
   //
   // Add the node back to the free list.
   //
-  *(Node.next) = Pool->FreeList;
-  Pool->FreeList = Node.header;
+  Node.Next->Next = Pool->FreeList.Next;
+  Pool->FreeList.Next = Node.Next;
 
   return;
 }


Index: poolalloc/runtime/FreeListAllocator/PoolAllocator.h
diff -u poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.2 poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.3
--- poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.2	Mon Nov 10 15:57:48 2003
+++ poolalloc/runtime/FreeListAllocator/PoolAllocator.h	Mon Nov 10 21:45:37 2003
@@ -16,6 +16,10 @@
 #define POOLALLOCATOR_RUNTIME_H
 
 struct SlabHeader;
+typedef struct NodePointer
+{
+  struct NodePointer * Next;
+} NodePointer;
 
 typedef struct PoolTy {
   // NodeSize - Keep track of the object size tracked by this pool
@@ -25,7 +29,7 @@
   struct SlabHeader * Slabs;
 
   // Pointer to the free list of nodes
-  unsigned char * FreeList;
+  struct NodePointer FreeList;
 
   // FreeablePool - Set to false if the memory from this pool cannot be freed
   // before destroy.





More information about the llvm-commits mailing list