Internals. More...
#include "tm.h"
#include "internal.h"
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_block * | tm_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_type * | tm_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_type * | tm_size_to_type_2 (size_t size) |
Look for a type by size. | |
static __inline tm_type * | tm_type_new_2 (size_t size) |
Returns a new tm_type for a given size. | |
tm_adesc * | tm_adesc_for_size (tm_adesc *desc, int force_new) |
WHAT DOES THIS DO??? | |
static __inline tm_type * | tm_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. |
Internals.
Definition in file tm.c.
#define POW2 | ( | i | ) | if ( size <= (1UL << i) ) size = (1UL << i); else |
Referenced by tm_size_to_type().
__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 }
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 }
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 }
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 }
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 }
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 }