Lua5.3 GC源码阅读(1)

最近Lua 5.4 work1已经发布了, 其中GC最大的变化就是增加了分代GC的实现, 而GC在动态语言中一向是重中之重. 趁着这个机会, 我打算具体比较一下Lua5.3和Lua5.4中GC实现到底是如何变迁的, 根据以往的经验来看, 这其中必然充满各种精巧的设计.

Lua5.3的GC源码以前就断断续续看过一次了, 这次打算从头再分析一遍, 并做一下笔记为分析Lua5.4 GC做准备.

在Lua中字符串、表、用户数据、函数、线程、 内部结构等对象,都使用GC模块进行管理.

在分析GC流程前先做一些准备工作, 比如lua中的Value是如何实现的.

  //lobject.h

  /*
  ** Common type for all collectable objects
  */
  typedef struct GCObject GCObject;


  /*
  ** Common Header for all collectable objects (in macro form, to be
  ** included in other objects)
  */
  #define CommonHeader    GCObject *next; lu_byte tt; lu_byte marked


  /*
  ** Common type has only the common header
  */
  struct GCObject {
    CommonHeader;
  };

 /*
  ** Union of all Lua values
  */
  typedef union Value {
    GCObject *gc;    /* collectable objects */
    void *p;         /* light userdata */
    int b;           /* booleans */
    lua_CFunction f; /* light C functions */
    lua_Integer i;   /* integer numbers */
    lua_Number n;    /* float numbers */
  } Value;

  #define TValuefields    Value value_; int tt_

  typedef struct lua_TValue {
    TValuefields;
  } TValue;

在编写的lua代码中,全部是以TValue来表示的,而这个TValue到底是哪种类型是靠tt_字段来标识的.

tt_字段中的bits0-3用来表示基础类型可选值如下.

  //lua.h
  #define LUA_TNIL                0
  #define LUA_TBOOLEAN            1
  #define LUA_TLIGHTUSERDATA      2
  #define LUA_TNUMBER             3
  #define LUA_TSTRING             4
  #define LUA_TTABLE              5
  #define LUA_TFUNCTION           6
  #define LUA_TUSERDATA           7
  #define LUA_TTHREAD             8

一些基础类型中可能会有不同的变种,tt_字段的bits4-5用来表示每个基础类型中更具体的子类型, 在lobject.h中定义如下:

 /*
  ** LUA_TFUNCTION variants:
  ** 0 - Lua function
  ** 1 - light C function
  ** 2 - regular C function (closure)
  */

  /* Variant tags for functions */
  #define LUA_TLCL        (LUA_TFUNCTION | (0 << 4))  /* Lua closure */
  #define LUA_TLCF        (LUA_TFUNCTION | (1 << 4))  /* light C function */
  #define LUA_TCCL        (LUA_TFUNCTION | (2 << 4))  /* C closure */


  /* Variant tags for strings */
  #define LUA_TSHRSTR     (LUA_TSTRING | (0 << 4))  /* short strings */
  #define LUA_TLNGSTR     (LUA_TSTRING | (1 << 4))  /* long strings */


  /* Variant tags for numbers */
  #define LUA_TNUMFLT     (LUA_TNUMBER | (0 << 4))  /* float numbers */
  #define LUA_TNUMINT     (LUA_TNUMBER | (1 << 4))  /* integer numbers */

tt_字段的bit6中来表示此value是否可回收, 其中宏定义同样在lobject.h中定义

  /* Bit mark for collectable types */
  #define BIT_ISCOLLECTABLE       (1 << 6)

在lobject.h中提供了一组宏用于获取tt_字段中的各种含义

  #define val_(o)         ((o)->value_)

  /* raw type tag of a TValue */
  #define rttype(o)       ((o)->tt_)

  /* tag with no variants (bits 0-3) */
  #define novariant(x)    ((x) & 0x0F)

  /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
  #define ttype(o)        (rttype(o) & 0x3F)

  /* type tag of a TValue with no variants (bits 0-3) */
  #define ttnov(o)        (novariant(rttype(o)))

其中CommonHeader中的tt字段与TValue中的tt_字段的bits0-5是一致的.

《Lua5.3 GC源码阅读(1)》有1条评论

发表评论

× 3 = six