Summary: Currently there is a direct cycle of dependencies Var -> Trm -> Var. Inside Trm, these two modules are defined as mutually recursive modules, so at some level this is ok. Due to internals of how recursive modules are compiled, recursive modules that are "unsafe" (that is, export some value of non-function type) are compiled more efficiently. This diff moves Var from being defined recursively with Trm to being a submodule of Trm. This eliminates that Var -> Trm -> Var cycle and enables making Trm an "unsafe" module. (Trm is still mutually recursive with Arith (and Arith0), but they are "safe".) The difference between how "safe" and "unsafe" recursive modules are compiled, in this context, is that the safe ones are first initialized to a block containing dummy function closures that immediately raise, then the unsafe ones are initialized as normal modules, and then the safe ones are back-patched. A consequence of this is that calls to functions in safe recursive modules are "unknown" calls, and they are implemented as loading from a pointer to a closure and calling the generic caml_apply function. In contrast, calls to functions in normal or "unsafe" modules can be known, and get compiled to direct assembly calls to the statically resolved callee. The second case is faster. Additionally, in the indirect case, the callee is unknown, and so some register spilling and restoring is also potentially involved. Normally (I guess), this difference in performance is not significant, but it can be significant for e.g. compare or hash functions of modules used as container keys / elements, where the container data structure is very hot. Reviewed By: ngorogiannis Differential Revision: D26250517 fbshipit-source-id: ecef49b32master
parent
781280faf1
commit
6ecdb72fcc
Loading…
Reference in new issue