tm.c File Reference

Internals. More...

#include "tm.h"
#include "internal.h"
Include dependency graph for tm.c:

Go to the source code of this file.

Defines

#define tm_DEFAULT_ALLOC_COLOR   tm_ECRU
 Default allocated nodes to "not marked".
#define tm_SWEEP_ALLOC_COLOR   tm_GREY
 Default allocated node color during sweep.
#define POW2(i)   if ( size <= (1UL << i) ) size = (1UL << i); else

Functions

void tm_validate_lists ()
 Validate internal lists against bookkeeping stats.
static tm_block_tm_block_alloc_from_free_list (size_t size)
 Allocate a tm_block from the free list.
void _tm_phase_init (int p)
 Initialize the collection/allocation phase.
__inline void _tm_block_sweep_init ()
 Begin sweeping of tm_blocks.
static __inline void _tm_type_add_block (tm_type *t, tm_block *b)
 Add a tm_block to a tm_type.
static __inline void _tm_type_remove_block (tm_type *t, tm_block *b)
 Remove a tm_block from its tm_type.
static __inline void tm_block_init (tm_block *b)
 Initialize a new tm_block.
static __inline size_t tm_block_align_size (size_t size)
 Align size to a multiple of tm_block_SIZE.
static tm_block_tm_block_alloc (size_t size)
 Allocate a tm_block of a given size.
static tm_blocktm_block_scavenge (tm_type *t)
 Scavenges all tm_types for an unused tm_block.
static __inline void _tm_node_delete (tm_node *n, tm_block *b)
 Deletes a WHITE tm_node from a tm_block.
static int _tm_block_unparcel_nodes (tm_block *b)
 Unparcels the tm_nodes in a tm_block.
static __inline void _tm_block_reclaim (tm_block *b)
 Reclaim a live tm_block.
static __inline void _tm_block_free (tm_block *b)
 Frees a block either returning the block to the OS or keeping it on a free list.
static tm_block_tm_block_alloc_for_type (tm_type *t)
 Allocates a tm_block of tm_block_SIZE for a tm_type.
static __inline void _tm_node_init (tm_node *n, tm_block *b)
 Initialize a tm_node from a tm_block.
static __inline int _tm_node_parcel_some (tm_type *t, long left)
 Parcel some nodes for a tm_type from a tm_block already allocated from the OS.
static __inline int _tm_node_parcel_or_alloc (tm_type *t)
 Parcel some nodes from an existing tm_block, or allocate a new tm_block and try again.
__inline void tm_type_init (tm_type *t, size_t size)
 Initialize a new tm_type of a given size.
static __inline tm_typetm_type_new (size_t size)
 Returns a new tm_type for a given size.
static __inline int tm_size_hash (size_t size)
 Returns the tm.type_hash[] index for a size.
static __inline tm_typetm_size_to_type_2 (size_t size)
 Look for a type by size.
static __inline tm_typetm_type_new_2 (size_t size)
 Returns a new tm_type for a given size.
tm_adesctm_adesc_for_size (tm_adesc *desc, int force_new)
 WHAT DOES THIS DO???
static __inline tm_typetm_size_to_type (size_t size)
 Return a tm_type for a size.
static int _tm_block_sweep_maybe (tm_block *b)
 Maybe sweep a tm_block.
static int _tm_block_sweep_some ()
 Sweep some blocks.
static size_t _tm_node_unmark_some (long left)
 Unmark some tm_BLACK nodes.
static void _tm_node_unmark_all ()
 Unmark all tm_BLACK nodes.
static void _tm_gc_clear_stats ()
 Clear GC stats.
void _tm_gc_full_type_inner (tm_type *type)
 Force a full GC for a specific type.
void _tm_gc_full_inner ()
 Force a full GC sequence.
static __inline void * _tm_type_alloc_node_from_free_list (tm_type *t)
 Allocates a node from at tm_type's free list.
static __inline int _tm_type_memory_pressureQ (tm_type *t)
static __inline int _tm_type_memory_pressureQ_2 (tm_type *t)
void * _tm_alloc_type_inner (tm_type *t)
 Allocates a node of a given type.
void * _tm_alloc_inner (size_t size)
 Allocates a node of a particular size.
void * _tm_alloc_desc_inner (tm_adesc *desc)
 Allocates a node of a particular type.
void * _tm_realloc_inner (void *oldptr, size_t size)
 Reallocates a node to a particular size.
void _tm_free_inner (void *ptr)
 Manually returns a node back to its tm_type free list.
void __tm_clear_some_stack_words ()
 Clears some words on the stack to prevent some garabage.



static __inline void _tm_node_set_color (tm_node *n, tm_block *b, tm_type *t, tm_color c)
 Sets the color of a tm_node.
void tm_node_set_color (tm_node *n, tm_block *b, tm_color c)
 Set a tm_node color within a tm_block.
static __inline void _tm_node_sweep (tm_node *n, tm_block *b)
 Sweep an ECRU node to the free list.
static size_t _tm_node_sweep_some (int left)
 Sweep some tm_ECRU nodes of any type.
static size_t _tm_node_sweep_some_for_type (tm_type *t, int left)
 Sweep some nodes for a tm_type.
static void _tm_node_sweep_all ()
 Sweep all ECRU nodes back to free lists.

Variables

static const tm_color tm_phase_alloc []
struct tm_data tm
 Global allocator data.

Detailed Description

Internals.

Definition in file tm.c.


Define Documentation

#define POW2 (  )     if ( size <= (1UL << i) ) size = (1UL << i); else

Referenced by tm_size_to_type().


Function Documentation

__inline void _tm_block_sweep_init (  ) 

Begin sweeping of tm_blocks.

UNIMPLEMENTED!

Definition at line 417 of file tm.c.

References tm_data::bb, tm_type::blocks, tm_data::bt, tm, tm_list_next, and tm_data::types.

Referenced by _tm_block_free(), tm_block_init(), and tm_init().

00418 {
00419 #if 0
00420   tm.bt = tm_list_next(&tm.types);
00421   tm.bb = tm.bt != tm_list_next(tm.bt) ?
00422     tm_list_next(&tm.bt->blocks) :
00423     0;
00424 #endif
00425 }

Here is the caller graph for this function:

static __inline void _tm_node_set_color ( tm_node n,
tm_block b,
tm_type t,
tm_color  c 
) [static]

Sets the color of a tm_node.

Increment cumulative global stats.

Increment global color transitions.

Adjust global stats.

Adjust type stats.

Adjust block stats.

Set the tm_code color.

Definition at line 438 of file tm.c.

References tm_data::alloc_n, tm_block::n, tm_type::n, tm_data::n, tm_data::n_color_transitions, tm_data::parceling, tm, tm_assert_test, tm_BLACK, tm_list_set_color, tm_node_color, and tm_TOTAL.

Referenced by tm_node_set_color().

00439 {
00440   int nc = tm_node_color(n);
00441 
00442   tm_assert_test(b);
00443   tm_assert_test(t);
00444   tm_assert_test(c <= tm_BLACK);
00445 
00446   /*! Increment cumulative global stats. */
00447   ++ tm.alloc_n[c];
00448   ++ tm.alloc_n[tm_TOTAL];
00449 
00450   /*! Increment global color transitions. */
00451   if ( ! tm.parceling ) {
00452     tm_assert_test(c != nc);
00453     ++ tm.n_color_transitions[nc][c];
00454     ++ tm.n_color_transitions[nc][tm_TOTAL];
00455     ++ tm.n_color_transitions[tm_TOTAL][c];
00456     ++ tm.n_color_transitions[tm_TOTAL][tm_TOTAL];
00457   }
00458 
00459   /*! Adjust global stats. */
00460   ++ tm.n[c];
00461   tm_assert_test(tm.n[nc]);
00462   -- tm.n[nc];
00463 
00464   /*! Adjust type stats. */
00465   ++ t->n[c];
00466   tm_assert_test(t->n[nc]);
00467   -- t->n[nc];
00468 
00469   /*! Adjust block stats. */
00470   ++ b->n[c];
00471   tm_assert_test(b->n[nc]);
00472   -- b->n[nc];
00473 
00474   /*! Set the tm_code color. */
00475   tm_list_set_color(n, c);
00476 }

Here is the caller graph for this function:

static __inline void _tm_node_sweep ( tm_node n,
tm_block b 
) [static]

Sweep an ECRU node to the free list.

If its tm_block is unused, free the block also.

Make sure the node is unmarked and not in use.

Clear out the data portion of the tm_node.

Put the tm_node on its tm_type free (tm_WHITE) list.

Free the tm_node's tm_block if the tm_block completely unused.

Definition at line 1450 of file tm.c.

References _tm_block_free(), tm_type::size, tm_assert_test, tm_block_unused, tm_ECRU, tm_msg(), tm_node_color, tm_node_set_color(), tm_node_to_ptr(), tm_WHITE, and tm_block::type.

Referenced by _tm_node_sweep_some(), and _tm_node_sweep_some_for_type().

01451 {
01452   /*! Make sure the node is unmarked and not in use. */
01453   tm_assert_test(tm_node_color(n) == tm_ECRU);
01454   // _tm_block_validate(b);
01455 
01456   /*! Clear out the data portion of the tm_node. */
01457   memset(tm_node_to_ptr(n), 0, b->type->size);
01458 
01459   /*! Put the tm_node on its tm_type free (tm_WHITE) list. */
01460   tm_node_set_color(n, b, tm_WHITE);
01461 
01462 #if 0
01463   tm_msg("s n%p\n", n);
01464 #endif
01465 
01466   /*! Free the tm_node's tm_block if the tm_block completely unused. */
01467   if ( tm_block_unused(b) ) {
01468     _tm_block_free(b);
01469   }
01470 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void _tm_node_sweep_all (  )  [static]

Sweep all ECRU nodes back to free lists.

While there are tm_ECRU nodes,

Keep sweeping them.

Definition at line 1552 of file tm.c.

References _tm_node_sweep_some(), tm_data::n, tm, tm_ECRU, and tm_node_LOOP_INIT.

Referenced by _tm_gc_full_type_inner().

01553 {
01554   /*! While there are tm_ECRU nodes, */
01555   while ( tm.n[tm_ECRU] ) {
01556     /*! Keep sweeping them. */
01557     tm_node_LOOP_INIT(tm_ECRU);
01558     _tm_node_sweep_some(tm.n[tm_ECRU]);
01559   }
01560 }

Here is the call graph for this function:

Here is the caller graph for this function:

static size_t _tm_node_sweep_some ( int  left  )  [static]

Sweep some tm_ECRU nodes of any type.

Decrement global stats.

Return the global number of tm_ECRU nodes.

Definition at line 1477 of file tm.c.

References _tm_check_sweep_error(), _tm_node_sweep(), tm_data::n, tm, tm_assert_test, tm_b, tm_ECRU, tm_msg(), tm_node_color, tm_node_LOOP, tm_node_LOOP_BREAK, tm_node_LOOP_END, and tm_node_to_block().

Referenced by _tm_alloc_type_inner(), and _tm_node_sweep_all().

01478 {
01479   size_t count = 0, bytes = 0;
01480  
01481   if ( tm.n[tm_ECRU] ) {
01482     if ( _tm_check_sweep_error() )
01483       return 0;
01484 
01485     tm_node_LOOP(tm_ECRU);
01486     {
01487       tm_assert_test(tm_node_color(n) == tm_ECRU);
01488 
01489       _tm_node_sweep(n, tm_node_to_block(n));
01490 
01491       bytes += t->size;
01492       ++ count;
01493 
01494       if ( -- left <= 0 ) {
01495         tm_node_LOOP_BREAK(tm_ECRU);
01496       }
01497     }
01498     tm_node_LOOP_END(tm_ECRU);
01499   }
01500 
01501   /*! Decrement global stats. */
01502   tm.n[tm_b] -= bytes;
01503 
01504 #if 0
01505   if ( count ) 
01506     tm_msg("s c%lu b%lu l%lu\n", count, bytes, tm.n[tm_ECRU]);
01507 #endif
01508 
01509   /*! Return the global number of tm_ECRU nodes. */
01510   return tm.n[tm_ECRU];
01511 }

Here is the call graph for this function:

Here is the caller graph for this function:

static size_t _tm_node_sweep_some_for_type ( tm_type t,
int  left 
) [static]

Sweep some nodes for a tm_type.

Decrement global allocation stats.

Return the number of tm_ECRU nodes for the tm_type.

Definition at line 1518 of file tm.c.

References _tm_node_sweep(), tm_type::color_list, tm_type::n, tm_data::n, tm_type::size, tm, tm_b, tm_ECRU, tm_list_first(), tm_msg(), and tm_node_to_block().

Referenced by _tm_alloc_type_inner().

01519 {
01520   size_t count = 0, bytes = 0;
01521   tm_node *n;
01522 
01523   while ( t->n[tm_ECRU] ) {
01524     n = tm_list_first(&t->color_list[tm_ECRU]);
01525     _tm_node_sweep(n, tm_node_to_block(n));
01526     
01527     bytes += t->size;
01528     ++ count;
01529     
01530     if ( -- left <= 0 ) {
01531       break;
01532     }
01533   }
01534 
01535   /*! Decrement global allocation stats. */
01536   tm.n[tm_b] -= bytes;
01537 
01538 #if 0
01539   if ( count ) 
01540     tm_msg("s t%p c%lu b%lu l%lu\n", t, count, bytes, tm.n[tm_ECRU]);
01541 #endif
01542 
01543   /*! Return the number of tm_ECRU nodes for the tm_type. */
01544   return t->n[tm_ECRU];
01545 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on Mon Jan 25 06:33:12 2010 for TM(tredmill) by  doxygen 1.6.1