1*03ce13f7SAndroid Build Coastguard WorkerObject allocation and lifetime in ICE 2*03ce13f7SAndroid Build Coastguard Worker===================================== 3*03ce13f7SAndroid Build Coastguard Worker 4*03ce13f7SAndroid Build Coastguard WorkerThis document discusses object lifetime and scoping issues, starting with 5*03ce13f7SAndroid Build Coastguard Workerbitcode parsing and ending with ELF file emission. 6*03ce13f7SAndroid Build Coastguard Worker 7*03ce13f7SAndroid Build Coastguard WorkerMultithreaded translation model 8*03ce13f7SAndroid Build Coastguard Worker------------------------------- 9*03ce13f7SAndroid Build Coastguard Worker 10*03ce13f7SAndroid Build Coastguard WorkerA single thread is responsible for parsing PNaCl bitcode (possibly concurrently 11*03ce13f7SAndroid Build Coastguard Workerwith downloading the bitcode file) and constructing the initial high-level ICE. 12*03ce13f7SAndroid Build Coastguard WorkerThe result is a queue of Cfg pointers. The parser thread incrementally adds a 13*03ce13f7SAndroid Build Coastguard WorkerCfg pointer to the queue after the Cfg is created, and then moves on to parse 14*03ce13f7SAndroid Build Coastguard Workerthe next function. 15*03ce13f7SAndroid Build Coastguard Worker 16*03ce13f7SAndroid Build Coastguard WorkerMultiple translation worker threads draw from the queue of Cfg pointers as they 17*03ce13f7SAndroid Build Coastguard Workerare added to the queue, such that several functions can be translated in parallel. 18*03ce13f7SAndroid Build Coastguard WorkerThe result is a queue of assembler buffers, each of which consists of machine code 19*03ce13f7SAndroid Build Coastguard Workerplus fixups. 20*03ce13f7SAndroid Build Coastguard Worker 21*03ce13f7SAndroid Build Coastguard WorkerA single thread is responsible for writing the assembler buffers to an ELF file. 22*03ce13f7SAndroid Build Coastguard WorkerIt consumes the assembler buffers from the queue that the translation threads 23*03ce13f7SAndroid Build Coastguard Workerwrite to. 24*03ce13f7SAndroid Build Coastguard Worker 25*03ce13f7SAndroid Build Coastguard WorkerThis means that Cfgs are created by the parser thread and destroyed by the 26*03ce13f7SAndroid Build Coastguard Workertranslation thread (including Cfg nodes, instructions, and most kinds of 27*03ce13f7SAndroid Build Coastguard Workeroperands), and assembler buffers are created by the translation thread and 28*03ce13f7SAndroid Build Coastguard Workerdestroyed by the writer thread. 29*03ce13f7SAndroid Build Coastguard Worker 30*03ce13f7SAndroid Build Coastguard WorkerDeterministic execution 31*03ce13f7SAndroid Build Coastguard Worker^^^^^^^^^^^^^^^^^^^^^^^ 32*03ce13f7SAndroid Build Coastguard Worker 33*03ce13f7SAndroid Build Coastguard WorkerAlthough code randomization is a key aspect of security, deterministic and 34*03ce13f7SAndroid Build Coastguard Workerrepeatable translation is sometimes needed, e.g. for regression testing. 35*03ce13f7SAndroid Build Coastguard WorkerMultithreaded translation introduces potential for randomness that may need to 36*03ce13f7SAndroid Build Coastguard Workerbe made deterministic. 37*03ce13f7SAndroid Build Coastguard Worker 38*03ce13f7SAndroid Build Coastguard Worker* Bitcode parsing is sequential, so it's easy to use a FIFO queue to keep the 39*03ce13f7SAndroid Build Coastguard Worker translation queue in deterministic order. But since translation is 40*03ce13f7SAndroid Build Coastguard Worker multithreaded, FIFO order for the assembler buffer queue may not be 41*03ce13f7SAndroid Build Coastguard Worker deterministic. The writer thread would be responsible for reordering the 42*03ce13f7SAndroid Build Coastguard Worker buffers, potentially waiting for slower translations to complete even if other 43*03ce13f7SAndroid Build Coastguard Worker assembler buffers are available. 44*03ce13f7SAndroid Build Coastguard Worker 45*03ce13f7SAndroid Build Coastguard Worker* Different translation threads may add new constant pool entries at different 46*03ce13f7SAndroid Build Coastguard Worker times. Some constant pool entries are emitted as read-only data. This 47*03ce13f7SAndroid Build Coastguard Worker includes floating-point constants for x86, as well as integer immediate 48*03ce13f7SAndroid Build Coastguard Worker randomization through constant pooling. These constant pool entries are 49*03ce13f7SAndroid Build Coastguard Worker emitted after all assembler buffers have been written. The writer needs to be 50*03ce13f7SAndroid Build Coastguard Worker able to sort them deterministically before emitting them. 51*03ce13f7SAndroid Build Coastguard Worker 52*03ce13f7SAndroid Build Coastguard WorkerObject lifetimes 53*03ce13f7SAndroid Build Coastguard Worker---------------- 54*03ce13f7SAndroid Build Coastguard Worker 55*03ce13f7SAndroid Build Coastguard WorkerObjects of type Constant, or a subclass of Constant, are pooled globally. The 56*03ce13f7SAndroid Build Coastguard Workerpooling is managed by the GlobalContext class. Since Constants are added or 57*03ce13f7SAndroid Build Coastguard Workerlooked up by translation threads and the parser thread, access to the constant 58*03ce13f7SAndroid Build Coastguard Workerpools, as well as GlobalContext in general, need to be arbitrated by locks. 59*03ce13f7SAndroid Build Coastguard Worker(It's possible that if there's too much contention, we can maintain a 60*03ce13f7SAndroid Build Coastguard Workerthread-local cache for Constant pool lookups.) Constants live across all 61*03ce13f7SAndroid Build Coastguard Workerfunction translations, and are destroyed only at the end. 62*03ce13f7SAndroid Build Coastguard Worker 63*03ce13f7SAndroid Build Coastguard WorkerSeveral object types are scoped within the lifetime of the Cfg. These include 64*03ce13f7SAndroid Build Coastguard WorkerCfgNode, Inst, Variable, and any target-specific subclasses of Inst and Operand. 65*03ce13f7SAndroid Build Coastguard WorkerWhen the Cfg is destroyed, these scoped objects are destroyed as well. To keep 66*03ce13f7SAndroid Build Coastguard Workerthis cheap, the Cfg includes a slab allocator from which these objects are 67*03ce13f7SAndroid Build Coastguard Workerallocated, and the objects should not contain fields with non-trivial 68*03ce13f7SAndroid Build Coastguard Workerdestructors. Most of these fields are POD, but in a couple of cases these 69*03ce13f7SAndroid Build Coastguard Workerfields are STL containers. We deal with this, and avoid leaking memory, by 70*03ce13f7SAndroid Build Coastguard Workerproviding the container with an allocator that uses the Cfg-local slab 71*03ce13f7SAndroid Build Coastguard Workerallocator. Since the container allocator generally needs to be stateless, we 72*03ce13f7SAndroid Build Coastguard Workerstore a pointer to the slab allocator in thread-local storage (TLS). This is 73*03ce13f7SAndroid Build Coastguard Workerstraightforward since on any of the threads, only one Cfg is active at a time, 74*03ce13f7SAndroid Build Coastguard Workerand a given Cfg is only active in one thread at a time (either the parser 75*03ce13f7SAndroid Build Coastguard Workerthread, or at most one translation thread, or the writer thread). 76*03ce13f7SAndroid Build Coastguard Worker 77*03ce13f7SAndroid Build Coastguard WorkerEven though there is a one-to-one correspondence between Cfgs and assembler 78*03ce13f7SAndroid Build Coastguard Workerbuffers, they need to use different allocators. This is because the translation 79*03ce13f7SAndroid Build Coastguard Workerthread wants to destroy the Cfg and reclaim all its memory after translation 80*03ce13f7SAndroid Build Coastguard Workercompletes, but possibly before the assembly buffer is written to the ELF file. 81*03ce13f7SAndroid Build Coastguard WorkerOwnership of the assembler buffer and its allocator are transferred to the 82*03ce13f7SAndroid Build Coastguard Workerwriter thread after translation completes, similar to the way ownership of the 83*03ce13f7SAndroid Build Coastguard WorkerCfg and its allocator are transferred to the translation thread after parsing 84*03ce13f7SAndroid Build Coastguard Workercompletes. 85*03ce13f7SAndroid Build Coastguard Worker 86*03ce13f7SAndroid Build Coastguard WorkerAllocators and TLS 87*03ce13f7SAndroid Build Coastguard Worker------------------ 88*03ce13f7SAndroid Build Coastguard Worker 89*03ce13f7SAndroid Build Coastguard WorkerPart of the Cfg building, and transformations on the Cfg, include STL container 90*03ce13f7SAndroid Build Coastguard Workeroperations which may need to allocate additional memory in a stateless fashion. 91*03ce13f7SAndroid Build Coastguard WorkerThis requires maintaining the proper slab allocator pointer in TLS. 92*03ce13f7SAndroid Build Coastguard Worker 93*03ce13f7SAndroid Build Coastguard WorkerWhen the parser thread creates a new Cfg object, it puts a pointer to the Cfg's 94*03ce13f7SAndroid Build Coastguard Workerslab allocator into its own TLS. This is used as the Cfg is built within the 95*03ce13f7SAndroid Build Coastguard Workerparser thread. After the Cfg is built, the parser thread clears its allocator 96*03ce13f7SAndroid Build Coastguard Workerpointer, adds the new Cfg pointer to the translation queue, continues with the 97*03ce13f7SAndroid Build Coastguard Workernext function. 98*03ce13f7SAndroid Build Coastguard Worker 99*03ce13f7SAndroid Build Coastguard WorkerWhen the translation thread grabs a new Cfg pointer, it installs the Cfg's slab 100*03ce13f7SAndroid Build Coastguard Workerallocator into its TLS and translates the function. When generating the 101*03ce13f7SAndroid Build Coastguard Workerassembly buffer, it must take care not to use the Cfg's slab allocator. If 102*03ce13f7SAndroid Build Coastguard Workerthere is a slab allocator for the assembler buffer, a pointer to it can also be 103*03ce13f7SAndroid Build Coastguard Workerinstalled in TLS if needed. 104*03ce13f7SAndroid Build Coastguard Worker 105*03ce13f7SAndroid Build Coastguard WorkerThe translation thread destroys the Cfg when it is done translating, including 106*03ce13f7SAndroid Build Coastguard Workerthe Cfg's slab allocator, and clears the allocator pointer from its TLS. 107*03ce13f7SAndroid Build Coastguard WorkerLikewise, the writer thread destroys the assembler buffer when it is finished 108*03ce13f7SAndroid Build Coastguard Workerwith it. 109*03ce13f7SAndroid Build Coastguard Worker 110*03ce13f7SAndroid Build Coastguard WorkerThread safety 111*03ce13f7SAndroid Build Coastguard Worker------------- 112*03ce13f7SAndroid Build Coastguard Worker 113*03ce13f7SAndroid Build Coastguard WorkerThe parse/translate/write stages of the translation pipeline are fairly 114*03ce13f7SAndroid Build Coastguard Workerindependent, with little opportunity for threads to interfere. The Subzero 115*03ce13f7SAndroid Build Coastguard Workerdesign calls for all shared accesses to go through the GlobalContext, which adds 116*03ce13f7SAndroid Build Coastguard Workerlocking as appropriate. This includes the coarse-grain work queues for Cfgs and 117*03ce13f7SAndroid Build Coastguard Workerassembler buffers. It also includes finer-grain access to constant pool 118*03ce13f7SAndroid Build Coastguard Workerentries, as well as output streams for verbose debugging output. 119*03ce13f7SAndroid Build Coastguard Worker 120*03ce13f7SAndroid Build Coastguard WorkerIf locked access to constant pools becomes a bottleneck, we can investigate 121*03ce13f7SAndroid Build Coastguard Workerthread-local caches of constants (as mentioned earlier). Also, it should be 122*03ce13f7SAndroid Build Coastguard Workersafe though slightly less efficient to allow duplicate copies of constants 123*03ce13f7SAndroid Build Coastguard Workeracross threads (which could be de-dupped by the writer at the end). 124*03ce13f7SAndroid Build Coastguard Worker 125*03ce13f7SAndroid Build Coastguard WorkerWe will use ThreadSanitizer as a way to detect potential data races in the 126*03ce13f7SAndroid Build Coastguard Workerimplementation. 127