@@ -493,6 +493,26 @@ typedef struct JSWeakRefRecord {
493493 } u;
494494} JSWeakRefRecord;
495495
496+ typedef struct JSMapRecord {
497+ int ref_count; /* used during enumeration to avoid freeing the record */
498+ bool empty; /* true if the record is deleted */
499+ struct JSMapState *map;
500+ struct list_head link;
501+ struct list_head hash_link;
502+ JSValue key;
503+ JSValue value;
504+ } JSMapRecord;
505+
506+ typedef struct JSMapState {
507+ bool is_weak; /* true if WeakSet/WeakMap */
508+ struct list_head records; /* list of JSMapRecord.link */
509+ uint32_t record_count;
510+ struct list_head *hash_table;
511+ uint32_t hash_size; /* must be a power of two */
512+ uint32_t record_count_threshold; /* count at which a hash table
513+ resize is needed */
514+ } JSMapState;
515+
496516enum {
497517 JS_ATOM_TYPE_STRING = 1,
498518 JS_ATOM_TYPE_GLOBAL_SYMBOL,
@@ -1694,8 +1714,8 @@ static JSClassShortDef const js_std_class_def[] = {
16941714 { JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */
16951715 { JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */
16961716 { JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */
1697- { JS_ATOM_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */
1698- { JS_ATOM_WeakSet, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKSET */
1717+ { JS_ATOM_WeakMap, js_map_finalizer, NULL }, /* JS_CLASS_WEAKMAP */
1718+ { JS_ATOM_WeakSet, js_map_finalizer, NULL }, /* JS_CLASS_WEAKSET */
16991719 { JS_ATOM_Iterator, NULL, NULL }, /* JS_CLASS_ITERATOR */
17001720 { JS_ATOM_IteratorHelper, js_iterator_helper_finalizer, js_iterator_helper_mark }, /* JS_CLASS_ITERATOR_HELPER */
17011721 { JS_ATOM_IteratorWrap, js_iterator_wrap_finalizer, js_iterator_wrap_mark }, /* JS_CLASS_ITERATOR_WRAP */
@@ -5783,6 +5803,22 @@ void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func)
57835803 }
57845804}
57855805
5806+ static void mark_weak_map_value(JSRuntime *rt, JSWeakRefRecord *first_weak_ref, JS_MarkFunc *mark_func) {
5807+ JSWeakRefRecord *wr;
5808+ JSMapRecord *mr;
5809+ JSMapState *s;
5810+
5811+ for (wr = first_weak_ref; wr != NULL; wr = wr->next_weak_ref) {
5812+ if (wr->kind == JS_WEAK_REF_KIND_MAP) {
5813+ mr = wr->u.map_record;
5814+ s = mr->map;
5815+ assert(s->is_weak);
5816+ assert(!mr->empty); /* no iterator on WeakMap/WeakSet */
5817+ JS_MarkValue(rt, mr->value, mark_func);
5818+ }
5819+ }
5820+ }
5821+
57865822static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
57875823 JS_MarkFunc *mark_func)
57885824{
@@ -5822,6 +5858,10 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
58225858 prs++;
58235859 }
58245860
5861+ if (unlikely(p->first_weak_ref)) {
5862+ mark_weak_map_value(rt, p->first_weak_ref, mark_func);
5863+ }
5864+
58255865 if (p->class_id != JS_CLASS_OBJECT) {
58265866 JSClassGCMark *gc_mark;
58275867 gc_mark = rt->class_array[p->class_id].gc_mark;
@@ -48433,26 +48473,6 @@ static const JSCFunctionListEntry js_symbol_funcs[] = {
4843348473
4843448474/* Set/Map/WeakSet/WeakMap */
4843548475
48436- typedef struct JSMapRecord {
48437- int ref_count; /* used during enumeration to avoid freeing the record */
48438- bool empty; /* true if the record is deleted */
48439- struct JSMapState *map;
48440- struct list_head link;
48441- struct list_head hash_link;
48442- JSValue key;
48443- JSValue value;
48444- } JSMapRecord;
48445-
48446- typedef struct JSMapState {
48447- bool is_weak; /* true if WeakSet/WeakMap */
48448- struct list_head records; /* list of JSMapRecord.link */
48449- uint32_t record_count;
48450- struct list_head *hash_table;
48451- uint32_t hash_size; /* must be a power of two */
48452- uint32_t record_count_threshold; /* count at which a hash table
48453- resize is needed */
48454- } JSMapState;
48455-
4845648476#define MAGIC_SET (1 << 0)
4845748477#define MAGIC_WEAK (1 << 1)
4845848478
@@ -49056,10 +49076,10 @@ static void js_map_mark(JSRuntime *rt, JSValueConst val,
4905649076
4905749077 s = p->u.map_state;
4905849078 if (s) {
49079+ assert(!s->is_weak);
4905949080 list_for_each(el, &s->records) {
4906049081 mr = list_entry(el, JSMapRecord, link);
49061- if (!s->is_weak)
49062- JS_MarkValue(rt, mr->key, mark_func);
49082+ JS_MarkValue(rt, mr->key, mark_func);
4906349083 JS_MarkValue(rt, mr->value, mark_func);
4906449084 }
4906549085 }
0 commit comments