首页 > 代码库 > android art JNI函数的调用代码及生成过程

android art JNI函数的调用代码及生成过程

JNI函数的调用

 

我们使用的测试Java代码如下:

packagecom.example.testar;

 

 

importjava.lang.reflect.Method;

 

 

importandroid.app.Application;

importandroid.util.Log;

 

 

publicclass InjectApplication extends Application {

         static {

                   System.loadLibrary("so");

         }

 

 

 

 

         @Override

         public void onCreate() {

                   // TODO Auto-generated methodstub

               System.out.println("InjectApplication native test");

此处调用JNI函数

                   testddd();

                   super.onCreate();

         }

 

         public native String testddd();

}

 

修改art/compiler/dex/frontend.cc,打开输出

 

staticuint32_t kCompilerDebugFlags = 0 |     //Enable debug/testing modes

  // (1 << kDebugDisplayMissingTargets) |

   (1 <<kDebugVerbose) |

   (1 <<kDebugDumpCFG) |

 

 

adblogcat –S dex2oat:*

得到编译onCreate函数输出如下:

 

I/dex2oat(10839): Compiling void com.example.testar.InjectApplication.onCreate()...

I/dex2oat(10839): Compiling void com.example.testar.InjectApplication.onCreate()

I/dex2oat(10839): 0xb587c3f8 insns

I/dex2oat(10839): 13 blocks in total

I/dex2oat(10839): Block 0 (Entry Block) (insn 0000 - 0000 empty)

I/dex2oat(10839):   Fallthrough : block 2 (0x0)

I/dex2oat(10839): Block 1 (Exit Block) (insn 0000 - 0000 empty)

I/dex2oat(10839): Block 2 (Code Block) (insn 0000 - 0000)

I/dex2oat(10839):   Taken branch: block 3(0x0)

I/dex2oat(10839):   Fallthrough : block 4 (0x0)

I/dex2oat(10839): Block 3 (Exception Handling) (insn 0000 - 0000 empty)

I/dex2oat(10839): Block 4 (Code Block) (insn 0000 - 0002)

I/dex2oat(10839):   Taken branch: block 5(0x2)

I/dex2oat(10839):   Fallthrough : block 6 (0x2)

I/dex2oat(10839): Block 5 (Exception Handling) (insn 0002 - 0002 empty)

I/dex2oat(10839): Block 6 (Code Block) (insn 0002 - 0004)

I/dex2oat(10839):   Taken branch: block 7(0x4)

I/dex2oat(10839):   Fallthrough : block 8 (0x4)

I/dex2oat(10839): Block 7 (Exception Handling) (insn 0004 - 0004 empty)

I/dex2oat(10839): Block 8 (Code Block) (insn 0004 - 0007)

I/dex2oat(10839):   Taken branch: block 9(0x7)

I/dex2oat(10839):   Fallthrough : block 10 (0x7)

I/dex2oat(10839): Block 9 (Exception Handling) (insn 0007 - 0007 empty)

I/dex2oat(10839): Block 10 (Code Block) (insn 0007 - 000a)

I/dex2oat(10839):   Taken branch: block 11(0xa)

I/dex2oat(10839):   Fallthrough : block 12 (0xa)

I/dex2oat(10839): Block 11 (Exception Handling) (insn 000a - 000a empty)

I/dex2oat(10839): Block 12 (Code Block) (insn 000a - 000d)

I/dex2oat(10839):   Fallthrough : block 1 (0x0)

I/dex2oat(10839): Core regs after sort

I/dex2oat(10839): s_reg[2]: 2

I/dex2oat(10839): s_reg[0]: 1

I/dex2oat(10839): s_reg[1]: 1

I/dex2oat(10839): s_reg[3]: 1

I/dex2oat(10839): Fp regs after sort

I/dex2oat(10839): s_reg[0]: 0

I/dex2oat(10839): s_reg[1]: 0

I/dex2oat(10839): s_reg[2]: 0

I/dex2oat(10839): s_reg[3]: 0

I/dex2oat(10839): V[00] -> r6

I/dex2oat(10839): V[01] -> r7

I/dex2oat(10839): V[02] -> r5

I/dex2oat(10839): V[Method*] -> r8

I/dex2oat(10839): After Promotion

I/dex2oat(10839): Loc[00] : PhysReg, N U C n L h r6 s31 S0

I/dex2oat(10839): Loc[01] : PhysReg, N U C n L h r7 s31 S1

I/dex2oat(10839): Loc[02] : PhysReg, N D R n L h r5 s31 S2

I/dex2oat(10839): Loc[-1] : PhysReg, N D C n L h r8 s31 S3

I/dex2oat(10839): Loc[04] : PhysReg, N D R n L h r6 s31 S0

I/dex2oat(10839): Loc[05] : PhysReg, N D R n L h r7 s31 S1

I/dex2oat(10839): Dumping LIR insns for voidcom.example.testar.InjectApplication.onCreate()

I/dex2oat(10839): Regs (excluding ins) : 2

I/dex2oat(10839): Ins          : 1

I/dex2oat(10839): Outs         : 2

I/dex2oat(10839): CoreSpills       : 5

I/dex2oat(10839): FPSpills       : 0

I/dex2oat(10839): CompilerTemps    : 0

I/dex2oat(10839): Frame size       : 48

I/dex2oat(10839): code size is 172 bytes, Dalvik size is 28

I/dex2oat(10839): expansion factor: 6.14286

I/dex2oat(10839): V[00] -> r6

I/dex2oat(10839): V[01] -> r7

thispointer

I/dex2oat (10839): V[02] -> r5

I/dex2oat(10839): V[Method*] -> r8

I/dex2oat(10839): L0xb585b9ec:

 

 

 

 

I/dex2oat(10839): -------- method entry voidcom.example.testar.InjectApplication.onCreate()

I/dex2oat(10839): 00000: ldr      r12, [rSELF, #16]

I/dex2oat(10839): 00004: push     <r5, r6, r7,r8, r14>

I/dex2oat(10839): 00008: sub      lr,sp,#28

I/dex2oat(10839): 0000c: cmp      lr, r12

I/dex2oat(10839): 0000e: bcc      0x0000009a(L0xb585beb4)

I/dex2oat(10839): 00012: mov      sp, lr

I/dex2oat(10839): 00014: mov      r8, r0

I/dex2oat(10839): 00016: str      r0, [sp, #0]

I/dex2oat(10839): 00018: movs     r5, r1

I/dex2oat(10839): L0xb585ba7c:

 

 

I/dex2oat(10839): -------- dalvik offset: 0x0 @ sget-object v0_1, index #312

I/dex2oat(10839): 0001a: mov      r1, r8

I/dex2oat(10839): 0001c: ldr      r0, [r1, #12]

I/dex2oat(10839): 0001e: ldr      r0, [r0, #944]

I/dex2oat(10839): 00022: cbnz     r0,0x0000002c(L0xb585c354)

I/dex2oat(10839): 00024: ldr      lr, [rSELF,#372]

I/dex2oat(10839): 00028: movs     r0, #233

I/dex2oat(10839): 0002a: blx      lr

I/dex2oat(10839): LsafepointPC_0x2c_0:

I/dex2oat(10839): L0xb585c354:

I/dex2oat(10839): 0002c: ldr      r6, [r0, #116]

I/dex2oat(10839): -------- dalvik offset: 0x2 @ const-string v1_1, index #239

I/dex2oat(10839): 0002e: ldr      lr, [rSELF,#384]

I/dex2oat(10839): 00032: mov      r2, r8

I/dex2oat(10839): 00034: ldr      r0, [r2, #24]

I/dex2oat(10839): 00036: ldr      r0, [r0, #968]

I/dex2oat(10839): 0003a: movs     r1, #239

I/dex2oat(10839): 0003c: cmp      r0, #0

I/dex2oat(10839): -------- BARRIER

I/dex2oat(10839): 0003e: it:0100  eq

I/dex2oat(10839): 00040: movs     r0, r2

I/dex2oat(10839): 00042: blx      lr

I/dex2oat(10839): LsafepointPC_0x44_2:

I/dex2oat(10839): -------- BARRIER

I/dex2oat(10839): 00044: movs     r7, r0

I/dex2oat(10839): -------- dalvik offset: 0x4 @ Check1: invoke-virtual v0_1, v1_1

I/dex2oat(10839): 00046: movs     r1, r6

I/dex2oat(10839): 00048: movs     r2, r7

I/dex2oat(10839): 0004a: cbz      r1,0x000000a6(L0xb585c990)

I/dex2oat(10839): 0004c: ldr      lr, [r1, #0]

I/dex2oat(10839): 00050: ldr      lr, [lr, #52]

I/dex2oat(10839): 00054: ldr      r0, [lr, #188]

I/dex2oat(10839): 00058: ldr      lr, [r0, #40]

I/dex2oat(10839): 0005c: blx      lr

I/dex2oat(10839): LsafepointPC_0x5e_4:

I/dex2oat(10839): L0xb585bc2c:

I/dex2oat(10839): -------- dalvik offset: 0x4 @ Check2: invoke-virtual v0_1, v1_1

 

 

I/dex2oat(10839): -------- dalvik offset: 0x7 @ invoke-virtual v2_0

//thispointer

I/dex2oat (10839): 0005e: movs     r1, r5

453      cg->LoadWordDisp(cg->TargetReg(kArg1),mirror::Object::ClassOffset().Int32Value(),

454                       cg->TargetReg(kInvokeTgt));

 

I/dex2oat(10839): 00060: ldr      lr, [r1, #0]

457      cg->LoadWordDisp(cg->TargetReg(kInvokeTgt),mirror::Class::VTableOffset().Int32Value(),

 458                       cg->TargetReg(kInvokeTgt));

 

I/dex2oat(10839): 00064: ldr      lr, [lr, #52]

461      cg->LoadWordDisp(cg->TargetReg(kInvokeTgt), (method_idx * 4) +

462                       mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value(),

463                       cg->TargetReg(kArg0));

 

I/dex2oat(10839): 00068: ldr      r0, [lr, #588]

466       if(cu->instruction_set != kX86) {

467        cg->LoadWordDisp(cg->TargetReg(kArg0),

468                         mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(),

469                         cg->TargetReg(kInvokeTgt));

 

 

I/dex2oat(10839): 0006c: ldr      lr, [r0, #40]

I/dex2oat(10839): 00070: blx      lr

I/dex2oat(10839): LsafepointPC_0x72_7:

 

 

 

 

I/dex2oat(10839): -------- dalvik offset: 0xa @ invoke-super v2_0

I/dex2oat(10839): 00072: mov      lr, #1717

I/dex2oat(10839): 00076: movt     lr, #25352

I/dex2oat(10839): 0007a: mov      r0, #30304

I/dex2oat(10839): 0007e: movt     r0, #24657

I/dex2oat(10839): 00082: movs     r1, r5

I/dex2oat(10839): 00084: blx      lr

I/dex2oat(10839): LsafepointPC_0x86_a:

I/dex2oat(10839): -------- dalvik offset: 0xd @ return-void

I/dex2oat(10839): 00086: subs     r4, #1

I/dex2oat(10839): 00088: beq      0x00000092(L0xb585d338)

I/dex2oat(10839): L0xb585d2f0:

I/dex2oat(10839): L0xb585ba34:

 

 

I/dex2oat(10839): -------- Method_Exit

I/dex2oat(10839): 0008c: add      sp, #7*4

I/dex2oat(10839): 0008e: pop      <r5, r6, r7,r8, r15>

I/dex2oat(10839): L0xb585bbe4:

I/dex2oat(10839): LS0xb585d338:

I/dex2oat(10839): 00092: ldr      lr, [rSELF,#604]

I/dex2oat(10839): 00096: blx      lr

I/dex2oat(10839): LsafepointPC_0x98_d:

I/dex2oat(10839): 00098: b        0x0000008c(L0xb585d2f0)

I/dex2oat(10839): LT0xb585beb4:

I/dex2oat(10839): 0009a: ldr      lr, [sp, #16]

I/dex2oat(10839): 0009e: add      sp, #5*4

I/dex2oat(10839): 000a0: ldr      r12, [rSELF,#628]

I/dex2oat(10839): 000a4: bx       r12

I/dex2oat(10839): LT0xb585c990:

I/dex2oat(10839): 000a6: ldr      lr, [rSELF,#624]

I/dex2oat(10839): 000aa: blx      lr

I/dex2oat(10839): LsafepointPC_0xac_4:

I/dex2oat(10839):   PC2Dex_MappingTableLcom/example/testar/InjectApplication_onCreate_()V_table[14] = {

I/dex2oat(10839):     {0x0002c, 0x0000},

I/dex2oat(10839):     {0x00044, 0x0002},

I/dex2oat(10839):     {0x0005e, 0x0004},

I/dex2oat(10839):     {0x00072, 0x0007},

I/dex2oat(10839):     {0x00086, 0x000a},

I/dex2oat(10839):     {0x00098, 0x000d},

I/dex2oat(10839):     {0x000ac, 0x0004},

I/dex2oat(10839):   };

I/dex2oat(10839): Compiled void com.example.testar.InjectApplication.onCreate()

 

 

编译生成调用代码的地方

art/compiler/dex/quick/gen_invoke.cc

 

435static int NextVCallInsn(CompilationUnit* cu, CallInfo* info,

 436                          int state, constMethodReference& target_method,

 437                          uint32_t method_idx,uintptr_t unused, uintptr_t unused2,

 438                          InvokeType unused3) {

 439  Mir2Lir* cg = static_cast<Mir2Lir*>(cu->cg.get());

 440   /*

 441    *This is the fast path in which the target virtual method is

 442    *fully resolved at compile time.

 443   */

 444  switch (state) {

 445    case 0: {  // Get "this" [set kArg1]

 446      RegLocation  rl_arg =info->args[0];

 447      cg->LoadValueDirectFixed(rl_arg, cg->TargetReg(kArg1));

 448      break;

 449    }

 450    case 1:  // Is "this" null?[use kArg1]

 451      cg->GenNullCheck(info->args[0].s_reg_low, cg->TargetReg(kArg1),info->opt_flags);

 452      // get this->klass_ [use kArg1, set kInvokeTgt]

 453       cg->LoadWordDisp(cg->TargetReg(kArg1),mirror::Object::ClassOffset().Int32Value(),

 454                       cg->TargetReg(kInvokeTgt));

 455      break;

 456    case 2:  // Getthis->klass_->vtable [usr kInvokeTgt, set kInvokeTgt]

 457       cg->LoadWordDisp(cg->TargetReg(kInvokeTgt),mirror::Class::VTableOffset().Int32Value(),

 458                       cg->TargetReg(kInvokeTgt));

 459      break;

 460    case 3:  // Get target method [use kInvokeTgt, set kArg0]

 461      cg->LoadWordDisp(cg->TargetReg(kInvokeTgt), (method_idx * 4) +

 462                       mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value(),

 463                       cg->TargetReg(kArg0));

 464      break;

 465    case 4:  // Get the compiled code address [uses kArg0,sets kInvokeTgt]

 466      if (cu->instruction_set != kX86) {

 467        cg->LoadWordDisp(cg->TargetReg(kArg0),

 468                          mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(),

 469                          cg->TargetReg(kInvokeTgt));

 470        break;

 471      }

 472      // Intentional fallthrough for X86

 473    default:

 474      return -1;

 475   }

 476  return state + 1;

 477 }

 

 

android art JNI函数的调用代码及生成过程