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

John Criswell criswell at cs.uiuc.edu
Tue Nov 11 10:01:03 PST 2003


Changes in directory poolalloc/runtime/FreeListAllocator:

PoolSlab.h added (r1.1)
PoolAllocator.cpp updated: 1.7 -> 1.8
PoolAllocator.h updated: 1.3 -> 1.4

---
Log message:

Moved Slab structure definitions to PoolSlab.h.
Added code to re-use arrays.



---
Diffs of the changes:  (+123 -33)

Index: poolalloc/runtime/FreeListAllocator/PoolSlab.h
diff -c /dev/null poolalloc/runtime/FreeListAllocator/PoolSlab.h:1.1
*** /dev/null	Tue Nov 11 10:00:06 2003
--- poolalloc/runtime/FreeListAllocator/PoolSlab.h	Tue Nov 11 09:59:55 2003
***************
*** 0 ****
--- 1,79 ----
+ //===- Slab.h - Implementation of poolallocator runtime -------------------===//
+ // 
+ //                       The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // This header file defines structures used internally by the free list pool
+ // allocator library.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef _POOLSLAB_H
+ #define _POOLSLAB_H
+ 
+ #include "PoolAllocator.h"
+ #include "PageManager.h"
+ #include <assert.h>
+ #include <stdlib.h>
+ 
+ #undef assert
+ #define assert(X)
+ 
+ //===----------------------------------------------------------------------===//
+ //
+ //  Defintion of Slab Data Structures
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ //
+ // Provide a pointer type that points to pointers of itself.
+ //
+ typedef struct NodePointer
+ {
+   struct NodePointer * Next;
+ } NodePointer;
+ 
+ //
+ // Structure: SlabHeader
+ //
+ // Description:
+ //  This structure defines the beginning of a memory slab.  A memory slab
+ //  consists of book keeping information, a list of pointers, and a list of
+ //  data blocks.
+ //
+ //  There is a 1 to 1 correspondence between the pointers and the data blocks.
+ //  Pointer[x] points to Pointer[y] if Data[y] is linked after Data[x] in a
+ //  linked list.  In other words, Pointer[x] is the "next" pointer for Data[x].
+ //
+ //  The slab is allocated on a page boundary, so it is easy to find match
+ //  pointers to blocks if you know the offset of one of them.
+ //
+ struct SlabHeader
+ {
+   // Flags whether this is an array
+   unsigned int IsArray;
+ 
+   // Number of nodes per slab
+   unsigned int NodesPerSlab;
+ 
+   // Reference Count
+   unsigned int LiveNodes;
+ 
+   // Next free data block
+   unsigned int NextFreeData;
+ 
+   // 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
+   NodePointer BlockList [];
+ };
+ 
+ #endif /* _POOLSLAB_H */


Index: poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp
diff -u poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.7 poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.8
--- poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp:1.7	Mon Nov 10 23:46:11 2003
+++ poolalloc/runtime/FreeListAllocator/PoolAllocator.cpp	Tue Nov 11 09:59:55 2003
@@ -14,6 +14,7 @@
 
 #include "PoolAllocator.h"
 #include "PageManager.h"
+#include "PoolSlab.h"
 #include <assert.h>
 #include <stdlib.h>
 
@@ -25,29 +26,6 @@
 //  PoolSlab implementation
 //
 //===----------------------------------------------------------------------===//
-struct SlabHeader
-{
-  // Flags whether this is an array
-  unsigned int IsArray;
-
-  // Number of nodes per slab
-  unsigned int NodesPerSlab;
-
-  // Reference Count
-  unsigned int LiveNodes;
-
-  // Next free data block
-  unsigned int NextFreeData;
-
-  // 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
-  NodePointer BlockList [];
-};
 
 //
 // Function: createSlab ()
@@ -166,7 +144,7 @@
 
   // We must alway return unique pointers, even if they asked for 0 bytes
   Pool->NodeSize = NodeSize ? NodeSize : 1;
-  Pool->Slabs = NULL;
+  Pool->Slabs = Pool->ArraySlabs = NULL;
   Pool->FreeList.Next = NULL;
   Pool->FreeablePool = 1;
 
@@ -289,6 +267,37 @@
   assert(Pool && "Null pool pointer passed into poolallocarray!\n");
 
   //
+  // Scan the list of array slabs to see if there is one that fits.
+  //
+  struct SlabHeader * Slabp = Pool->ArraySlabs;
+  struct SlabHeader * Prevp = NULL;
+
+  for (; Slabp != NULL; Prevp = Slabp, Slabp=Slabp->Next)
+  {
+    //
+    // Check to see if this slab has enough room.
+    //
+    if (Slabp->NodesPerSlab >= ArraySize)
+    {
+      if (Prevp == NULL)
+      {
+        //
+        // This is the first item.  Change the head of the list.
+        //
+        Pool->ArraySlabs = Slabp->Next;
+      }
+      else
+      {
+        //
+        // This is some other item.  Modify the preceding item.
+        //
+        Prevp->Next = Slabp->Next;
+      }
+      return (&(Slabp->Data[0]));
+    }
+  }
+
+  //
   // Create a new slab and mark it as an array.
   //
   struct SlabHeader * NewSlab = createSlab (Pool->NodeSize, ArraySize);
@@ -304,7 +313,7 @@
 poolfree (PoolTy * Pool, void * Block)
 {
   assert(Pool && "Null pool pointer passed in to poolfree!\n");
-  assert(Block && "Null pool pointer passed in to poolfree!\n");
+  assert(Block && "Null block pointer passed in to poolfree!\n");
 
   //
   // Find the header of the memory block.
@@ -312,15 +321,18 @@
   struct SlabHeader * slabp = DataOwner (Block);
 
   //
-  // If the owner is an array, just nuke the whole thing for now.
-  // FIXME: Inefficient!  Danger Will Robinson!
+  // If the owning slab is an array, add it back to the free array list.
   //
   if (slabp->IsArray)
   {
-    FreePage (slabp);
+    slabp->Next = Pool->ArraySlabs;
+    Pool->ArraySlabs = slabp;
     return;
   }
 
+  //
+  // Find the node pointer that corresponds to this data block.
+  //
   NodePointer Node;
   Node.Next = &(slabp->BlockList[((unsigned char *)Block - slabp->Data)/Pool->NodeSize]);
 


Index: poolalloc/runtime/FreeListAllocator/PoolAllocator.h
diff -u poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.3 poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.4
--- poolalloc/runtime/FreeListAllocator/PoolAllocator.h:1.3	Mon Nov 10 21:45:37 2003
+++ poolalloc/runtime/FreeListAllocator/PoolAllocator.h	Tue Nov 11 09:59:55 2003
@@ -15,11 +15,7 @@
 #ifndef POOLALLOCATOR_RUNTIME_H
 #define POOLALLOCATOR_RUNTIME_H
 
-struct SlabHeader;
-typedef struct NodePointer
-{
-  struct NodePointer * Next;
-} NodePointer;
+#include "PoolSlab.h"
 
 typedef struct PoolTy {
   // NodeSize - Keep track of the object size tracked by this pool
@@ -27,6 +23,9 @@
 
   // Pointer to the list of slabs allocated for this pool
   struct SlabHeader * Slabs;
+
+  // List of slabs used to hold arrays
+  struct SlabHeader * ArraySlabs;
 
   // Pointer to the free list of nodes
   struct NodePointer FreeList;





More information about the llvm-commits mailing list