Implement GC stack object tracking for func object

This commit is contained in:
Wenyong Huang 2022-06-25 05:01:20 +08:00
parent e521d9991d
commit d6e4fd7d63
5 changed files with 72 additions and 13 deletions

View File

@ -290,15 +290,24 @@ wasm_array_obj_get_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
WASMFuncObjectRef
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;
uint64 total_size;
uint32 ref_param_count = 0, offset = 0, i;
uint16 *reference_table;
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)
+ (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))) {
return NULL;
}
@ -306,6 +315,18 @@ wasm_func_obj_new(void *heap_handle, WASMRttObjectRef rtt_obj,
func_obj->header = (WASMObjectHeader)rtt_obj;
func_obj->func_idx_bound = func_idx_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;
}
@ -399,8 +420,12 @@ wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
return true;
}
else if (rtt_obj->defined_type->type_flag == WASM_TYPE_FUNC) {
/* TODO */
return false;
/* function object */
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) {
/* struct object */

View File

@ -97,6 +97,10 @@ typedef struct WASMFuncObject {
WASMObjectHeader header;
uint32 func_idx_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];
} WASMFuncObject, *WASMFuncObjectRef;
@ -225,7 +229,8 @@ wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx)
WASMFuncObjectRef
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
wasm_func_obj_set_param_bound(WASMFuncObjectRef func_obj, uint32 param_idx,

View File

@ -1773,7 +1773,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
func_type_dst =
(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) {
wasm_set_exception(module, "null function object");
goto got_exception;
@ -1794,6 +1798,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
goto got_exception;
}
/* Pop object after the func object is created */
(void)POP_REF();
param_count_bound =
wasm_func_obj_get_param_count_bound(func_obj_old);
for (j = 0; j < (int32)param_count_bound; j++) {

View File

@ -393,14 +393,24 @@ init_frame_refs(uint8 *frame_ref, uint32 cell_num, WASMFunctionInstance *func)
(opnd_off = GET_OFFSET(), CLEAR_FRAME_REF(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() \
do { \
frame->ip = frame_ip; \
SYNC_FRAME_REF(); \
} while (0)
#define UPDATE_ALL_FROM_FRAME() \
do { \
frame_ip = frame->ip; \
UPDATE_FRAME_REF(); \
} while (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++)
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++)
if (opcode_table[i].count > 0)
printf("\t\t%s count:\t\t%ld,\t\t%.2f%%\n", opcode_table[i].name,
opcode_table[i].count,
opcode_table[i].count * 100.0f / total_count);
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 * 100.0f / total_count);
}
#endif
@ -1601,6 +1611,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
#if WASM_ENABLE_GC == 0
PUSH_I32(func_idx);
#else
SYNC_ALL_TO_FRAME();
if (!(gc_obj = wasm_create_func_obj(module, func_idx, true,
NULL, true, NULL, 0))) {
goto got_exception;
@ -1654,7 +1665,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
type_idx = read_uint32(frame_ip);
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) {
wasm_set_exception(module, "null function object");
goto got_exception;
@ -1779,6 +1794,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
struct_type =
(WASMStructType *)module->module->types[type_idx];
SYNC_ALL_TO_FRAME();
rtt_obj = POP_REF();
struct_obj = wasm_struct_obj_new(module->gc_heap_handle,
rtt_obj);
@ -1936,6 +1953,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
}
SYNC_ALL_TO_FRAME();
array_obj =
wasm_array_obj_new(module->gc_heap_handle, rtt_obj,
array_len, &array_elem);
@ -3975,6 +3994,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
+ s,
(uint32)(n * sizeof(uint32)));
#else
SYNC_ALL_TO_FRAME();
table_elems =
(table_elem_type_t *)tbl_inst->base_addr + d;
func_indexes = module->module->table_segments[elem_idx]

View File

@ -1207,8 +1207,9 @@ wasm_create_func_obj(WASMModuleInstance *module_inst, uint32 func_idx,
return NULL;
}
if (!(func_obj = wasm_func_obj_new(module_inst->gc_heap_handle, rtt_obj,
func_idx, param_count_bound))) {
if (!(func_obj =
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");
return NULL;
}