Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

> > # 内存地址相关 #560

Closed
nacyzhouw opened this issue Jul 15, 2019 · 3 comments
Closed

> > # 内存地址相关 #560

nacyzhouw opened this issue Jul 15, 2019 · 3 comments

Comments

@nacyzhouw
Copy link

内存地址相关

简介

https://blog.csdn.net/qq_23079443/article/details/81143877

  • 32位系统最大可用内存2^32个字节,2^10*2^10*2^10*2^2,1024个字节等于1KB 1024个KB等于1MB,1024个MB等于1GB,2^30 = 1GB2^40 = 1TB1111 1111 1111 ...1111,32位共32个*8个1(1Byte = 8bit)
  • 在64位操作系统中: 程序员可以使用的内存只要有前面的48位就可以了。也就是0X7fffffffffffffff(0x7fffffffffff = 01111111111111111111111111111111111111111111111)以下的。
  • javascript的帧栈:
    https://github.com/stacktracejs/stackframe/blob/0d7a328bf05f6867e62245e3c9574aab2c97fd3b/stackframe.js#L29
var stackFrame = new StackFrame({
    functionName: 'funName',
    args: ['args'],
    fileName: 'http://localhost:3000/file.js',
    lineNumber: 1,
    columnNumber: 3288, 
    isEval: true,
    isNative: false,
    source: 'ORIGINAL_STACK_LINE'
});
   var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel'];
    var numericProps = ['columnNumber', 'lineNumber'];
    var stringProps = ['fileName', 'functionName', 'source'];
    var arrayProps = ['args'];
  • ecma_init()的调用栈
jmem_heap_alloc_block_internal(const size_t size) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/jmem/jmem-heap.c:163)
jmem_heap_gc_and_alloc_block(const size_t size, _Bool ret_null_on_error) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/jmem/jmem-heap.c:327)
jmem_heap_alloc_block(const size_t size) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/jmem/jmem-heap.c:373)
ecma_alloc_extended_object(size_t size) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/base/ecma-alloc.c:113)
ecma_create_object(ecma_object_t * prototype_object_p, size_t ext_object_size, ecma_object_type_t type) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/base/ecma-helpers.c:81)
ecma_instantiate_builtin(ecma_builtin_id_t obj_builtin_id) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/builtin-objects/ecma-builtins.c:385)
ecma_instantiate_builtin(ecma_builtin_id_t obj_builtin_id) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/builtin-objects/ecma-builtins.c:360)
ecma_builtin_get(ecma_builtin_id_t builtin_id) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/builtin-objects/ecma-builtins.c:297)
ecma_init_global_lex_env() (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/operations/ecma-lex-env.c:42)
ecma_init() (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/ecma/base/ecma-init-finalize.c:38)
jerry_init(jerry_init_flag_t flags) (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/jerry-core/api/jerry.c:185)
main() (/home/cisen/桌面/develop/jerryscript/demo-jerryscript/main.c:13)
  • jmem_heap_alloc_block_internal函数是内存分配的最底层调用,该函数直接从全局的jerry_global_heap堆中申请内存,jerry_global_heap是固定512KB。jerry_global_heap堆的结构如下:
/**
 *  Free region node
 * 自由区域节点
 */
typedef struct
{
  uint32_t next_offset; /**< Offset of next region in list 列表中下一个区域的偏移量 */
  uint32_t size; /**< Size of region 区域大小 */
} jmem_heap_free_t;

struct jmem_heap_t
{
  jmem_heap_free_t first; /**< first node in free region list 自由区域列表中的第一个节点 */
  uint8_t area[JMEM_HEAP_AREA_SIZE]; /**< heap area 头部区域 JMEM_HEAP_AREA_SIZE是512*1024 -8预留8字节*/
};
  • jmen就是jerry-memory的意思
  • jerry_context_t是一个独立的栈,不是存在上面jerry_global_heap堆里面的

内部

  • 貌似定义的地址范围是0x7FFFFFFFFFFF,即可

总结

  • 说有的数据变更基本都是变更global_heap, 所以一定要搞清楚,全局堆的操作方式,具体见:jmem_heap_alloc_block_internal函数
  • parser_list的每个项目叫做page
  • parser_context的literal_pool就是存储很多literal_p的地方,详见:
literal_p = (lexer_literal_t *) parser_list_append (context_p, &context_p->literal_pool);

parser_context.lit_object只是存储当前的literal_object。每个literal_object其实是存在global_heap里面的,详见上面的函数调用了:parser_malloc函数申请heap堆内存

您好,好巧我最近也在研究JerryScript,有个问题请教下。
jerry_global_heap 这个代码中要求8字节对齐,知道是什么原因吗?
JERRY_ASSERT ((uintptr_t) JERRY_HEAP_CONTEXT (area) % JMEM_ALIGNMENT == 0);

因为的它的存储结构是jmem_heap_free_t,刚好是8字节吧,(建议关注:#535 这个帖子,以后解读基本以那个为主)

Originally posted by @cisen in #479 (comment)

分析了下觉得和jmem_heap_free_t 8字节没关系。
与JerryScript中ecma的结构有关。
具体分析如下: jerry_global_heap是我们分配的堆的起始地址,以创建object为例子,jerry_global_heap的8字节对齐,决定了后面分配的ecma_object_point8字节对齐。(ecma_object_point 必须8字节对齐,因为ecma_object_point 转成ecma_data时,通过ecma_pointer_to_ecma_value直接(将指针地址转为值)强转得到的,后面3bit必须为000, 官网中已说明ecma_value后面的3bit需要用于标志type)

@cisen
Copy link
Owner

cisen commented Jul 15, 2019

JERRY_ASSERT ((uintptr_t) JERRY_HEAP_CONTEXT (area) % JMEM_ALIGNMENT == 0);

上面这句应该只是要求jerry_global_heap.area为8字节对齐把?没有要求jerry_global_heap为8字节对齐把?分析area关键是这两个宏:

#define JMEM_HEAP_GET_OFFSET_FROM_ADDR(p) ((uint32_t) ((uint8_t *) (p) - JERRY_HEAP_CONTEXT (area)))
#define JMEM_HEAP_GET_ADDR_FROM_OFFSET(u) ((jmem_heap_free_t *) (JERRY_HEAP_CONTEXT (area) + (u)))

看这两个宏的读写操作赋值结果area的类型都是jmem_heap_free_t,没读写别的东西,所以只能是8字节

@nacyzhouw
Copy link
Author

JERRY_ASSERT ((uintptr_t) JERRY_HEAP_CONTEXT (area) % JMEM_ALIGNMENT == 0);

上面这句应该只是要求jerry_global_heap.area为8字节对齐把?没有要求jerry_global_heap为8字节对齐把?分析area关键是这两个宏:

#define JMEM_HEAP_GET_OFFSET_FROM_ADDR(p) ((uint32_t) ((uint8_t *) (p) - JERRY_HEAP_CONTEXT (area)))
#define JMEM_HEAP_GET_ADDR_FROM_OFFSET(u) ((jmem_heap_free_t *) (JERRY_HEAP_CONTEXT (area) + (u)))

看这两个宏的读写操作赋值结果area的类型都是jmem_heap_free_t,没读写别的东西,所以只能是8字节

为了保证jerry_global_heap.area可以是8字节对齐,必须是 jerry_global_heap是8字节对齐,对吧

另外下面的宏 (jmem_heap_free_t *)的作用是将jerry_global_heap.area指向的类型转为jmem_heap_free_t,它的地址是不变,并不是对jerry_global_heap.area地址对齐有什么约束
#define JMEM_HEAP_GET_ADDR_FROM_OFFSET(u) ((jmem_heap_free_t *) (JERRY_HEAP_CONTEXT (area) + (u)))

@cisen
Copy link
Owner

cisen commented Jul 17, 2019

我觉得你理解错我的意思了,我的意思是对area的操作基本都是通过JMEM_HEAP_GET_OFFSET_FROM_ADDR和JMEM_HEAP_GET_ADDR_FROM_OFFSET这两个宏进行的。那么我们可以看看jerryscript通过调用这两个宏往area塞入了什么数据。全局搜索这两个宏发现,只往area塞入了jmem_heap_free_t类型的数据,没有别的类型数据。所以area里面只有jmem_heap_free_t为结构单元的数据

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants