Skip to content

Commit cc65b0e

Browse files
Merge pull request swiftwasm#19 from swiftwasm/fix-heap-system
Renovate heap system to avoid polluting object
2 parents 423431f + 166912c commit cc65b0e

File tree

2 files changed

+40
-18
lines changed

2 files changed

+40
-18
lines changed

IntegrationTests/TestSuites/Sources/BenchmarkTests/main.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,15 @@ serialization.testSuite("Swift String to JavaScript") {
1919
object.set("stringValue\(i)", jsString)
2020
}
2121
}
22+
23+
24+
let objectHeap = Benchmark("Object heap")
25+
26+
let global = JSObjectRef.global
27+
let Object = global.Object.function!
28+
global.objectHeapDummy = .object(Object.new())
29+
objectHeap.testSuite("Increment and decrement RC") {
30+
for _ in 0 ..< 100 {
31+
_ = global.objectHeapDummy
32+
}
33+
}

Runtime/src/index.ts

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,13 @@ enum JavaScriptValueKind {
3131
Function = 6,
3232
}
3333

34+
type SwiftRuntimeHeapEntry = {
35+
id: number,
36+
rc: number,
37+
}
3438
class SwiftRuntimeHeap {
35-
private _heapValues: Map<number, any>;
39+
private _heapValueById: Map<number, any>;
40+
private _heapEntryByValue: Map<any, SwiftRuntimeHeapEntry>;
3641
private _heapNextKey: number;
3742

3843
constructor() {
@@ -42,43 +47,48 @@ class SwiftRuntimeHeap {
4247
} else if (typeof global !== "undefined") {
4348
_global = global
4449
}
45-
this._heapValues = new Map();
46-
this._heapValues.set(0, _global);
50+
this._heapValueById = new Map();
51+
this._heapValueById.set(0, _global);
52+
53+
this._heapEntryByValue = new Map();
54+
this._heapEntryByValue.set(_global, { id: 0, rc: 1 });
55+
4756
// Note: 0 is preserved for global
4857
this._heapNextKey = 1;
4958
}
5059

5160
allocHeap(value: any) {
52-
const isObject = typeof value == "object"
53-
if (isObject && value.swjs_heap_id) {
54-
value.swjs_heap_rc++;
55-
return value.swjs_heap_id
61+
const isObject = typeof value == "object";
62+
const entry = this._heapEntryByValue.get(value);
63+
if (isObject && entry) {
64+
entry.rc++
65+
return entry.id
5666
}
5767
const id = this._heapNextKey++;
58-
this._heapValues.set(id, value)
68+
this._heapValueById.set(id, value)
5969
if (isObject) {
60-
Reflect.set(value, "swjs_heap_id", id);
61-
Reflect.set(value, "swjs_heap_rc", 1);
70+
this._heapEntryByValue.set(value, { id: id, rc: 1 })
6271
}
6372
return id
6473
}
6574

6675
freeHeap(ref: ref) {
67-
const value = this._heapValues.get(ref);
76+
const value = this._heapValueById.get(ref);
6877
const isObject = typeof value == "object"
6978
if (isObject) {
70-
const rc = --value.swjs_heap_rc;
71-
if (rc != 0) return;
72-
delete value.swjs_heap_id;
73-
delete value.swjs_heap_rc;
74-
this._heapValues.delete(ref)
79+
const entry = this._heapEntryByValue.get(value)!;
80+
entry.rc--;
81+
if (entry.rc != 0) return;
82+
83+
this._heapEntryByValue.delete(value);
84+
this._heapValueById.delete(ref)
7585
} else {
76-
this._heapValues.delete(ref)
86+
this._heapValueById.delete(ref)
7787
}
7888
}
7989

8090
referenceHeap(ref: ref) {
81-
return this._heapValues.get(ref)
91+
return this._heapValueById.get(ref)
8292
}
8393
}
8494

0 commit comments

Comments
 (0)