Skip to content

Commit 0f5c465

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents bcd6552 + f483b91 commit 0f5c465

252 files changed

Lines changed: 24778 additions & 4723 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
target: "wasm32-unknown-wasip1"
2727
- os: ubuntu-24.04
2828
toolchain:
29-
download-url: https://download.swift.org/swift-6.3-branch/ubuntu2404/swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-05-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2025-12-05-a-ubuntu24.04.tar.gz
29+
download-url: https://download.swift.org/swift-6.3-branch/ubuntu2404/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a/swift-6.3-DEVELOPMENT-SNAPSHOT-2026-03-05-a-ubuntu24.04.tar.gz
3030
wasi-backend: Node
3131
target: "wasm32-unknown-wasip1"
3232
- os: ubuntu-22.04
@@ -81,6 +81,8 @@ jobs:
8181
swift-syntax-version: "601.0.0"
8282
- image: "swift:6.2"
8383
swift-syntax-version: "602.0.0"
84+
- image: "swift:6.3"
85+
swift-syntax-version: "603.0.0"
8486
runs-on: ubuntu-latest
8587
container:
8688
image: ${{ matrix.entry.image }}
@@ -167,21 +169,23 @@ jobs:
167169
- uses: actions/checkout@v6
168170
- uses: ./.github/actions/install-swift
169171
with:
170-
download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-02-02-a/swift-DEVELOPMENT-SNAPSHOT-2026-02-02-a-ubuntu22.04.tar.gz
172+
download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2026-03-09-a/swift-DEVELOPMENT-SNAPSHOT-2026-03-09-a-ubuntu22.04.tar.gz
171173
- uses: swiftwasm/setup-swiftwasm@v2
172174
id: setup-wasm32-unknown-wasip1
173175
with: { target: wasm32-unknown-wasip1 }
174176
- uses: swiftwasm/setup-swiftwasm@v2
175177
id: setup-wasm32-unknown-wasip1-threads
176178
with: { target: wasm32-unknown-wasip1-threads }
177-
- run: ./Utilities/build-examples.sh
179+
- run: |
180+
swift --version
181+
./Utilities/build-examples.sh
178182
env:
179183
SWIFT_SDK_ID_wasm32_unknown_wasip1_threads: ${{ steps.setup-wasm32-unknown-wasip1-threads.outputs.swift-sdk-id }}
180184
SWIFT_SDK_ID_wasm32_unknown_wasip1: ${{ steps.setup-wasm32-unknown-wasip1.outputs.swift-sdk-id }}
181185
- run: ./Utilities/prepare-gh-pages.sh
182186
- name: Upload static files as artifact
183187
id: deployment
184-
uses: actions/upload-pages-artifact@v4
188+
uses: actions/upload-pages-artifact@v5
185189
with:
186190
path: ./_site
187191
deploy-examples:
@@ -197,4 +201,4 @@ jobs:
197201
steps:
198202
- name: Deploy to GitHub Pages
199203
id: deployment
200-
uses: actions/deploy-pages@v4
204+
uses: actions/deploy-pages@v5

Benchmarks/README.md

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ This directory contains performance benchmarks for JavaScriptKit.
44

55
## Building Benchmarks
66

7-
Before running the benchmarks, you need to build the test suite:
8-
97
```bash
108
swift package --swift-sdk $SWIFT_SDK_ID js -c release
119
```
@@ -19,19 +17,38 @@ node run.js
1917
# Save results to a JSON file
2018
node run.js --output=results.json
2119

22-
# Specify number of iterations
23-
node run.js --runs=20
24-
2520
# Run in adaptive mode until results stabilize
2621
node run.js --adaptive --output=stable-results.json
2722

28-
# Run benchmarks and compare with previous results
23+
# Compare with previous results
2924
node run.js --baseline=previous-results.json
3025

31-
# Run only a subset of benchmarks
32-
# Substring match
26+
# Filter benchmarks by name
3327
node run.js --filter=Call
34-
# Regex (with flags)
3528
node run.js --filter=/^Property access\//
36-
node run.js --filter=/string/i
3729
```
30+
31+
## Identity Mode Benchmarks
32+
33+
The benchmark suite includes identity-mode variants (`@JS(identityMode: true)`) of the core classes to measure pointer identity caching. Both variants are in the same build and run as regular benchmarks alongside everything else.
34+
35+
```bash
36+
# Run only identity benchmarks
37+
node --expose-gc run.js --filter=Identity
38+
39+
# Run only pointer-mode identity benchmarks
40+
node --expose-gc run.js --filter=Identity/pointer
41+
42+
# Run only non-identity baseline
43+
node --expose-gc run.js --filter=Identity/none
44+
```
45+
46+
### Identity Scenarios
47+
48+
| Scenario | What it measures |
49+
|----------|-----------------|
50+
| `passBothWaysRoundtrip` | Same object crossing boundary repeatedly (cache hit path) |
51+
| `getPoolRepeated_100` | Bulk return of 100 cached objects (model collection pattern) |
52+
| `churnObjects` | Create, roundtrip, release cycle (FinalizationRegistry cleanup pressure) |
53+
| `swiftConsumesSameObject` | JS passes same object to Swift repeatedly |
54+
| `swiftCreatesObject` | Fresh object creation overhead (cache miss path) |

Benchmarks/Sources/Benchmarks.swift

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,109 @@ enum ComplexResult {
257257
}
258258
}
259259

260+
// MARK: - Class Array Performance Tests
261+
262+
nonisolated(unsafe) var _classArrayPool: [SimpleClass] = []
263+
264+
@JS class ClassArrayRoundtrip {
265+
@JS init() {}
266+
267+
@JS func setupPool(_ count: Int) {
268+
_classArrayPool = (0..<count).map {
269+
SimpleClass(name: "Item \($0)", count: $0, flag: true, rate: 0.5, precise: 3.14)
270+
}
271+
}
272+
273+
@JS func getPool() -> [SimpleClass] {
274+
return _classArrayPool
275+
}
276+
277+
@JS func makeClassArray() -> [SimpleClass] {
278+
return (0..<100).map {
279+
SimpleClass(name: "Item \($0)", count: $0, flag: true, rate: 0.5, precise: 3.14)
280+
}
281+
}
282+
283+
@JS func takeClassArray(_ values: [SimpleClass]) {}
284+
285+
@JS func roundtripClassArray(_ values: [SimpleClass]) -> [SimpleClass] {
286+
return values
287+
}
288+
}
289+
290+
// MARK: - Identity Cache Benchmark
291+
292+
nonisolated(unsafe) var _cachedPool: [SimpleClass] = []
293+
294+
@JS class IdentityCacheBenchmark {
295+
@JS init() {}
296+
297+
@JS func setupPool(_ count: Int) {
298+
_cachedPool = (0..<count).map {
299+
SimpleClass(name: "Item \($0)", count: $0, flag: true, rate: 0.5, precise: 3.14)
300+
}
301+
}
302+
303+
@JS func getPoolRepeated() -> [SimpleClass] {
304+
return _cachedPool
305+
}
306+
}
307+
308+
// MARK: - Identity Mode Benchmark Variants
309+
// These classes use @JS(identityMode: true) so that identity cache benchmarks
310+
// can run in the SAME build alongside the non-identity classes above.
311+
312+
@JS(identityMode: true)
313+
class SimpleClassIdentity {
314+
@JS var name: String
315+
@JS var count: Int
316+
@JS var flag: Bool
317+
@JS var rate: Float
318+
@JS var precise: Double
319+
320+
@JS init(name: String, count: Int, flag: Bool, rate: Float, precise: Double) {
321+
self.name = name
322+
self.count = count
323+
self.flag = flag
324+
self.rate = rate
325+
self.precise = precise
326+
}
327+
}
328+
329+
@JS(identityMode: true)
330+
class ClassRoundtripIdentity {
331+
@JS init() {}
332+
333+
@JS func roundtripSimpleClassIdentity(_ obj: SimpleClassIdentity) -> SimpleClassIdentity {
334+
return obj
335+
}
336+
337+
@JS func makeSimpleClassIdentity() -> SimpleClassIdentity {
338+
return SimpleClassIdentity(name: "Hello", count: 42, flag: true, rate: 0.5, precise: 3.14159)
339+
}
340+
341+
@JS func takeSimpleClassIdentity(_ obj: SimpleClassIdentity) {
342+
// consume without returning
343+
}
344+
}
345+
346+
nonisolated(unsafe) var _cachedPoolIdentity: [SimpleClassIdentity] = []
347+
348+
@JS(identityMode: true)
349+
class IdentityCacheBenchmarkIdentity {
350+
@JS init() {}
351+
352+
@JS func setupPool(_ count: Int) {
353+
_cachedPoolIdentity = (0..<count).map {
354+
SimpleClassIdentity(name: "Item \($0)", count: $0, flag: true, rate: 0.5, precise: 3.14)
355+
}
356+
}
357+
358+
@JS func getPoolRepeated() -> [SimpleClassIdentity] {
359+
return _cachedPoolIdentity
360+
}
361+
}
362+
260363
// MARK: - Array Performance Tests
261364

262365
@JS struct Point {

0 commit comments

Comments
 (0)