Dart VM FFI Vision
Background
The aim of Dart FFI project (tracked as Issue #34452) is to provide a low boilerplate, low ceremony & low overhead way of interoperating with native C/C++ code.
The motivation behind this project is twofold:
The aim of Dart FFI project (tracked as Issue #34452) is to provide a low boilerplate, low ceremony & low overhead way of interoperating with native C/C++ code.
The motivation behind this project is twofold:
There are two types (actually more, but for the problem at hand only these two are important):
flat strings are immutable arrays of characters
cons strings are pairs of strings, result of concatenation.
If you concat a and b you get a cons-string (a, b)
that represents result of concatenation. If you later concat d
to that you get another cons-string ((a, b), d)
.
Indexing into such a "tree-like" string is not O(1) so to make it faster V8 flattens the string when you index: copies all characters into a flat string.
new Fn(...)
vs Object.create(P)
Each JavaScript object in V8 looks like this
+-------+
| map | -> pointer to the hidden class
+-------+
Lets imagine we have forEach
method. The core loop of this method in V8 is implemented in JavaScript and looks like this:
for (var i = 0; i < length; i++) {
if (i in array) {
var element = array[i];
%_CallFunction(receiver, element, i, array, f);
}
// Based on Martin Kustermann's version and adding support for | |
// finalization of memory mapped views. | |
import 'dart:ffi'; | |
import 'dart:io'; | |
import 'dart:typed_data'; | |
import 'dart:math' as math; | |
import 'package:ffi/ffi.dart'; | |
library mirrors.src.decode; | |
import 'dart:mirrors' as mirrors; | |
import 'dart:convert'; | |
/// Create an object of the given type [t] from the given JSON string. | |
decode(String json, Type t) { | |
// Get deserialization descriptor for the given type. | |
// This descriptor describes how to handle the type and all its fields. | |
final TypeDesc desc = getDesc(t); |
void main() { | |
final count = 1000000; | |
final names = ['good', 'bad', 'whatever']; | |
final tests = [_test1, _test2, _test3]; | |
final sw = Stopwatch(); | |
var repeat = 10; | |
sw.start(); | |
while (repeat-- > 0) { | |
for (var i = 0; i < tests.length; i++) { | |
final name = names[i]; |
library writer; | |
import 'dart:typed_data'; | |
/// Writer wraps a fixed size Uint8List and writes values into it using | |
/// big-endian byte order. | |
class Writer { | |
/// Output buffer. | |
final Uint8List out; |
$ cat test.js | |
function foo () { while (true) { } } | |
function bar () { return foo(); } | |
bar(); | |
$ node test.js & | |
$ gdb attach $(pidof node) | |
0x00000bf778c63d5f in ?? () | |
(gdb) b v8::internal::Runtime_StackGuard | |
Breakpoint 1 at 0x84a1f0 | |
(gdb) print 'v8::V8::TerminateExecution'(0) |
+------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+ | |
| Library | Method | Diff (Bytes) | | |
+------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------+--------------+ |