Просмотр исходного кода

Fix GC issues (#2204)

- don't mark non-ref array elements
- trace ref returned from native function
- fix calculated array element offset error in reclaim_instance_heap
Xu Jun 2 лет назад
Родитель
Сommit
8021df9894

+ 13 - 4
core/iwasm/common/gc/gc_object.c

@@ -684,7 +684,7 @@ wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
         static uint16 externref_obj_ref_list[] = { (uint16)offsetof(
             WASMExternrefObject, internal_obj) };
         *p_is_compact_mode = false;
-        *p_ref_num = 0;
+        *p_ref_num = 1;
         *p_ref_list = externref_obj_ref_list;
         return true;
     }
@@ -712,9 +712,18 @@ wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
     }
     else if (rtt_type->defined_type->type_flag == WASM_TYPE_ARRAY) {
         /* array object */
-        *p_is_compact_mode = true;
-        *p_ref_num = (uint16)wasm_array_obj_length((WASMArrayObjectRef)obj);
-        *p_ref_start_offset = (uint16)offsetof(WASMArrayObject, elem_data);
+        WASMArrayType *type = (WASMArrayType *)rtt_type->defined_type;
+        if (wasm_is_type_reftype(type->elem_type)) {
+            *p_is_compact_mode = true;
+            *p_ref_num = (uint16)wasm_array_obj_length((WASMArrayObjectRef)obj);
+            *p_ref_start_offset = (uint16)offsetof(WASMArrayObject, elem_data);
+        }
+        else {
+            *p_is_compact_mode = false;
+            *p_ref_num = 0;
+            *p_ref_list = NULL;
+        }
+
         return true;
     }
     else {

+ 15 - 0
core/iwasm/interpreter/wasm_interp_classic.c

@@ -1025,6 +1025,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     char buf[128];
     bool ret;
 #if WASM_ENABLE_GC != 0
+    WASMFuncType *func_type;
     uint8 *frame_ref;
 #endif
 
@@ -1093,6 +1094,20 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     if (!ret)
         return;
 
+#if WASM_ENABLE_GC != 0
+    func_type = cur_func->u.func_import->func_type;
+    if (func_type->result_count
+        && wasm_is_type_reftype(func_type->types[cur_func->param_count])) {
+        frame_ref = (uint8 *)prev_frame->csp_boundary
+                    + (unsigned)(uintptr_t)(prev_frame->sp - prev_frame->lp);
+#if UINTPTR_MAX == UINT64_MAX
+        *frame_ref = *(frame_ref + 1) = 1;
+#else
+        *frame_ref = 1;
+#endif
+    }
+#endif
+
     if (cur_func->ret_cell_num == 1) {
         prev_frame->sp[0] = argv_ret[0];
         prev_frame->sp++;

+ 17 - 0
core/iwasm/interpreter/wasm_interp_fast.c

@@ -1030,6 +1030,10 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     uint32 argv_ret[2], cur_func_index;
     void *native_func_pointer = NULL;
     bool ret;
+#if WASM_ENABLE_GC != 0
+    WASMFuncType *func_type;
+    uint8 *frame_ref;
+#endif
 
     all_cell_num = local_cell_num;
 #if WASM_ENABLE_GC != 0
@@ -1096,6 +1100,19 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
     if (!ret)
         return;
 
+#if WASM_ENABLE_GC != 0
+    func_type = cur_func->u.func_import->func_type;
+    if (func_type->result_count
+        && wasm_is_type_reftype(func_type->types[cur_func->param_count])) {
+        frame_ref = prev_frame->frame_ref + prev_frame->ret_offset;
+#if UINTPTR_MAX == UINT64_MAX
+        *frame_ref = *(frame_ref + 1) = 1;
+#else
+        *frame_ref = 1;
+#endif
+    }
+#endif
+
     if (cur_func->ret_cell_num == 1) {
         prev_frame->lp[prev_frame->ret_offset] = argv_ret[0];
     }

+ 3 - 3
core/shared/mem-alloc/ems/ems_gc.c

@@ -368,8 +368,8 @@ reclaim_instance_heap(gc_heap_t *heap)
 
             if (is_compact_mode) {
                 for (j = 0; j < (int)ref_num; j++) {
-                    offset = ref_start_offset + j * 4;
-                    bh_assert(offset + 4 < size);
+                    offset = ref_start_offset + j * sizeof(void *);
+                    bh_assert(offset + sizeof(void *) < size);
                     ref = *(gc_object_t *)(((gc_uint8 *)obj) + offset);
                     if (ref == NULL_REF)
                         continue; /* NULL REF */
@@ -384,7 +384,7 @@ reclaim_instance_heap(gc_heap_t *heap)
             else {
                 for (j = 0; j < (int)ref_num; j++) {
                     offset = ref_list[j];
-                    bh_assert(offset + 4 < size);
+                    bh_assert(offset + sizeof(void *) < size);
 
                     ref = *(gc_object_t *)(((gc_uint8 *)obj) + offset);
                     if (ref == NULL_REF)