Avoid hh_get producing temporary strings on local heaps
commit438b54f98e0f85f0ed59e9921dd4f7ccb83fcab9
authorAndrew Kennedy <akenn@fb.com>
Tue, 12 Jul 2016 08:39:36 +0000 (12 01:39 -0700)
committerHhvm Bot <hhvm-bot-bot@fb.com>
Tue, 12 Jul 2016 08:45:59 +0000 (12 01:45 -0700)
treedad51541b383aff7b2eeb0a89f484b5625a24e89
parent84532d51b1c390397becced74a2cb0223e8bc0dc
Avoid hh_get producing temporary strings on local heaps

Summary:
Maps in the shared heap (implemented in hh_shared.c and sharedMem.ml) currently work as follows.

* To add a value to a map, the value is first serialized to a string (in Serial.make), using Caml's Marshal.to_string. Space is then allocated in the shared heap, and the contents of the string are copied across (in hh_store_ocaml).
* To get a value from a map, space is allocated for a string, and the bytes copied across from the shared heap (in hh_get). The string is the deserialized to a value (in Serial.get), using Caml's Marshal.from_string.

For "get", we don't need to create a string and then deserialize (the string is immediately garbage). Instead, we can use the native caml_input_value_from_block to deserialize directly from the shared heap. We save on garbage (although it would never leave the minor generation), and on allocation and copying costs.

[Not in this diff: for "add", it's not so clear what can be done, as we don't know ahead of time how much space to allocate. The Caml code for marshalling creates a sequence of fixed-size blocks using malloc, then creates the string off these, but we don't have control over this, and we're not using malloc, instead rolling our own allocator in hh_shared. But it might be worth looking at in the future.]

Reviewed By: gabelevi, dlreeves

Differential Revision: D3456769

fbshipit-source-id: 1e5399a91db405dce5d230de373802ef88cc9d5a
hphp/hack/src/heap/hh_shared.c
hphp/hack/src/heap/sharedMem.ml