Avoid hard coded uses of the name for the SDK runtime library. This
unblocks a more consistent name/rename logic for all dart libraries
when they are imported.
Change-Id: I4599006569ecae81a0526686467e06da9b335fc7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385188
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Nicholas Shahan <nshahan@google.com>
In https://github.com/flutter/engine/pull/54714 the "int value" that was used for storing the color values for a Flutter color was removed and replaced with `double red, double green` etc.
The color computer used the `value` field so this stopped it from computing any colors for previews in LSP clients. No tests broke because the tests here use a mock version of the Color class that still had `value`.
This change updates the mock Color class to match the new Flutter implementation, and updates the computer to use the red/green/blue doubles instead of parsing from an int.
It also adds support for the new `Color.from()` constructor that was also recently added.
Fixes https://github.com/Dart-Code/Dart-Code/issues/5289
Change-Id: I3ff20bda0cc848e028822cfcb5a14e6a8f6934d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386802
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Previously the implementation of this method was a stub.
It turns out that all the necessary infrastructure was in place
already, however the type arguments supplied by MiniAstOperations to
TypeAnalyzerOperationsMixin and TypeAnalyzerOperations needed to be
changed: in the "mini_ast" representation of types, an
InferableParameter is represented by a String, not a
PromotedTypeVariableType. This is because InferableParameter is meant
to represent the declaration of the type parameter
(StructuralParameter for the CFE, TypeParameterElement for the
analyzer), not the type itself. The types used for unit testing in
_fe_analyzer_shared don't have a separate notion of the declaration of
a type parameter, so we just use its name.
Implementing this logic required adding a method
`TypeSystem.matchTypeParameterType`, which checks if a Type is a type
parameter type, and returns the name of the type parameter if so. I
based this on the previously existing `TypeSystem._isTypeVar` method
(which performed the same job but did not return the type parameter
name).
I also took the liberty of fixing a flow analysis test that treated
`T` as a type variable but failed to mark it as a type variable by
calling `addTypeVariable`.
This should help pave the way for unit testing more of the shared
infrastructure for types.
Change-Id: Ia7a9777ec3d90a5886567dcb9f831e388e372f32
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386607
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
The (utf8) scanner currently has this thing where you give it a
0-terminated byte-array (i.e. you read the file, then allocate
something that's 1 bigger, copy the data, then give it to the scanner)
to 'avoid bounds checks'.
Dart still has bounds checks though - they're just implicit.
As for the string scanner ut gets a string, then creates a new string
like `string + '\x00'` - so basically the same thing.
This CL uses the 'vm:unsafe:no-bounds-checks' pragma, removing the
implicit bounds checks, adding explicit bounds checks,
saving ~73.6 mio instructions when compiling the CFE in the process:
```
Comparing snapshot #1 with snapshot #2
cycles:u: -0.9983% +/- 0.6563% (-174026333.30 +/- 114410028.98)
instructions:u: -0.3416% +/- 0.0005% (-73659267.00 +/- 108567.20)
branch-misses:u: -4.8952% +/- 2.2612% (-3172939.50 +/- 1465641.18)
```
With the scanner-benchmark with `--bytes` I get this:
```
msec task-clock:u: -1.2251% +/- 0.6355% (-50.64 +/- 26.27)
cycles:u: -1.2376% +/- 0.6385% (-223642830.80 +/- 115393789.68)
instructions:u: -2.8155% +/- 0.0000% (-1153243856.00 +/- 428.11)
seconds time elapsed: -1.2165% +/- 0.6408% (-0.05 +/- 0.03)
seconds user: -1.1539% +/- 0.6495% (-0.05 +/- 0.03)
```
With the scanner-benchmark with `--string` I get this:
```
msec task-clock:u: -7.6439% +/- 0.6628% (-366.08 +/- 31.74)
page-faults:u: -95.0034% +/- 0.0014% (-228023.50 +/- 3.41)
instructions:u: 2.1041% +/- 0.0000% (897941907.60 +/- 2082.79)
branch-misses:u: 3.2994% +/- 1.4675% (3239735.30 +/- 1440940.88)
seconds time elapsed: -7.6595% +/- 0.6610% (-0.37 +/- 0.03)
seconds user: -0.8801% +/- 0.7676% (-0.04 +/- 0.03)
seconds sys: -92.0140% +/- 2.8075% (-0.33 +/- 0.01)
MarkSweep( old space) goes from 6 to 0
Notice combined GC time goes from 112 ms to 41 ms (notice only 1 run each).
```
Where I'll note that the 'vm:unsafe:no-bounds-checks' pragma doesn't
(yet?) work for `String.codeUnitAt`.
See https://dart-review.googlesource.com/c/sdk/+/384540
(and https://dart-review.googlesource.com/c/sdk/+/385201) for details.
I assume the relatively big change here is caused by not allocating
a new string with a 0-byte in the end each time.
Note that the read-allocate-copy dance is still performed for the utf8
scanner in this CL as it requires changing all call-sites instead.
It will be done in a follow-up CL where the "end-of-file" int will
likely also be changed to `-1` to (I assume) allow for having the
0-byte in the middle of a file (see also the 10+ year old bug at
https://github.com/dart-lang/sdk/issues/18090)
Note: The pragma (currently?) only has effect in AOT and this change
will (for the utf8 scanner) make the JIT version slower
(probably by the same ~73.6 mio instructions as - at least in AOT -
the implicit check is 6 instructions and the explicit one is 3
instructions). As the pragma doesn't work in the StringScanner anyway
I expect the change to be somewhat equivalent there. Once the
read-allocate-copy dance is also removed from the utf8 scanner I expect
the combined result to be positive all around.
Update: With https://dart-review.googlesource.com/c/sdk/+/385201 landed
I get these changes:
Compiling the CFE:
```
instructions:u: -0.4520% +/- 0.0002% (-98470955.29 +/- 42253.40)
```
Scanner benchmark with `--bytes`:
```
msec task-clock:u: -2.1758% +/- 0.2316% (-92.07 +/- 9.80)
cycles:u: -2.1941% +/- 0.2283% (-405224983.11 +/- 42160655.88)
instructions:u: -3.1049% +/- 0.0000% (-1272360052.95 +/- 706.54)
branch-misses:u: 2.4718% +/- 0.5142% (2371345.23 +/- 493257.76)
seconds time elapsed: -2.1761% +/- 0.2317% (-0.09 +/- 0.01)
seconds user: -2.2071% +/- 0.2308% (-0.09 +/- 0.01)
```
Scanner benchmark with `--string`:
```
msec task-clock:u: -15.0073% +/- 0.2175% (-745.93 +/- 10.81)
page-faults:u: -95.0035% +/- 0.0003% (-228024.25 +/- 0.81)
cycles:u: -7.7986% +/- 0.2329% (-1558985588.99 +/- 46560962.79)
instructions:u: -3.7054% +/- 0.0000% (-1581977447.66 +/- 481.68)
branch-misses:u: -0.6880% +/- 0.5818% (-689453.22 +/- 583101.50)
seconds time elapsed: -15.0198% +/- 0.2170% (-0.75 +/- 0.01)
seconds user: -8.8149% +/- 0.2648% (-0.41 +/- 0.01)
seconds sys: -94.1247% +/- 1.6444% (-0.34 +/- 0.01)
MarkSweep( old space) goes from 6 to 0
```
Change-Id: I524a21f488da7df5dc9d2cdf40112b84896ad3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/383324
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Short explanation: For whatever reason, when using `identical` on `int`s
the ints are first boxed (`BoxInt64`) before being compared
(`StrictCompare`) whereas just doing `==` just does a compare
(`EqualityCompare`).
Results:
With the CFE compiling (a fixed version of) itself I get these results:
```
instructions:u: -0.5756% +/- 0.0003% (-124825401.80 +/- 64013.17)
```
i.e. almost 125 mio instructions saved.
Another run - with 100 iterations each - I get
```
msec task-clock:u: -0.4927% +/- 0.2585% (-20.85 +/- 10.94)
page-faults:u: 0.0174% +/- 0.0139% (18.80 +/- 15.00)
cycles:u: -0.5233% +/- 0.2683% (-91305451.82 +/- 46815747.30)
instructions:u: -0.5754% +/- 0.0002% (-124793061.49 +/- 37426.30)
branch-misses:u: -1.6903% +/- 1.1207% (-1091410.69 +/- 723627.04)
seconds time elapsed: -0.4863% +/- 0.2581% (-0.02 +/- 0.01)
seconds user: -0.4547% +/- 0.3253% (-0.02 +/- 0.01)
```
In the scanner benchmark with `--string` (i.e. using string scanner) I
get these results:
```
msec task-clock:u: -3.7992% +/- 0.3316% (-190.54 +/- 16.63)
cycles:u: -4.1423% +/- 0.3566% (-836808313.28 +/- 72033424.19)
instructions:u: -3.3524% +/- 0.0000% (-1480262370.08 +/- 828.58)
branch-misses:u: -1.7591% +/- 0.9582% (-1781144.28 +/- 970258.82)
seconds time elapsed: -3.7988% +/- 0.3303% (-0.19 +/- 0.02)
seconds user: -4.0211% +/- 0.4161% (-0.19 +/- 0.02)
```
(Just running the benchmark also sees the characters/µs go from ~93 to
~97).
In the scanner benchmark with `--bytes` (i.e. using the utf8 scanner) I
get these results:
```
msec task-clock:u: -4.2872% +/- 0.4467% (-185.64 +/- 19.34)
cycles:u: -4.2972% +/- 0.4382% (-812955454.92 +/- 82892232.23)
instructions:u: -3.4867% +/- 0.0000% (-1479744935.28 +/- 297.12)
seconds time elapsed: -4.2872% +/- 0.4470% (-0.19 +/- 0.02)
seconds user: -4.2204% +/- 0.4730% (-0.18 +/- 0.02)
```
(Just running the benchmark also sees the bytes/µs go from ~108 to ~113).
In both cases we notice how the actual time, cycles and instructions
agree pretty well.
Combining the data for the compile and the benchmark I assume this CL
actually reduces the runtime of the CFE compiling itself by a about
half a percent.
Change-Id: I67d056837240aef61b6707d02507ab4121b31715
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385940
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
E.g. we might do this
```
$ out/ReleaseX64/dart-sdk/bin/dart compile aot-snapshot pkg/_fe_analyzer_shared/test/scanner_benchmark.dart
Generated: /usr/local/google/home/jensj/code/dart-sdk/sdk/pkg/_fe_analyzer_shared/test/scanner_benchmark.aot
$ for type in --bytes --bytes0 --string --stringtobytes --count ; do out/ReleaseX64/dart-sdk/bin/dartaotruntime pkg/_fe_analyzer_shared/test/scanner_benchmark.aot pkg/kernel/lib/ast.dart $type; done
Scanned 466534 bytes 1000 times in 0:00:04.413011
Found errors 0 times
That's 105.71784208106438 bytes per microsecond
Scanned 466534 bytes 1000 times in 0:00:04.911947
Found errors 0 times
That's 94.97944501437007 bytes per microsecond
Scanned 466532 string characters 1000 times in 0:00:05.413169
Found errors 0 times
That's 86.18463602374136 string characters per microsecond
Scanned 466532 string characters as bytes 1000 times in 0:00:06.722731
Found errors 0 times
That's 69.39620222793386 string characters as bytes per microsecond
Scanned 466534 bytes 1000 times in 0:00:00.641854
Found errors 0 times
That's 726.8537704836302 bytes per microsecond
```
to see that scanning pre-0-at-the-end'ed bytes scan at ~105 bytes/µs,
doing a copy to add the 0 at then end, then parse bytes scan at ~95,
scanning strings runs at ~86, converting strings to bytes, then scanning
the bytes at ~69 and - for comparision - just running through the bytes
counting linebreaks runs at ~726.
The benchmark is also useful for comparing optimizations.
Change-Id: I67c12850505e7f712660fd353575e8c7a455f112
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385920
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Currently when the .wasm file path passed to run_wasm.js is a relative
path, `Uri.base` becomes something like `file://test.wasm`, which is not
a valid file URI, so it causes crashes in `Uri.toFilePath`.
When the file path is relative add a omit `file://` prefix.
`Uri.base` values before and after:
- Before, relative .wasm path: `file://test.wasm` (invalid)
- Before, absolute .wasm path: `file:///home/user/test.wasm`
- After, relative .wasm path: `test.wasm` (fixed)
- After, absolute .wasm path: `file:///home/user/test.wasm` (same as before)
Change-Id: I0d1c43716e07a9ee926e7feeeab514c2c66bac16
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385700
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Adds a mode that puts every library (outside of the SDK) into its own wasm module. Each module is then loaded before the program executes.
This allows us to get better coverage on multi-module logic.
I chose to augment the SDK `_invokeMain` entry point because it allows us to push the user-defined main into a second module ensuring we always have at least 2 modules. The SDK alone is then the main module and all user-code is in deferred modules.
The next step is to make a test configuration for this and decide what frequency to execute it with.
Change-Id: I01bf3a5fee4604a890ef376ebd35113281a36a5c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384404
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
- Declare dummy value globals as needed per module. We cannot share these across modules as they can be used in a const context which limits how we can reference them. The other option is to declare the dummy values for all heap types in the main module. However, declaring as needed per-module is more in line with our approach elsewhere and will work better for dynamic modules.
Change-Id: Ib2cd0a9300610ff8aa86d904902815d4fe9042d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385401
Reviewed-by: Martin Kustermann <kustermann@google.com>
This annotates each code location in wasm stacktraces with the name of the referenced module. By default v8 only includes an opaque hash to name each module.
For tests and debugging where we want to analyze stacktraces the opaque hash alone makes it impossible to associate each code location back to a file. With multiple modules we will need this additional information.
Change-Id: I464780d9234e0685d08f4f1925f65ce073b3f322
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385400
Reviewed-by: Martin Kustermann <kustermann@google.com>
This pushes the module branching to the specific functions used for closures. Rather than have separate ClosureRepresentation objects for each module, we have the representation create the functions it needs within each module on demand.
This duplicates some of the closure logic but it means each module (including main) only needs the representations relevant to it and we don't have to worry about module import ordering.
If there are no deferred imports (i.e. the program is 1 module) then this has no effect on the generated program. If there are deferred imports (i.e. multiple modules) they may contain duplicate closure representations which will increase total code size.
Change-Id: Ib9506e1f94866a4ae6de4472362bd5cd4260b1e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385182
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Follow up for https://dart-review.googlesource.com/c/sdk/+/381704
I think we don't need to canonicalize it at all, and pay for map lookup.
If stop doing this, we actually save memory.
My suspicion is that we use setter names transiently.
And removing a field itself save some memory.
Before:
flutter_elements
reachableObjects
count: 11865740
change: -0.01% -1335
size: 993783127 = 970491 KB = 947.7 MB
change: -0.01% -72336 = -70 KB
After:
flutter_elements
reachableObjects
count: 11861762
change: -0.04% -5313
size: 987428847 = 964285 KB = 941.7 MB
change: -0.65% -6426616 = -6275 KB = -6.1 MB
Change-Id: Iaab513e545862df53ae1f144a7a8b1e695768d06
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386261
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>