Memory management 使用lld和s2wasm查找堆的开始

Memory management 使用lld和s2wasm查找堆的开始,memory-management,heap-memory,webassembly,Memory Management,Heap Memory,Webassembly,我正在使用clang->llc->s2wasm和clang->lld>从C编译到WebAssembly。因为没有提供c库,所以我编写了自己的分配器。但我不确定找到自由记忆的开始的最佳方法是什么 lld和s2wasm似乎都有内存布局:|globals | stack | free memory |。使用s2wasm的堆栈指针位于内存地址,使用lld它位于全局中(无法从C访问) 我发现的一种方法是使用以下技巧在wasm执行开始时读取堆栈指针: intstacktop() { INTA; 返回值(整数

我正在使用
clang->llc->s2wasm
clang->lld>从C编译到WebAssembly。因为没有提供c库,所以我编写了自己的分配器。但我不确定找到自由记忆的开始的最佳方法是什么

lld和s2wasm似乎都有内存布局:
|globals | stack | free memory |
。使用s2wasm的堆栈指针位于内存地址,使用lld它位于全局中(无法从C访问)

我发现的一种方法是使用以下技巧在wasm执行开始时读取堆栈指针:

intstacktop()
{
INTA;
返回值(整数)(&a+1);
}
这将创建一个局部变量,它不驻留在线性内存中,并获取它的地址。要生成地址,编译器将其放在内存堆栈中


我使用返回的值作为堆的开始。是否有一种更优雅且经得起未来考验的方法来查找可用内存?

lld创建了一个名为
\uuuu heap\u base
的C符号,它指向堆的底部。它还将其导出为wasm全局,以便嵌入程序可以知道堆从何处开始。

您需要获取由lld创建的
\uuuu heap\u base
符号的地址:

$ cat wasm-heap.c
extern unsigned char __heap_base;

__attribute__ ((visibility("default"))) 
void * get_heap_base(void) {
  return &__heap_base;
}
这将返回与导出到JavaScript的WASM变量相同的值:

$ cat wasm-heap.js
var imports = {memory: new WebAssembly.Memory({initial:2})};
const module = new WebAssembly.Module(read('wasm-heap.wasm', 'binary'));
const instance = new WebAssembly.Instance(module, { "env" : imports }).exports;
var u8_data = new Uint8Array(imports["memory"]["buffer"]);

print("Heap base in WASM: " + instance.get_heap_base());
print("Heap base exported to JS: " + instance.__heap_base);

$ js52 wasm-heap.js
Heap base in WASM: 66560
Heap base exported to JS: 66560

谢谢,但我不知道如何访问它。Clang不知道符号,所以当我尝试使用
外部constuint32\u t\u heap\u base
定义它时。clang创建一个全局变量,但只在代码中插入
i32.const 0,i32.load offset=4294967295
。使用clang 6.0.0.lld在链接时创建此符号。Clang应该在代码中生成重定位,lld应该在链接时替换它。OK。我还没有设法访问它。Clang可能会创建一个全局的,但它没有。稍后我将试图弄清这一点。在编译时,它只是一个未知的外部符号。直到链接时间,这个符号才存在,所以clang不需要知道任何关于它的信息。我不知道你所说的“叮当声应该创造一个全球性的”是什么意思。也许您的意思是应该在某个地方的C头中声明它?如果您使用外部内存分配器,有些人可能会发现设置
-Clink arg=--export=\uuuu heap\u base
标志对lld很有帮助。