Add bespoke support for APC
Summary:
Support layout profiling for all static and uncounted arrays in APC. We key the profile of an APC dicts by a hash of the dict's keys. Doing so causes us to assign the same layout to all dicts with the same struct-like shape.
We profile an APC array on fetch. Note that we count a fetch as a sample for every subarray reachable from the root array that we're returning, because we don't have a later opportunity to make the sampling decision. That's why, when we first store the array in APC, we need two copies: a deeply-vanilla version, and a deeply-logging one. To help us build these variants, we have a core mapping helper, "makeAPCBespoke", which applies a given layout-selection mode to every array recursively contained within the root.
The core of this diff is the implementation of makeAPCBespoke. It's quite tricky, because we want to share as many subarrays between different results as possible, and we also want it to be decently fast. We specialize this helper on each vanilla array input type. We can assume for performance that almost all arrays being processed here are vanilla arrays, but we can't assume that for correctness; instead, we escalate bespoke arrays before passing them to the specialized helper. There are a variety of tricks we have to play to sample the behavior of logging array results here correctly - see inline comments.
Reviewed By: colavitam
Differential Revision:
D27899293
fbshipit-source-id:
f1528f79bd729d146e0564331ddae5cfc3fd2cf1