@@ -493,6 +493,26 @@ typedef struct JSWeakRefRecord {
493
493
} u;
494
494
} JSWeakRefRecord;
495
495
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
+
496
516
enum {
497
517
JS_ATOM_TYPE_STRING = 1,
498
518
JS_ATOM_TYPE_GLOBAL_SYMBOL,
@@ -1694,8 +1714,8 @@ static JSClassShortDef const js_std_class_def[] = {
1694
1714
{ JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */
1695
1715
{ JS_ATOM_Map, js_map_finalizer, js_map_mark }, /* JS_CLASS_MAP */
1696
1716
{ 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 */
1699
1719
{ JS_ATOM_Iterator, NULL, NULL }, /* JS_CLASS_ITERATOR */
1700
1720
{ JS_ATOM_IteratorHelper, js_iterator_helper_finalizer, js_iterator_helper_mark }, /* JS_CLASS_ITERATOR_HELPER */
1701
1721
{ 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)
5783
5803
}
5784
5804
}
5785
5805
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
+
5786
5822
static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
5787
5823
JS_MarkFunc *mark_func)
5788
5824
{
@@ -5822,6 +5858,10 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp,
5822
5858
prs++;
5823
5859
}
5824
5860
5861
+ if (unlikely(p->first_weak_ref)) {
5862
+ mark_weak_map_value(rt, p->first_weak_ref, mark_func);
5863
+ }
5864
+
5825
5865
if (p->class_id != JS_CLASS_OBJECT) {
5826
5866
JSClassGCMark *gc_mark;
5827
5867
gc_mark = rt->class_array[p->class_id].gc_mark;
@@ -48433,26 +48473,6 @@ static const JSCFunctionListEntry js_symbol_funcs[] = {
48433
48473
48434
48474
/* Set/Map/WeakSet/WeakMap */
48435
48475
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
-
48456
48476
#define MAGIC_SET (1 << 0)
48457
48477
#define MAGIC_WEAK (1 << 1)
48458
48478
@@ -49056,10 +49076,10 @@ static void js_map_mark(JSRuntime *rt, JSValueConst val,
49056
49076
49057
49077
s = p->u.map_state;
49058
49078
if (s) {
49079
+ assert(!s->is_weak);
49059
49080
list_for_each(el, &s->records) {
49060
49081
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);
49063
49083
JS_MarkValue(rt, mr->value, mark_func);
49064
49084
}
49065
49085
}
0 commit comments