1*9880d681SAndroid Build Coastguard Worker============================== 2*9880d681SAndroid Build Coastguard WorkerFaultMaps and implicit checks 3*9880d681SAndroid Build Coastguard Worker============================== 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Worker.. contents:: 6*9880d681SAndroid Build Coastguard Worker :local: 7*9880d681SAndroid Build Coastguard Worker :depth: 2 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard WorkerMotivation 10*9880d681SAndroid Build Coastguard Worker========== 11*9880d681SAndroid Build Coastguard Worker 12*9880d681SAndroid Build Coastguard WorkerCode generated by managed language runtimes tend to have checks that 13*9880d681SAndroid Build Coastguard Workerare required for safety but never fail in practice. In such cases, it 14*9880d681SAndroid Build Coastguard Workeris profitable to make the non-failing case cheaper even if it makes 15*9880d681SAndroid Build Coastguard Workerthe failing case significantly more expensive. This asymmetry can be 16*9880d681SAndroid Build Coastguard Workerexploited by folding such safety checks into operations that can be 17*9880d681SAndroid Build Coastguard Workermade to fault reliably if the check would have failed, and recovering 18*9880d681SAndroid Build Coastguard Workerfrom such a fault by using a signal handler. 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard WorkerFor example, Java requires null checks on objects before they are read 21*9880d681SAndroid Build Coastguard Workerfrom or written to. If the object is ``null`` then a 22*9880d681SAndroid Build Coastguard Worker``NullPointerException`` has to be thrown, interrupting normal 23*9880d681SAndroid Build Coastguard Workerexecution. In practice, however, dereferencing a ``null`` pointer is 24*9880d681SAndroid Build Coastguard Workerextremely rare in well-behaved Java programs, and typically the null 25*9880d681SAndroid Build Coastguard Workercheck can be folded into a nearby memory operation that operates on 26*9880d681SAndroid Build Coastguard Workerthe same memory location. 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard WorkerThe Fault Map Section 29*9880d681SAndroid Build Coastguard Worker===================== 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard WorkerInformation about implicit checks generated by LLVM are put in a 32*9880d681SAndroid Build Coastguard Workerspecial "fault map" section. On Darwin this section is named 33*9880d681SAndroid Build Coastguard Worker``__llvm_faultmaps``. 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard WorkerThe format of this section is 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker.. code-block:: none 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Worker Header { 40*9880d681SAndroid Build Coastguard Worker uint8 : Fault Map Version (current version is 1) 41*9880d681SAndroid Build Coastguard Worker uint8 : Reserved (expected to be 0) 42*9880d681SAndroid Build Coastguard Worker uint16 : Reserved (expected to be 0) 43*9880d681SAndroid Build Coastguard Worker } 44*9880d681SAndroid Build Coastguard Worker uint32 : NumFunctions 45*9880d681SAndroid Build Coastguard Worker FunctionInfo[NumFunctions] { 46*9880d681SAndroid Build Coastguard Worker uint64 : FunctionAddress 47*9880d681SAndroid Build Coastguard Worker uint32 : NumFaultingPCs 48*9880d681SAndroid Build Coastguard Worker uint32 : Reserved (expected to be 0) 49*9880d681SAndroid Build Coastguard Worker FunctionFaultInfo[NumFaultingPCs] { 50*9880d681SAndroid Build Coastguard Worker uint32 : FaultKind = FaultMaps::FaultingLoad (only legal value currently) 51*9880d681SAndroid Build Coastguard Worker uint32 : FaultingPCOffset 52*9880d681SAndroid Build Coastguard Worker uint32 : HandlerPCOffset 53*9880d681SAndroid Build Coastguard Worker } 54*9880d681SAndroid Build Coastguard Worker } 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard WorkerThe ``ImplicitNullChecks`` pass 58*9880d681SAndroid Build Coastguard Worker=============================== 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard WorkerThe ``ImplicitNullChecks`` pass transforms explicit control flow for 61*9880d681SAndroid Build Coastguard Workerchecking if a pointer is ``null``, like: 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker.. code-block:: llvm 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker %ptr = call i32* @get_ptr() 66*9880d681SAndroid Build Coastguard Worker %ptr_is_null = icmp i32* %ptr, null 67*9880d681SAndroid Build Coastguard Worker br i1 %ptr_is_null, label %is_null, label %not_null, !make.implicit !0 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker not_null: 70*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %ptr 71*9880d681SAndroid Build Coastguard Worker br label %do_something_with_t 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker is_null: 74*9880d681SAndroid Build Coastguard Worker call void @HFC() 75*9880d681SAndroid Build Coastguard Worker unreachable 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Worker !0 = !{} 78*9880d681SAndroid Build Coastguard Worker 79*9880d681SAndroid Build Coastguard Workerto control flow implicit in the instruction loading or storing through 80*9880d681SAndroid Build Coastguard Workerthe pointer being null checked: 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker.. code-block:: llvm 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker %ptr = call i32* @get_ptr() 85*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %ptr ;; handler-pc = label %is_null 86*9880d681SAndroid Build Coastguard Worker br label %do_something_with_t 87*9880d681SAndroid Build Coastguard Worker 88*9880d681SAndroid Build Coastguard Worker is_null: 89*9880d681SAndroid Build Coastguard Worker call void @HFC() 90*9880d681SAndroid Build Coastguard Worker unreachable 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard WorkerThis transform happens at the ``MachineInstr`` level, not the LLVM IR 93*9880d681SAndroid Build Coastguard Workerlevel (so the above example is only representative, not literal). The 94*9880d681SAndroid Build Coastguard Worker``ImplicitNullChecks`` pass runs during codegen, if 95*9880d681SAndroid Build Coastguard Worker``-enable-implicit-null-checks`` is passed to ``llc``. 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard WorkerThe ``ImplicitNullChecks`` pass adds entries to the 98*9880d681SAndroid Build Coastguard Worker``__llvm_faultmaps`` section described above as needed. 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker``make.implicit`` metadata 101*9880d681SAndroid Build Coastguard Worker-------------------------- 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard WorkerMaking null checks implicit is an aggressive optimization, and it can 104*9880d681SAndroid Build Coastguard Workerbe a net performance pessimization if too many memory operations end 105*9880d681SAndroid Build Coastguard Workerup faulting because of it. A language runtime typically needs to 106*9880d681SAndroid Build Coastguard Workerensure that only a negligible number of implicit null checks actually 107*9880d681SAndroid Build Coastguard Workerfault once the application has reached a steady state. A standard way 108*9880d681SAndroid Build Coastguard Workerof doing this is by healing failed implicit null checks into explicit 109*9880d681SAndroid Build Coastguard Workernull checks via code patching or recompilation. It follows that there 110*9880d681SAndroid Build Coastguard Workerare two requirements an explicit null check needs to satisfy for it to 111*9880d681SAndroid Build Coastguard Workerbe profitable to convert it to an implicit null check: 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker 1. The case where the pointer is actually null (i.e. the "failing" 114*9880d681SAndroid Build Coastguard Worker case) is extremely rare. 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker 2. The failing path heals the implicit null check into an explicit 117*9880d681SAndroid Build Coastguard Worker null check so that the application does not repeatedly page 118*9880d681SAndroid Build Coastguard Worker fault. 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard WorkerThe frontend is expected to mark branches that satisfy (1) and (2) 121*9880d681SAndroid Build Coastguard Workerusing a ``!make.implicit`` metadata node (the actual content of the 122*9880d681SAndroid Build Coastguard Workermetadata node is ignored). Only branches that are marked with 123*9880d681SAndroid Build Coastguard Worker``!make.implicit`` metadata are considered as candidates for 124*9880d681SAndroid Build Coastguard Workerconversion into implicit null checks. 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker(Note that while we could deal with (1) using profiling data, dealing 127*9880d681SAndroid Build Coastguard Workerwith (2) requires some information not present in branch profiles.) 128