ocsigen / js_of_ocaml

Compiler from OCaml to Javascript.
http://ocsigen.org/js_of_ocaml/
Other
943 stars 185 forks source link

Making the OCaml compiler more friendly to Js_of_ocaml #117

Open vouillon opened 10 years ago

vouillon commented 10 years ago

I have recently proposed to change the definition of Pervasives.min/max_int so that Js_of_ocaml does not have to patch the bytecode (ocaml/ocaml#19). I'm wondering what other changes we could propose that would be useful to Js_of_ocaml.

hhugo commented 10 years ago

One more PR that might break js_of_ocaml. see comment https://github.com/ocaml/ocaml/pull/14#issuecomment-35822033

hhugo commented 10 years ago

What about more debug (event) information ?

vouillon commented 10 years ago

What do you mean?

hhugo commented 10 years ago

could we improve sourcemap generation with more debug information ?

vouillon commented 10 years ago

Do you have anything specific in mind? I would say we already have all the needed information: for code with debugg information, we should be able to associate to any bytecode instruction a corresponding location in the source code.

vouillon commented 10 years ago

Code like let rec f x y = 1 and z = Some (f, h) is compiled using primitive caml_alloc_dummy to allocate a block (for all values but floats, including closures), then caml_update_dummy to fill the block with its actual contents. So we have a hack in Js_of_ocaml to be able to use a block (a JavaScript array), as if it was a function.

It would be better if a specific primitive caml_alloc_dummy_closure was used to allocate dummy closures. Even better, this primitive could be given the arity of the closure. Then, we could compile a primitive call caml_alloc_dummy_function(2) into a function function f(x,y) {return f.fun(x,y); } which does not need any specific runtime support.

vouillon commented 10 years ago

I'm wondering whether we could do something for recursive modules as well. At the moment, we have a hack that replaces the bytecode implementation of CamlinternalMod by a JavaScript implementation.

hhugo commented 10 years ago

caml_alloc_dummy_closure => https://github.com/hhugo/ocaml/compare/jsoo_friendly

hhugo commented 10 years ago

limits due to runtime representation should/could be set from the runtime.

hhugo commented 10 years ago

https://github.com/ocaml/ocaml/pull/37

hhugo commented 10 years ago

https://github.com/ocaml/ocaml/pull/36

vouillon commented 9 years ago

If String.copy and (^) were implemented as primitive, we could more easily generate efficient code for them.

vouillon commented 9 years ago

OCaml is switching to immutable strings. However, as they are implemented imperatively, based on byte sequence operations, there does not seem to be any easy way to take advantage of this.

vouillon commented 9 years ago

We should probably map OCaml values to JavaScript objects rather than JavaScript arrays. Indeed, this is more memory efficient (V8 has a high overhead for arrays; the block tag would not need to be stored in the object) and potentially faster (no need for bound check when accessing fields).

However, the same bytecode instruction MAKEBLOCK is used for allocating both arrays and blocks.

hhugo commented 9 years ago

How would you compile OCaml value to Js Object ? One constructor per tag and size couple ?

hhugo commented 9 years ago

@vouillon, a quick experiment with compiling ocaml blocks to Js objects shows poor performances. x2.5 slower on @jordwalke example.

(deriving and marshall not updated) https://github.com/ocsigen/js_of_ocaml/tree/caml_block https://github.com/hhugo/ocaml/tree/make_array

vouillon commented 9 years ago

This is because you are using numeric fields. Here is what I get by manually tweaking the JavaScript output:

Arrays Objects (numeric fields) Objects (non-numeric fields)
V8 180 500 125
JSC 86 150 83
Spidermonkey 170 300 82
hhugo commented 9 years ago

I've update the code (regression inside) to use non-numeric fields. It's better but still a little bit slower than the current implem.

vouillon commented 9 years ago

Which JavaScript engine did you try? Which version?

bobzhang commented 8 years ago

this is very interesting discussion, @vouillon , how did you get such numbers? btw, it is not always correct to compile blocks and arrays differently, since some internal hacks of the compiler treat array and object in a uniform way

vouillon commented 8 years ago

That's the timings for a single program, that I manually rewrote.

You're right that for making this work the OCaml compiler would have to be modified.

hhugo commented 4 years ago

If String.copy and (^) were implemented as primitive, we could more easily generate efficient code for them.

I believe we are now closer to optimize theses string operations (xlink #977 #976 #924)

hhugo commented 2 years ago

de implementation of CamlinternalMod by a JavaScript implementation.

This is now gone