• lua全局状态机


           本文内容基于版本:Lua 5.3.0

    global_State概述


           global_State结构,我们可以称之为Lua全局状态机。从Lua的使用者角度来看,global_State结构是完全感知不到的:我们无法用Lua公开的API获取到它的指针、句柄或引用,而且实际上我们也并不需要引用到它。但是对于Lua的实现来说,global_State是十分重要的部分:它里面有对主线程(lua_State实例)的引用、有全局字符串表、有内存管理函数、有GC需要的相关信息以及一切Lua在工作时需要的工作内存等等。

    global_State与lua_State结构的关联


           通过luaL_newstate函数创建虚拟机时,第一块申请的内存将用来存储lua_State(主线程)和global_State(全局状态机)实例。为了避免内存碎片的产生,同时减少内存分配和释放的次数,Lua采用了一个小技巧:利用一个LG结构,把分配lua_Stateglobal_State的行为关联在一起。这个LG结构是在C文件内部定义,而不存在公开的H文件中,仅供该C代码文件使用,因此这种依赖数据结构内存布局的用法负作用不大。

          

    // luaconf.h
    /*
    @@ LUA_EXTRASPACE defines the size of a raw memory area associated with
    ** a Lua state with very fast access.
    ** CHANGE it if you need a different size.
    */
    #define LUA_EXTRASPACE        (sizeof(void *))
    
    // lstate.c
    /*
    ** thread state + extra space
    */
    typedef struct LX {
      lu_byte extra_[LUA_EXTRASPACE];
      lua_State l;
    } LX;
    
    /*
    ** Main thread combines a thread state and the global state
    */
    typedef struct LG {
      LX l;
      global_State g;
    } LG;

     global_State的创建和销毁


    • global_State的创建和初始化

    // lstate.c
    LUA_API
    lua_State *lua_newstate (lua_Alloc f, void *ud) { int i; lua_State *L; global_State *g; LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); if (l == NULL) return NULL; L = &l->l.l; g = &l->g; ...... return L; }

     • global_State的销毁

    // lstate.c
    LUA_API void lua_close (lua_State *L) {
      L = G(L)->mainthread;  /* only the main thread can be closed */
      lua_lock(L);
      close_state(L);
    }
    
    // lstate.c
    static void close_state (lua_State *L) {
      global_State *g = G(L);
      luaF_close(L, L->stack);  /* close all upvalues for this thread */
      luaC_freeallobjects(L);  /* collect all objects */
      if (g->version)  /* closing a fully built state? */
        luai_userstateclose(L);
      luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
      luaZ_freebuffer(L, &g->buff);
      freestack(L);
      lua_assert(gettotalbytes(g) == sizeof(LG));
      (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);  /* free main block */
    }

     fromstate(L)宏


           fromstate(L)宏的实现源码:

    // stddef.h(Linux & Windows)
    #define offsetof(s,m)   (size_t)&(((s *)0)->m)
    
    // llimits.h
    #define cast(t, exp)    ((t)(exp))
    
    // lstate.c
    #define fromstate(L)    (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))

           fromstate(L)宏的实现图解:

          

  • 相关阅读:
    Laravel 静态资源管理及表单布局
    Laravel 中间件的使用(前置与后置)
    Laravel 中的模板中的url
    Laravel 基础语法和include的使用
    Laravel模板的继承
    Laravel的路由、控制器和模型
    用composer安装laravel
    vue cli3.0 给路径起别名 vue.config.js ;代码统一风格 .editorconfig
    github的使用
    Java学习的第十二天
  • 原文地址:https://www.cnblogs.com/heartchord/p/4538123.html
Copyright © 2020-2023  润新知