mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-07-15 08:48:33 +00:00
Implement GC stack object tracking for func object
This commit is contained in:
parent
e521d9991d
commit
d6e4fd7d63
|
@ -290,15 +290,24 @@ wasm_array_obj_get_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
|
||||||
|
|
||||||
WASMFuncObjectRef
|
WASMFuncObjectRef
|
||||||
wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
|
wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
|
||||||
uint32 func_idx_bound, uint32 param_count_bound)
|
const WASMFuncType *func_type_bound, uint32 func_idx_bound,
|
||||||
|
uint32 param_count_bound)
|
||||||
{
|
{
|
||||||
WASMFuncObjectRef func_obj;
|
WASMFuncObjectRef func_obj;
|
||||||
uint64 total_size;
|
uint64 total_size;
|
||||||
|
uint32 ref_param_count = 0, offset = 0, i;
|
||||||
|
uint16 *reference_table;
|
||||||
|
|
||||||
bh_assert(rtt_obj->type_flag == WASM_TYPE_FUNC);
|
bh_assert(rtt_obj->type_flag == WASM_TYPE_FUNC);
|
||||||
|
|
||||||
|
for (i = 0; i < param_count_bound; i++) {
|
||||||
|
if (wasm_is_type_reftype(func_type_bound->types[i]))
|
||||||
|
ref_param_count++;
|
||||||
|
}
|
||||||
|
|
||||||
total_size = offsetof(WASMFuncObject, params_bound)
|
total_size = offsetof(WASMFuncObject, params_bound)
|
||||||
+ (uint64)sizeof(WASMValue) * param_count_bound;
|
+ (uint64)sizeof(WASMValue) * param_count_bound
|
||||||
|
+ (uint64)sizeof(uint16) * (ref_param_count + 1);
|
||||||
if (!(func_obj = gc_obj_malloc(heap_handle, total_size))) {
|
if (!(func_obj = gc_obj_malloc(heap_handle, total_size))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -306,6 +315,18 @@ wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
|
||||||
func_obj->header = (WASMObjectHeader)rtt_obj;
|
func_obj->header = (WASMObjectHeader)rtt_obj;
|
||||||
func_obj->func_idx_bound = func_idx_bound;
|
func_obj->func_idx_bound = func_idx_bound;
|
||||||
func_obj->param_count_bound = param_count_bound;
|
func_obj->param_count_bound = param_count_bound;
|
||||||
|
func_obj->reference_table = reference_table =
|
||||||
|
(uint16 *)((uint8 *)func_obj + offsetof(WASMFuncObject, params_bound)
|
||||||
|
+ sizeof(WASMValue) * param_count_bound);
|
||||||
|
|
||||||
|
*reference_table++ = (uint16)ref_param_count;
|
||||||
|
offset = (uint16)offsetof(WASMFuncObject, params_bound);
|
||||||
|
for (i = 0; i < param_count_bound; i++) {
|
||||||
|
if (wasm_is_type_reftype(func_type_bound->types[i])) {
|
||||||
|
*reference_table++ = (uint16)offset;
|
||||||
|
offset += (uint16)sizeof(WASMValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
return func_obj;
|
return func_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,8 +420,12 @@ wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (rtt_obj->defined_type->type_flag == WASM_TYPE_FUNC) {
|
else if (rtt_obj->defined_type->type_flag == WASM_TYPE_FUNC) {
|
||||||
/* TODO */
|
/* function object */
|
||||||
return false;
|
WASMFuncObjectRef func_obj = (WASMFuncObjectRef)obj;
|
||||||
|
*p_is_compact_mode = false;
|
||||||
|
*p_ref_num = *func_obj->reference_table;
|
||||||
|
*p_ref_list = func_obj->reference_table + 1;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (rtt_obj->defined_type->type_flag == WASM_TYPE_STRUCT) {
|
else if (rtt_obj->defined_type->type_flag == WASM_TYPE_STRUCT) {
|
||||||
/* struct object */
|
/* struct object */
|
||||||
|
|
|
@ -97,6 +97,10 @@ typedef struct WASMFuncObject {
|
||||||
WASMObjectHeader header;
|
WASMObjectHeader header;
|
||||||
uint32 func_idx_bound;
|
uint32 func_idx_bound;
|
||||||
uint32 param_count_bound;
|
uint32 param_count_bound;
|
||||||
|
/* Offsets of reference params that need to be traced
|
||||||
|
during GC. The first element of the table is the
|
||||||
|
number of such offsets. */
|
||||||
|
uint16 *reference_table;
|
||||||
WASMValue params_bound[1];
|
WASMValue params_bound[1];
|
||||||
} WASMFuncObject, *WASMFuncObjectRef;
|
} WASMFuncObject, *WASMFuncObjectRef;
|
||||||
|
|
||||||
|
@ -225,7 +229,8 @@ wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx)
|
||||||
|
|
||||||
WASMFuncObjectRef
|
WASMFuncObjectRef
|
||||||
wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
|
wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
|
||||||
uint32 func_idx_bound, uint32 param_count_bound);
|
const WASMFuncType *func_type_bound, uint32 func_idx_bound,
|
||||||
|
uint32 param_count_bound);
|
||||||
|
|
||||||
void
|
void
|
||||||
wasm_func_obj_set_param_bound(WASMFuncObjectRef func_obj, uint32 param_idx,
|
wasm_func_obj_set_param_bound(WASMFuncObjectRef func_obj, uint32 param_idx,
|
||||||
|
|
|
@ -1773,7 +1773,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
func_type_dst =
|
func_type_dst =
|
||||||
(WASMFuncType *)module->module->types[type_index];
|
(WASMFuncType *)module->module->types[type_index];
|
||||||
|
|
||||||
func_obj_old = POP_REF();
|
SYNC_ALL_TO_FRAME();
|
||||||
|
|
||||||
|
/* Don't POP_REF() here to let the object be tracable
|
||||||
|
during GC when creating func object below */
|
||||||
|
func_obj_old = GET_REF_FROM_ADDR(frame_sp - REF_CELL_NUM);
|
||||||
if (!func_obj_old) {
|
if (!func_obj_old) {
|
||||||
wasm_set_exception(module, "null function object");
|
wasm_set_exception(module, "null function object");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -1794,6 +1798,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Pop object after the func object is created */
|
||||||
|
(void)POP_REF();
|
||||||
|
|
||||||
param_count_bound =
|
param_count_bound =
|
||||||
wasm_func_obj_get_param_count_bound(func_obj_old);
|
wasm_func_obj_get_param_count_bound(func_obj_old);
|
||||||
for (j = 0; j < (int32)param_count_bound; j++) {
|
for (j = 0; j < (int32)param_count_bound; j++) {
|
||||||
|
|
|
@ -393,14 +393,24 @@ init_frame_refs(uint8 *frame_ref, uint32 cell_num, WASMFunctionInstance *func)
|
||||||
(opnd_off = GET_OFFSET(), CLEAR_FRAME_REF(opnd_off), \
|
(opnd_off = GET_OFFSET(), CLEAR_FRAME_REF(opnd_off), \
|
||||||
GET_REF_FROM_ADDR(frame_lp + opnd_off))
|
GET_REF_FROM_ADDR(frame_lp + opnd_off))
|
||||||
|
|
||||||
|
#if WASM_ENABLE_GC != 0
|
||||||
|
#define SYNC_FRAME_REF() frame->frame_ref = frame_ref
|
||||||
|
#define UPDATE_FRAME_REF() frame_ref = frame->frame_ref
|
||||||
|
#else
|
||||||
|
#define SYNC_FRAME_REF() (void)0
|
||||||
|
#define UPDATE_FRAME_REF() (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SYNC_ALL_TO_FRAME() \
|
#define SYNC_ALL_TO_FRAME() \
|
||||||
do { \
|
do { \
|
||||||
frame->ip = frame_ip; \
|
frame->ip = frame_ip; \
|
||||||
|
SYNC_FRAME_REF(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define UPDATE_ALL_FROM_FRAME() \
|
#define UPDATE_ALL_FROM_FRAME() \
|
||||||
do { \
|
do { \
|
||||||
frame_ip = frame->ip; \
|
frame_ip = frame->ip; \
|
||||||
|
UPDATE_FRAME_REF(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||||
|
@ -1103,12 +1113,12 @@ wasm_interp_dump_op_count()
|
||||||
for (i = 0; i < WASM_OP_IMPDEP; i++)
|
for (i = 0; i < WASM_OP_IMPDEP; i++)
|
||||||
total_count += opcode_table[i].count;
|
total_count += opcode_table[i].count;
|
||||||
|
|
||||||
printf("total opcode count: %ld\n", total_count);
|
os_printf("total opcode count: %ld\n", total_count);
|
||||||
for (i = 0; i < WASM_OP_IMPDEP; i++)
|
for (i = 0; i < WASM_OP_IMPDEP; i++)
|
||||||
if (opcode_table[i].count > 0)
|
if (opcode_table[i].count > 0)
|
||||||
printf("\t\t%s count:\t\t%ld,\t\t%.2f%%\n", opcode_table[i].name,
|
os_printf("\t\t%s count:\t\t%ld,\t\t%.2f%%\n", opcode_table[i].name,
|
||||||
opcode_table[i].count,
|
opcode_table[i].count,
|
||||||
opcode_table[i].count * 100.0f / total_count);
|
opcode_table[i].count * 100.0f / total_count);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1601,6 +1611,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
#if WASM_ENABLE_GC == 0
|
#if WASM_ENABLE_GC == 0
|
||||||
PUSH_I32(func_idx);
|
PUSH_I32(func_idx);
|
||||||
#else
|
#else
|
||||||
|
SYNC_ALL_TO_FRAME();
|
||||||
if (!(gc_obj = wasm_create_func_obj(module, func_idx, true,
|
if (!(gc_obj = wasm_create_func_obj(module, func_idx, true,
|
||||||
NULL, true, NULL, 0))) {
|
NULL, true, NULL, 0))) {
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -1654,7 +1665,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
type_idx = read_uint32(frame_ip);
|
type_idx = read_uint32(frame_ip);
|
||||||
func_type_dst = (WASMFuncType *)module->module->types[type_idx];
|
func_type_dst = (WASMFuncType *)module->module->types[type_idx];
|
||||||
|
|
||||||
func_obj_old = POP_REF();
|
SYNC_ALL_TO_FRAME();
|
||||||
|
|
||||||
|
opnd_off = GET_OFFSET();
|
||||||
|
func_obj_old = GET_REF_FROM_ADDR(frame_lp + opnd_off);
|
||||||
|
|
||||||
if (!func_obj_old) {
|
if (!func_obj_old) {
|
||||||
wasm_set_exception(module, "null function object");
|
wasm_set_exception(module, "null function object");
|
||||||
goto got_exception;
|
goto got_exception;
|
||||||
|
@ -1779,6 +1794,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
struct_type =
|
struct_type =
|
||||||
(WASMStructType *)module->module->types[type_idx];
|
(WASMStructType *)module->module->types[type_idx];
|
||||||
|
|
||||||
|
SYNC_ALL_TO_FRAME();
|
||||||
|
|
||||||
rtt_obj = POP_REF();
|
rtt_obj = POP_REF();
|
||||||
struct_obj = wasm_struct_obj_new(module->gc_heap_handle,
|
struct_obj = wasm_struct_obj_new(module->gc_heap_handle,
|
||||||
rtt_obj);
|
rtt_obj);
|
||||||
|
@ -1936,6 +1953,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNC_ALL_TO_FRAME();
|
||||||
|
|
||||||
array_obj =
|
array_obj =
|
||||||
wasm_array_obj_new(module->gc_heap_handle, rtt_obj,
|
wasm_array_obj_new(module->gc_heap_handle, rtt_obj,
|
||||||
array_len, &array_elem);
|
array_len, &array_elem);
|
||||||
|
@ -3975,6 +3994,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||||
+ s,
|
+ s,
|
||||||
(uint32)(n * sizeof(uint32)));
|
(uint32)(n * sizeof(uint32)));
|
||||||
#else
|
#else
|
||||||
|
SYNC_ALL_TO_FRAME();
|
||||||
|
|
||||||
table_elems =
|
table_elems =
|
||||||
(table_elem_type_t *)tbl_inst->base_addr + d;
|
(table_elem_type_t *)tbl_inst->base_addr + d;
|
||||||
func_indexes = module->module->table_segments[elem_idx]
|
func_indexes = module->module->table_segments[elem_idx]
|
||||||
|
|
|
@ -1207,8 +1207,9 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(func_obj = wasm_func_obj_new(module_inst->gc_heap_handle, rtt_obj,
|
if (!(func_obj =
|
||||||
func_idx, param_count_bound))) {
|
wasm_func_obj_new(module_inst->gc_heap_handle, rtt_obj, func_type,
|
||||||
|
func_idx, param_count_bound))) {
|
||||||
set_error_buf(error_buf, error_buf_size, "create func object failed");
|
set_error_buf(error_buf, error_buf_size, "create func object failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user