Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making the OCaml compiler more friendly to Js_of_ocaml #117

Open
6 of 7 tasks
vouillon opened this issue Mar 20, 2014 · 24 comments
Open
6 of 7 tasks

Making the OCaml compiler more friendly to Js_of_ocaml #117

vouillon opened this issue Mar 20, 2014 · 24 comments

Comments

@vouillon
Copy link
Member

vouillon commented Mar 20, 2014

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
Copy link
Member

hhugo commented Mar 20, 2014

One more PR that might break js_of_ocaml. see comment ocaml/ocaml#14 (comment)

@hhugo
Copy link
Member

hhugo commented Mar 20, 2014

What about more debug (event) information ?

@vouillon
Copy link
Member Author

What do you mean?

@hhugo
Copy link
Member

hhugo commented Mar 20, 2014

could we improve sourcemap generation with more debug information ?

@vouillon
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member

hhugo commented Apr 1, 2014

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

@hhugo
Copy link
Member

hhugo commented Apr 9, 2014

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

  • Sys.max_array_length
  • Sys.int_size (new)

@hhugo
Copy link
Member

hhugo commented Apr 15, 2014

ocaml/ocaml#37

@hhugo
Copy link
Member

hhugo commented Apr 15, 2014

ocaml/ocaml#36

@vouillon
Copy link
Member Author

vouillon commented Sep 24, 2014

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

@vouillon
Copy link
Member Author

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
Copy link
Member Author

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
Copy link
Member

hhugo commented Sep 25, 2014

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

@hhugo
Copy link
Member

hhugo commented Sep 26, 2014

@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
Copy link
Member Author

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
Copy link
Member

hhugo commented Sep 26, 2014

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
Copy link
Member Author

Which JavaScript engine did you try? Which version?

@bobzhang
Copy link
Contributor

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
Copy link
Member Author

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
Copy link
Member

hhugo commented May 3, 2020

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
Copy link
Member

hhugo commented Sep 22, 2021

de implementation of CamlinternalMod by a JavaScript implementation.

This is now gone

@hhugo
Copy link
Member

hhugo commented Dec 9, 2024

x-links: #1745 #1721 ocaml/ocaml#13438

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants