Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6165368

Browse files
feat: optimize string literal tostack behavior
String literals are widely used static data, and our GC algorithm does not recycle them (see https://github.com/AssemblyScript/assemblyscript/blob/7e2a62d9615d2ae02b593af87ee4920a3c57b0bd/std/assembly/rt/itcms.ts#L244). Recording the addresses of all string literals and preventing the emission of tostack code can effectively improve performance
1 parent 7e2a62d commit 6165368

File tree

74 files changed

+3214
-17715
lines changed

Some content is hidden

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

74 files changed

+3214
-17715
lines changed

‎src/compiler.ts

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ import {
5959
isConstNegZero,
6060
isConstExpressionNaN,
6161
ensureType,
62-
createType
62+
createType,
63+
getConstValueInteger
6364
} from "./module";
6465

6566
import {
@@ -451,6 +452,8 @@ export class Compiler extends DiagnosticEmitter {
451452
memorySegments: MemorySegment[] = [];
452453
/** Map of already compiled static string segments. */
453454
stringSegments: Map<string,MemorySegment> = new Map();
455+
/** Set of static GC object offsets. tostack is unnecessary for them. */
456+
staticGcObjectOffsets: Map<i32, Set<i32>> = new Map();
454457
/** Function table being compiled. First elem is blank. */
455458
functionTable: Function[] = [];
456459
/** Arguments length helper global. */
@@ -1939,7 +1942,16 @@ export class Compiler extends DiagnosticEmitter {
19391942
stringSegment = this.addRuntimeMemorySegment(buf);
19401943
segments.set(stringValue, stringSegment);
19411944
}
1942-
return i64_add(stringSegment.offset, i64_new(totalOverhead));
1945+
let stringOffset = i64_add(stringSegment.offset, i64_new(totalOverhead));
1946+
let staticGcObjectOffsets = this.staticGcObjectOffsets;
1947+
if (staticGcObjectOffsets.has(i64_high(stringOffset))) {
1948+
assert(staticGcObjectOffsets.get(i64_high(stringOffset))).add(i64_low(stringOffset));
1949+
} else {
1950+
let s = new Set<i32>();
1951+
s.add(i64_low(stringOffset));
1952+
staticGcObjectOffsets.set(i64_high(stringOffset), s);
1953+
}
1954+
return stringOffset;
19431955
}
19441956

19451957
/** Writes a series of static values of the specified type to a buffer. */
@@ -6754,6 +6766,21 @@ export class Compiler extends DiagnosticEmitter {
67546766
stub.set(CommonFlags.Compiled);
67556767
}
67566768

6769+
private needToStack(expr: ExpressionRef): bool {
6770+
const precomp = this.module.runExpression(expr, ExpressionRunnerFlags.Default);
6771+
// cannot precompute, so must go to stack
6772+
if (precomp == 0) return true;
6773+
const value = getConstValueInteger(precomp, this.options.isWasm64);
6774+
// zero constant doesn't need to go to stack
6775+
if (i64_eq(value, i64_zero)) return false;
6776+
// static GC objects doesn't need to go to stack
6777+
let staticGcObjectOffsets = this.staticGcObjectOffsets;
6778+
if (staticGcObjectOffsets.has(i64_high(value))) {
6779+
if (assert(staticGcObjectOffsets.get(i64_high(value))).has(i64_low(value))) return false;
6780+
}
6781+
return true;
6782+
}
6783+
67576784
/** Marks managed call operands for the shadow stack. */
67586785
private operandsTostack(signature: Signature, operands: ExpressionRef[]): void {
67596786
if (!this.options.stackSize) return;
@@ -6763,8 +6790,7 @@ export class Compiler extends DiagnosticEmitter {
67636790
if (thisType) {
67646791
if (thisType.isManaged) {
67656792
let operand = operands[0];
6766-
let precomp = module.runExpression(operand, ExpressionRunnerFlags.Default);
6767-
if (!precomp || !isConstZero(precomp)) { // otherwise unnecessary
6793+
if (this.needToStack(operand)) {
67686794
operands[operandIndex] = module.tostack(operand);
67696795
}
67706796
}
@@ -6777,8 +6803,7 @@ export class Compiler extends DiagnosticEmitter {
67776803
let paramType = parameterTypes[parameterIndex];
67786804
if (paramType.isManaged) {
67796805
let operand = operands[operandIndex];
6780-
let precomp = module.runExpression(operand, ExpressionRunnerFlags.Default);
6781-
if (!precomp || !isConstZero(precomp)) { // otherwise unnecessary
6806+
if (this.needToStack(operand)) {
67826807
operands[operandIndex] = module.tostack(operand);
67836808
}
67846809
}

‎src/module.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3038,6 +3038,18 @@ export function getConstValueI64High(expr: ExpressionRef): i32 {
30383038
return binaryen._BinaryenConstGetValueI64High(expr);
30393039
}
30403040

3041+
export function getConstValueInteger(expr: ExpressionRef, isWasm64: bool): i64 {
3042+
let lo: i32 = 0;
3043+
let hi: i32 = 0;
3044+
if (isWasm64) {
3045+
lo = getConstValueI64Low(expr);
3046+
hi = getConstValueI64High(expr);
3047+
} else {
3048+
lo = getConstValueI32(expr);
3049+
}
3050+
return i64_new(lo, hi);
3051+
}
3052+
30413053
export function getConstValueF32(expr: ExpressionRef): f32 {
30423054
return binaryen._BinaryenConstGetValueF32(expr);
30433055
}

‎tests/compiler/NonNullable.debug.wat

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -357,28 +357,15 @@
357357
(local 0ドル i32)
358358
(local 1ドル i32)
359359
global.get $~lib/memory/__stack_pointer
360-
i32.const 12
360+
i32.const 8
361361
i32.sub
362362
global.set $~lib/memory/__stack_pointer
363363
call $~stack_check
364364
global.get $~lib/memory/__stack_pointer
365365
i64.const 0
366366
i64.store
367-
global.get $~lib/memory/__stack_pointer
368-
i32.const 0
369-
i32.store offset=8
370367
i32.const 32
371-
local.set 1ドル
372-
global.get $~lib/memory/__stack_pointer
373-
local.get 1ドル
374-
i32.store
375-
local.get 1ドル
376368
i32.const 32
377-
local.set 1ドル
378-
global.get $~lib/memory/__stack_pointer
379-
local.get 1ドル
380-
i32.store offset=4
381-
local.get 1ドル
382369
call $~lib/string/String.__eq
383370
i32.eqz
384371
if
@@ -390,17 +377,7 @@
390377
unreachable
391378
end
392379
i32.const 112
393-
local.set 1ドル
394-
global.get $~lib/memory/__stack_pointer
395-
local.get 1ドル
396-
i32.store
397-
local.get 1ドル
398380
i32.const 112
399-
local.set 1ドル
400-
global.get $~lib/memory/__stack_pointer
401-
local.get 1ドル
402-
i32.store offset=4
403-
local.get 1ドル
404381
call $~lib/string/String.__eq
405382
i32.eqz
406383
if
@@ -412,17 +389,7 @@
412389
unreachable
413390
end
414391
i32.const 144
415-
local.set 1ドル
416-
global.get $~lib/memory/__stack_pointer
417-
local.get 1ドル
418-
i32.store
419-
local.get 1ドル
420392
i32.const 144
421-
local.set 1ドル
422-
global.get $~lib/memory/__stack_pointer
423-
local.get 1ドル
424-
i32.store offset=4
425-
local.get 1ドル
426393
call $~lib/string/String.__eq
427394
i32.eqz
428395
if
@@ -436,7 +403,7 @@
436403
global.get $~lib/memory/__stack_pointer
437404
global.get $NonNullable/z
438405
local.tee 0ドル
439-
i32.store offset=8
406+
i32.store offset=4
440407
local.get 0ドル
441408
if (result i32)
442409
local.get 0ドル
@@ -462,7 +429,7 @@
462429
local.get 1ドル
463430
call $NonNullable/safetyCheck<~lib/string/String|null>
464431
global.get $~lib/memory/__stack_pointer
465-
i32.const 12
432+
i32.const 8
466433
i32.add
467434
global.set $~lib/memory/__stack_pointer
468435
)

‎tests/compiler/NonNullable.release.wat

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
(start $~start)
2323
(func $~start
2424
global.get $~lib/memory/__stack_pointer
25-
i32.const 12
25+
i32.const 8
2626
i32.sub
2727
global.set $~lib/memory/__stack_pointer
2828
block $folding-inner0
@@ -33,15 +33,6 @@
3333
global.get $~lib/memory/__stack_pointer
3434
i64.const 0
3535
i64.store
36-
global.get $~lib/memory/__stack_pointer
37-
i32.const 0
38-
i32.store offset=8
39-
global.get $~lib/memory/__stack_pointer
40-
i32.const 1056
41-
i32.store
42-
global.get $~lib/memory/__stack_pointer
43-
i32.const 1056
44-
i32.store offset=4
4536
i32.const 1056
4637
i32.const 1056
4738
call $~lib/string/String.__eq
@@ -54,12 +45,6 @@
5445
call $~lib/builtins/abort
5546
unreachable
5647
end
57-
global.get $~lib/memory/__stack_pointer
58-
i32.const 1136
59-
i32.store
60-
global.get $~lib/memory/__stack_pointer
61-
i32.const 1136
62-
i32.store offset=4
6348
i32.const 1136
6449
i32.const 1136
6550
call $~lib/string/String.__eq
@@ -72,12 +57,6 @@
7257
call $~lib/builtins/abort
7358
unreachable
7459
end
75-
global.get $~lib/memory/__stack_pointer
76-
i32.const 1168
77-
i32.store
78-
global.get $~lib/memory/__stack_pointer
79-
i32.const 1168
80-
i32.store offset=4
8160
i32.const 1168
8261
i32.const 1168
8362
call $~lib/string/String.__eq
@@ -92,7 +71,7 @@
9271
end
9372
global.get $~lib/memory/__stack_pointer
9473
i32.const 1248
95-
i32.store offset=8
74+
i32.store offset=4
9675
global.get $~lib/memory/__stack_pointer
9776
i32.const 1248
9877
i32.store
@@ -126,7 +105,7 @@
126105
i32.add
127106
global.set $~lib/memory/__stack_pointer
128107
global.get $~lib/memory/__stack_pointer
129-
i32.const 12
108+
i32.const 8
130109
i32.add
131110
global.set $~lib/memory/__stack_pointer
132111
return

‎tests/compiler/bindings/esm.debug.wat

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,27 @@
124124
(export "functionFunction" (func $export:bindings/esm/functionFunction))
125125
(func $start:bindings/esm~anonymous|0
126126
)
127+
(func $start:bindings/esm
128+
i32.const 128
129+
i32.const 1
130+
f64.const 42
131+
f64.const 0
132+
f64.const 0
133+
f64.const 0
134+
f64.const 0
135+
call $~lib/builtins/trace
136+
i32.const 160
137+
call $~lib/bindings/dom/console.log
138+
global.get $~lib/bindings/dom/Math.E
139+
call $~lib/bindings/dom/Math.log
140+
drop
141+
global.get $bindings/esm/immutableGlobal
142+
drop
143+
global.get $bindings/esm/immutableGlobalNested
144+
drop
145+
call $bindings/esm/Date_getTimezoneOffset
146+
drop
147+
)
127148
(func $bindings/esm/plainFunction (param $a i32) (param $b i32) (result i32)
128149
local.get $a
129150
local.get $b
@@ -3081,50 +3102,6 @@
30813102
unreachable
30823103
end
30833104
)
3084-
(func $start:bindings/esm
3085-
(local 0ドル i32)
3086-
global.get $~lib/memory/__stack_pointer
3087-
i32.const 4
3088-
i32.sub
3089-
global.set $~lib/memory/__stack_pointer
3090-
call $~stack_check
3091-
global.get $~lib/memory/__stack_pointer
3092-
i32.const 0
3093-
i32.store
3094-
i32.const 128
3095-
local.set 0ドル
3096-
global.get $~lib/memory/__stack_pointer
3097-
local.get 0ドル
3098-
i32.store
3099-
local.get 0ドル
3100-
i32.const 1
3101-
f64.const 42
3102-
f64.const 0
3103-
f64.const 0
3104-
f64.const 0
3105-
f64.const 0
3106-
call $~lib/builtins/trace
3107-
i32.const 160
3108-
local.set 0ドル
3109-
global.get $~lib/memory/__stack_pointer
3110-
local.get 0ドル
3111-
i32.store
3112-
local.get 0ドル
3113-
call $~lib/bindings/dom/console.log
3114-
global.get $~lib/bindings/dom/Math.E
3115-
call $~lib/bindings/dom/Math.log
3116-
drop
3117-
global.get $bindings/esm/immutableGlobal
3118-
drop
3119-
global.get $bindings/esm/immutableGlobalNested
3120-
drop
3121-
call $bindings/esm/Date_getTimezoneOffset
3122-
drop
3123-
global.get $~lib/memory/__stack_pointer
3124-
i32.const 4
3125-
i32.add
3126-
global.set $~lib/memory/__stack_pointer
3127-
)
31283105
(func $bindings/esm/bufferFunction (param $a i32) (param $b i32) (result i32)
31293106
(local $aByteLength i32)
31303107
(local $bByteLength i32)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /