• 自制编程语言crowbar(v0.1)构建解析器时分配内存


    crowbar中第一次申请内存是在生成解析器的时候:

    /* interface.c */
    CRB_Interpreter *CRB_create_interpreter(void) { MEM_Storage storage; CRB_Interpreter *interpreter; storage = MEM_open_storage(0); interpreter = MEM_storage_malloc(storage, sizeof(struct CRB_Interpreter_tag)); interpreter->interpreter_storage = storage; interpreter->execute_storage = NULL; interpreter->variable = NULL; interpreter->function_list = NULL; interpreter->statement_list = NULL; interpreter->current_line_number = 1; crb_set_current_interpreter(interpreter); add_native_functions(interpreter); return interpreter; }

    首先看一下MEM_Storage类型,声明:

    /* MEM.h */
    typedef struct MEM_Storage_tag *MEM_Storage;
    /* MEM/storage.c */
    struct MEM_Storage_tag {
        MemoryPageList      page_list;
        int                 current_page_size;
    };
    
    typedef MemoryPage *MemoryPageList;
    
    typedef struct MemoryPage_tag MemoryPage;
    
    struct MemoryPage_tag {
        int                 cell_num;
        int                 use_cell_num;
        MemoryPageList      next;
        Cell                cell[1];
    };
    
    typedef union {
        long        l_dummy;
        double      d_dummy;
        void        *p_dummy;
    } Cell;

    结构图:(cell是union)

    再接着看MEM_open_storage(0)

    /* MEM.h */
    #define
    MEM_open_storage(page_size)(MEM_open_storage_func(MEM_CURRENT_CONTROLLER, __FILE__, __LINE__, page_size))
    /* MEM/storage.c */
    MEM_Storage MEM_open_storage_func(MEM_Controller controller,char *filename, int line, int page_size)
    {
        MEM_Storage storage;
    
        storage = MEM_malloc_func(controller, filename, line,
                                  sizeof(struct MEM_Storage_tag));
        storage->page_list = NULL;
        assert(page_size >= 0);
        if (page_size > 0) {
            storage->current_page_size = page_size;
        } else {
            storage->current_page_size = DEFAULT_PAGE_SIZE;
        }
    
        return storage;
    }
    MEM_open_storage函数传了一个MEM_CURRENT_CONTROLLER宏,那接下来看一下这个宏定义:
    /* MEM.h */
    typedef struct MEM_Controller_tag *MEM_Controller;

    extern MEM_Controller mem_default_controller;

    #ifdef MEM_CONTROLLER
    #define MEM_CURRENT_CONTROLLER MEM_CONTROLLER #else /* MEM_CONTROLLER */ #define MEM_CURRENT_CONTROLLER mem_default_controller #endif /* MEM_CONTROLLER */

     MEM_Controller_tag的定义:

    /* MEM/memory.h */
    typedef union Header_tag Header;
    struct MEM_Controller_tag { FILE *error_fp; MEM_ErrorHandler error_handler; MEM_FailMode fail_mode; Header *block_header; };

    /* MEM.h */
    typedef void (*MEM_ErrorHandler)(MEM_Controller, char *, int, char *);

    typedef enum {
        MEM_FAIL_AND_EXIT,
        MEM_FAIL_AND_RETURN
    } MEM_FailMode;

      其中Header_tag定义:

    /* MEM/memory.c */
    union Header_tag {
        HeaderStruct        s;
        Align               u[HEADER_ALIGN_SIZE];
    };
    
    #define MARK_SIZE       (4)
    #define ALIGN_SIZE      (sizeof(Align))
    #define revalue_up_align(val) ((val) ? (((val) - 1) / ALIGN_SIZE + 1) : 0) #define HEADER_ALIGN_SIZE (revalue_up_align(sizeof(HeaderStruct)))
    #define MARK (0xCD)
    typedef struct { int size; char *filename; int line; Header *prev; Header *next; unsigned char mark[MARK_SIZE]; } HeaderStruct; typedef union { long l_dummy; double d_dummy; void *p_dummy; } Align;


    可以看到在MEM_open_storage_func()中调用了MEM_malloc_func(),MEM_malloc_func原型:

    /* MEM/memory.c */
    void
    *MEM_malloc_func(MEM_Controller controller, char *filename, int line, size_t size) { void *ptr; size_t alloc_size; #ifdef DEBUG alloc_size = size + sizeof(Header) + MARK_SIZE; #else alloc_size = size; #endif ptr = malloc(alloc_size); if (ptr == NULL) { error_handler(controller, filename, line, "malloc"); } #ifdef DEBUG memset(ptr, 0xCC, alloc_size); set_header(ptr, size, filename, line); set_tail(ptr, alloc_size); chain_block(controller, (Header*)ptr); ptr = (char*)ptr + sizeof(Header); #endif return ptr; }

    其中的DEBUG代码暂时先不管。那到这里为止已经从内存中申请了DEFAULT_PAGE_SIZE(1024)大小的内存给了MEM_Storage storage变量

    接着看 interpreter = MEM_storage_malloc(storage, sizeof(struct CRB_Interpreter_tag));

    MEM_storage_malloc原型:

    /* MEM.h */
    #define
    MEM_storage_malloc(storage, size) (MEM_storage_malloc_func(MEM_CURRENT_CONTROLLER,__FILE__, __LINE__, storage, size))
    /* MEM/storage.c */ void *MEM_storage_malloc_func(MEM_Controller controller, char *filename, int line, MEM_Storage storage, size_t size) { int cell_num; MemoryPage *new_page; void *p; cell_num = ((size - 1) / CELL_SIZE) + 1;   /* 如果storage中已经用到的cell加上将要分配的cell小于storage中所有的cell则从storage中取出一个cell返回 */ if (storage->page_list != NULL && (storage->page_list->use_cell_num + cell_num < storage->page_list->cell_num)) { p = &(storage->page_list->cell[storage->page_list->use_cell_num]); storage->page_list->use_cell_num += cell_num;
      /* 否则则重新从内存中申请 */ }
    else { int alloc_cell_num; alloc_cell_num = larger(cell_num, storage->current_page_size); new_page = MEM_malloc_func(controller, filename, line, sizeof(MemoryPage) + CELL_SIZE * (alloc_cell_num - 1)); new_page->next = storage->page_list; new_page->cell_num = alloc_cell_num; storage->page_list = new_page; p = &(new_page->cell[0]); new_page->use_cell_num = cell_num; } return p; }

    到此解析器的构建中内存分配已分析完



  • 相关阅读:
    微博粉丝服务---“公众号”开发
    springboot --- 之SSM框架整合
    Android 接收短信
    数字币开发相关
    boot camp要求独立的fat分区
    u盘安装 osx 出现 “不能验证”
    微软驱动签名
    centos7 安装 isign
    用windbg查看dmp文件,定位bug位置
    H5移动端,ios从后台返回到app,页面会白一下
  • 原文地址:https://www.cnblogs.com/orlion/p/5516232.html
Copyright © 2020-2023  润新知