惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
IT之家
IT之家
F
Full Disclosure
B
Blog RSS Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
B
Blog
H
Help Net Security
The Cloudflare Blog
Recorded Future
Recorded Future
P
Proofpoint News Feed
P
Proofpoint News Feed
C
Cisco Blogs
T
Tailwind CSS Blog
P
Palo Alto Networks Blog
D
Docker
爱范儿
爱范儿
Know Your Adversary
Know Your Adversary
博客园 - 聂微东
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Y
Y Combinator Blog
雷峰网
雷峰网
AWS News Blog
AWS News Blog
D
DataBreaches.Net
博客园 - 司徒正美
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - Franky
C
Cybersecurity and Infrastructure Security Agency CISA
Blog — PlanetScale
Blog — PlanetScale
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
C
CERT Recently Published Vulnerability Notes
阮一峰的网络日志
阮一峰的网络日志
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
CXSECURITY Database RSS Feed - CXSecurity.com
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
腾讯CDC
小众软件
小众软件
G
Google Developers Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Scott Helme
Scott Helme
O
OpenAI News

重归混沌的BLOG

给silly实现了一个ernro模块 | 重归混沌的BLOG 给silly实现了一个ernro模块 | 重归混沌的BLOG 第一次在生产环境使用 Vibe Coding | 重归混沌的BLOG 第一次在生产环境使用 Vibe Coding | 重归混沌的BLOG API 设计的艰难抉择 | 重归混沌的BLOG API 设计的艰难抉择 | 重归混沌的BLOG 十年 | 重归混沌的BLOG 十年 | 重归混沌的BLOG 在Go语言中如何使XML加载内存无限趋近于0 | 重归混沌的BLOG 在Go语言中如何使XML加载内存无限趋近于0 | 重归混沌的BLOG 对跨服玩法中的分布式一致性问题进行简单抽象 | 重归混沌的BLOG 对跨服玩法中的分布式一致性问题进行简单抽象 | 重归混沌的BLOG Go语言逃逸分析之slice和map | 重归混沌的BLOG Go语言逃逸分析之slice和map | 重归混沌的BLOG 谈谈观测 | 重归混沌的BLOG 谈谈观测 | 重归混沌的BLOG 写了个AI Agent服务端 | 重归混沌的BLOG 写了个AI Agent服务端 | 重归混沌的BLOG 谈谈代码设计中“严丝合缝” | 重归混沌的BLOG 谈谈代码设计中“严丝合缝” | 重归混沌的BLOG 一次艰难的线上游戏服务器内存排查经历 | 重归混沌的BLOG 一次艰难的线上游戏服务器内存排查经历 如何基于LanguageServerProtocol来编写lint工具 谈谈游戏服务器中RPC模块的设计 谈谈游戏服务器代码抽象 最近碰到的一个分布式一致性问题 谈谈游戏服务器的自动化测试 对Raft协议的一点理解 使用mmap来学习/proc/pid/smaps 2023(完) 再次实现了一个Lua性能分析器 终于给Silly的定时器增加了取消功能 一次虚拟内存排查经历 游戏服务器分布式数据的一种同步的思路 为silly增加了互斥锁 2022(完) Go语言之闭包篇 一例误用unsafe包引起的内存问题 Go语言之内存篇 初识Go语言 重新抽象图形API 给Lua实现了一个数学库 谈谈跨平台图形API的抽象 寻路和Flocking算法的结合 行为树的一种高效实现 内测过程中Shader出现的问题 彻底解决多国语言 谈谈数据库的选型 再谈Lua热更新(终) 初窥Rust 关于游戏服务器的服务拆分 ECS的初步实现 ECS初探 屏幕空间(SreenSpace)的想象力 一些对辐射度量学的理解 深度缓冲和半透明渲染 Mysql的间隙锁 更新一些GPU相关知识 2020 地形渲染之爬过的坑 Lua5.3 GC源码阅读(5) 实现一个数据库存储队列 再学计算机图形学入门 再谈分布式服务架构 游戏上线一个月后的反思 一次并发Bug 双向链表的三种实现 谈谈随机数的使用 再谈性能优化 2019 Lua中的函数式编程 重构登录逻辑 Unity资源管理(续) 谈谈Unity的资源管理 一次关于Cache的性能分析 历史之2018 DC3算法 移动平台native代码遭遇的坑 从CPU层面谈谈优化 开卷有益(UNIX编程艺术篇) GC竞争问题 通过Mesh投影来实现贴花系统 谈谈我对数据同步的理解 又一个类型提升引起的Bug Lua5.3 GC源码阅读(4) Lua5.3 GC源码阅读(3) Lua5.3 GC源码阅读(2) 三角形光栅化时遇到的坑 一次git事故 再见2017 又一个lua调试器 客户端缓存落地方案 Paxos算法 HTTP服务器的特点 一次性能优化经历 关于CPU分支预测 C程序中让两个不同版本的库共存 实现了一个AOI模块 一个高可伸缩的游戏服务器架构 关于网络协议封装的一些新想法
Lua5.3 GC源码阅读(1)
重归混沌 · 2018-04-11 · via 重归混沌的BLOG

最近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是一致的.