On Wed, Oct 12, 2011 at 17:01, Duane Sand <duane....@gmail.com> wrote:
Are the underlying semantics of the Dart and Ecmascript languages
close enough that both can be efficiently implemented in a single V8-
style virtual machine? Or are there differences which pragmatically
mean that getting the best performance for each will require separate
implementations?
For best performance one definitely needs separate implementations. Just three very small examples (there are hundreds more):1. in JS it is possible to replace global functions. If I want to inline such a function I also need to compile a check that the inlined function is still the same. In Dart it is not possible to change static function. Inlining thus becomes faster.
2. in JS all numbers are doubles. In dart there are integers and doubles. Under the hood a JS (V8-like) VM optimizes for integers too, but needs to keep in mind that a double can only represent 53bits of integers efficiently. This leads to the strange situation that on 64-bit machines only 32bit of integers are optimized.A Dart VM can go up to 63 bits (before switching to big integers).3. A JS VM needs to guess the class description of objects (it does this using "hidden classes"). That is it assigns a guessed class-description to every object it sees. This is much less efficient than having the description given to it as part of the source-code.
// florian
On 10/12/2011 07:32 PM, Florian Loitsch wrote:The JVM is able to optimize this case :)On Wed, Oct 12, 2011 at 17:01, Duane Sand <duane....@gmail.com> wrote:
Are the underlying semantics of the Dart and Ecmascript languages
close enough that both can be efficiently implemented in a single V8-
style virtual machine? Or are there differences which pragmatically
mean that getting the best performance for each will require separate
implementations?
For best performance one definitely needs separate implementations. Just three very small examples (there are hundreds more):1. in JS it is possible to replace global functions. If I want to inline such a function I also need to compile a check that the inlined function is still the same. In Dart it is not possible to change static function. Inlining thus becomes faster.
The interpreter does the check but the JIT remove the check and install a dependency
to invalidate the generated assembler code if the global function is changed and
deopt back to the interpreter.
I think cranksaft is able to do this kind of deopt.
Rémi
2. in JS all numbers are doubles. In dart there are integers and doubles. Under the hood a JS (V8-like) VM optimizes for integers too, but needs to keep in mind that a double can only represent 53bits of integers efficiently. This leads to the strange situation that on 64-bit machines only 32bit of integers are optimized.A Dart VM can go up to 63 bits (before switching to big integers).3. A JS VM needs to guess the class description of objects (it does this using "hidden classes"). That is it assigns a guessed class-description to every object it sees. This is much less efficient than having the description given to it as part of the source-code.
// florian
On Wed, Oct 12, 2011 at 20:11, Rémi Forax <fo...@univ-mlv.fr> wrote:
On 10/12/2011 07:32 PM, Florian Loitsch wrote:The JVM is able to optimize this case :)On Wed, Oct 12, 2011 at 17:01, Duane Sand <duane....@gmail.com> wrote:
Are the underlying semantics of the Dart and Ecmascript languages
close enough that both can be efficiently implemented in a single V8-
style virtual machine? Or are there differences which pragmatically
mean that getting the best performance for each will require separate
implementations?
For best performance one definitely needs separate implementations. Just three very small examples (there are hundreds more):1. in JS it is possible to replace global functions. If I want to inline such a function I also need to compile a check that the inlined function is still the same. In Dart it is not possible to change static function. Inlining thus becomes faster.
The interpreter does the check but the JIT remove the check and install a dependency
to invalidate the generated assembler code if the global function is changed and
deopt back to the interpreter.
Class changes are extremely rare in the JVM.
I think cranksaft is able to do this kind of deopt.Crankshaft checks at every access unless it just did the check and knows that nothing could have changed in the mean-time. Typically calling another function invalidates all assumptions.
// florian
Or this optimization for 33..63 bit integers could be dropped from
both,
as a rarely profitable trick. (Was this motivated by Uint32Arrays?)
Yes. That difference particularly applies during the initial runs of
> 3. A JS VM needs to guess the class description of objects (it does this
> using "hidden classes"). That is it assigns a guessed class-description to
> every object it sees. This is much less efficient than having the
> description given to it as part of the source-code.
a function, before either V8 or dartvm recompiles hot functions with their
optimizing code generator. Perhaps things are less different, during
optimization and during execution of the optimized code?
I thought Dart can express the case where a named object has unpredicted type and hence unknown class description. In those cases, the dart vm will either
need to do the slow symbol table lookups every time, or apply the same class discovery and cached binding methods as V8.
>
> // florian
>
> --
> Give a man a fire and he's warm for the whole day,
> but set fire to him and he's warm for the rest of his life. - Terry
> Pratchett