随笔 - 119  文章 - 290  trackbacks - 0

博客搬家了哦,请移步
叫我abc

常用链接

留言簿(12)

随笔分类

我的博客

搜索

  •  

积分与排名

  • 积分 - 302262
  • 排名 - 84

最新评论

阅读排行榜

昨天看完了cache_flush,有关gc_malloc的内容,就到此为止了。接下来,就是补看这一路上暂时略过的一些函数,顺便引出对malloc出来但是没有建立依赖关系的内存是如何管理的。
其实这一路过来,就忽略了两个函数:map_idstack_push。有关map_id的作用已经说过,仍打算继续忽略下去。至于stack_push分别出现在了gc_mallocgc_link中,在gc_link中作为解除内存依赖关系的一个步骤,可以以后再看,而在gc_malloc中,是在没有提供parent参数的时候的一个执行分支,也就是新分配的内存没有建立依赖关系而进行的另外一种管理,这种管理使得内存可以被gc_collect回收。

如果要看stack_push,就必须先看gc_entergc_leave,根据提供的说明,这两个函数对必须在应用程序的每个函数的开始和结束调用,也可以只是简单的放置在main loop中,而不必填充到每一个函数里。光介绍概念还是太抽象,直接看代码来得实惠。
1void
2gc_enter()
3{
4    stack_expand();
5    E.stack.data[E.stack.top].number=E.stack.top-E.stack.current;
6    E.stack.current=E.stack.top++;
7}
忘了说,这一块内容,其本质都是对stack进行操作,所以第4行,首先拓展stack的尺寸。stack_expand里面包含一个拓展策略,因为我看不懂,就不介绍了,总之,其结果就是保证了stack总是有足够的空间而很少越界。

第5、6行,看起来还是要配上云风画的图可能更容易理解
/*    stack data
   +----------+
 0 | level 0  |                ----> level 0 / root ( node pack )
 1 | level 1  |                --+-> level 1 ( 1 node ref + node pack )
 2 | node ref | <-bottom       --+
 3 | 2 (lv.2) |
 4 | node ref |                --+-> level 2 ( 3 node ref )
 5 | node ref |                  |
 6 | node ref |                --+
 7 | 4 (lv.3) | <-current
 8 | node ref |                --+-> level 3 ( 2 node ref )
 9 | node ref |                --+
 10|   nil    | <-top
 11|   nil    |
   +----------+
 */
在top和current之间,保存的是在父函数中分配而没有建立依赖关系的内存的id。所以第5行,就是把父函数中分配的自由内存的数量压入堆栈。第6行则让current指向这个位置。
结论也就是,相对当前的函数而言:
1.current指向的数据是爷爷函数中分配的自由内存的数量
2.top和current之间保存的是父函数中分配的自由内存的id
通过调用gc_enter,堆栈调整为:current指向的数据保存着父函数中分配的自由内存的数量,而现在top和current之间空无一物,用于存储当前函数将要分配的自由内存id。

下面看看stack_push的代码
1static void
2stack_push(int handle)
3{
4    stack_expand();
5    E.stack.data[E.stack.top++].handle=handle;
6}
参数handle就是新分配的内存的id。代码就2行,首先是拓展stack,然后就是把内存id压入堆栈,放在top和current之间。这也就解释了上面的那个堆栈的布局结构如何而来。

最后,贴一下stack的定义。因为前两个函数都有些简单,以至于忘记看数据结构的定义了
union stack_node {
    
int stack;
    
int number;
    
int handle;
}
;

struct stack {
    union stack_node 
*data;
    
int top;
    
int bottom;
    
int current;
}
;
stack即堆栈,内部用一个数组实现,即成员变量data。数组元素为stack_node。
由stack_node的定义可知,堆栈的一个元素可能表示3种用途:
1.stack,不知道
2.number,存储父函数,爷爷函数等等的函数中分配自由内存的数量
3.handle,存储某个函数分配出来的自由内存的id

that is today
posted on 2008-09-17 21:02 LOGOS 阅读(1540) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理