SlideShare una empresa de Scribd logo
1 de 22
Descargar para leer sin conexión
Dalvik
                                                           (1)

                                 @kishima
                         http://silentworlds.info/

                                           2011/6/5   AndroidPF
                                             (                    )

2011   6   12                                                         1
(            )




                Zygote




                     fork
                VM
                     dex
                             dexopt


2011   6   12                             2
dalvik/
                 dalvikvm/
                   DalvikVM main()
                 dexdump/
                  dex
                 dexlist/
                                                    frameworks/base/cmds/app_process/
                   ?
                 dexopt/                             Zygote(system-server)
                  dex           dex
                 docs/

                 dvz/
                  zygote
                                                    system/core/libcutils/zygote.c
                 dx/
                                                      zygote
                                    dex
                 hit/
                   ?
                 libdex/
                   dex                    (vm   )
                 libnativehelper/
                   ?
                 tests/

                 tools/

                 vm/
                  VM

2011   6   12                                                                           3
dalvik/
            vm/
             alloc/                 GC
                analysis/
                arch/
                compiler/ JIT
                hprof/
                interp/           mterp
                jdwp/
                mterp/


                native/     JNI
                oo/
                reflect/
                test/
                VM

2011   6   12                             4
Zygote

       init.rc

       service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-
       server




2011   6   12                                                                                 5
Zygote
  frameworks/base/cmds/app_process/app_main.cpp


   int main(int argc, const char* const argv[])
   {
   ---                                                                     init
       // Next arg is startup classname or "--zygote"
       if (i < argc) {                                                 Zygote
           arg = argv[i++];
           if (0 == strcmp("--zygote", arg)) {
               bool startSystemServer = (i < argc) ?
                    strcmp(argv[i], "--start-system-server") == 0 : false;
               setArgv0(argv0, "zygote");
               set_process_name("zygote");
               runtime.start("com.android.internal.os.ZygoteInit",
                 startSystemServer);
   ---




2011   6   12                                                                     6
Zygote
  frameworks/base/core/jni/AndroidRuntime.cpp

       /*
        * Start the Android runtime. This involves starting the virtual machine
        * and calling the "static void main(String[] args)" method in the class
        * named by "className".
        */
       void AndroidRuntime::start(const char* className, const bool startSystemServer)
       {
       ---
           /* start the virtual machine */
                                                             VM
           if (startVm(&mJavaVM, &env) != 0)
       ---
           /*
            * Start VM. This thread becomes the main thread of the VM, and will
            * not return until the VM exits.
            */
       ---                                                          “com.android.internal.os.ZygoteInit”
           startClass = env->FindClass(slashClassName);
       ---
               startMeth = env->GetStaticMethodID(startClass, "main",
                  "([Ljava/lang/String;)V");
       ---
                  env->CallStaticVoidMethod(startClass, startMeth, strArray);
       ---
       }

                                                        JNI    Java       main



2011   6    12                                                                                             7
Zygote
                                       AndroidRuntime.cpp                   JNI
       frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

            public static void main(String argv[]) {                                    if (argv[1].equals("true")) {
              try {                                                                         startSystemServer();
                 VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);            } else if (!argv[1].equals("false")) {
                                                                                            throw new RuntimeException(argv[0] + USAGE_STRING);
                // Start profiling the zygote initialization.                            }
                SamplingProfilerIntegration.start();
                                                                                        Log.i(TAG, "Accepting command socket connections");
                registerZygoteSocket();
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,                    if (ZYGOTE_FORK_MODE) {
                  SystemClock.uptimeMillis());                                              runForkMode();
                preloadClasses();                              PreLoad                  } else {                                Fork?
                preloadResources();                                                         runSelectLoopMode();
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                      }
                  SystemClock.uptimeMillis());
                                                                                         closeServerSocket();
                // Finish profiling the zygote initialization.                         } catch (MethodAndArgsCaller caller) {
                SamplingProfilerIntegration.writeZygoteSnapshot();                        caller.run();
                                                                                      } catch (RuntimeException ex) {
                // Do an initial gc to clean up after startup                            Log.e(TAG, "Zygote died with exception", ex);
                gc();                                                                    closeServerSocket();
                                                                                         throw ex;
                // If requested, start system server directly from Zygote             }
                if (argv.length != 2) {                                           }
                    throw new RuntimeException(argv[0] + USAGE_STRING);
                }




2011   6   12                                                                                                                                     8
dvz
                dalvik/dvz
                int main (int argc, const char **argv) {
                ---
                    err = zygote_run_wait(argc - 1, argv + 1, post_run_func);


                system/core/libcutils/zygote.c

                int zygote_run_wait(int argc, const char **argv, void (*post_run_func)(int))   /dec/socket/zygote
                {
                    fd = socket_local_client(ZYGOTE_SOCKET,
                         ANDROID_SOCKET_NAMESPACE_RESERVED, AF_LOCAL);
                ---
                    // The command socket is passed to the peer as close-on-exec
                    // and will close when the peer dies                                       zygote
                    newargv[0] = "--peer-wait";
                    memcpy(newargv + 1, argv, argc * sizeof(*argv));

                      pid = send_request(fd, 1, argc + 1, newargv);
                ---
                }




2011   6   12                                                                                                       9
system/core/libcutils/zygote.c
       static int send_request(int fd, int sendStdio, int argc, const char **argv)
       {
       ---
           struct msghdr msg;
       ---
               ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
                                                                                   sendmsg
       ---
           // replace any newlines with spaces and send the args                 1.stdio
           For (i = 0; i < argc; i++) {
       ---                                                                       2.argv
               toprint = argv[i];
       ---                                                                       3.PID
               ivs[0].iov_base = (char *)toprint;
               ivs[0].iov_len = strlen(toprint);                                    (    fork   PID
               ivs[1].iov_base = (char *)newline_string; //     ”¥n”
                                                                                          )
                ivs[1].iov_len = 1;

                msg.msg_iovlen = 2;

                do {
                   ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
                } while (ret < 0 && errno == EINTR);
       ---
             // Read the pid, as a 4-byte network-order integer
             ivs[0].iov_base = &pid;
       ---
                  ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL);



2011   6   12                                                                                         10
VM
 frameworks/base/core/jni/AndroidRuntime.cpp

       int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
       {
       ---
           if (executionMode == kEMIntPortable) {                              JIT
               opt.optionString = "-Xint:portable";
               mOptions.add(opt);
           } else if (executionMode == kEMIntFast) {
               opt.optionString = "-Xint:fast";
               mOptions.add(opt);
       #if defined(WITH_JIT)
           } else if (executionMode == kEMJitCompiler) {
               opt.optionString = "-Xint:jit";
               mOptions.add(opt);
       #endif
       ---
           /*
            * Initialize the VM.
            *
            * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
            * If this call succeeds, the VM is ready, and we can start issuing
            * JNI calls.
            */
           if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
                                                                                       VM
       ---
       }




2011   6   12                                                                               11
VM
       dalvik/vm/Jni.c
           jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args)             VM
           {
              /*
               * Set up structures for JNIEnv and VM.
               */
              pVM = (JavaVMExt*) malloc(sizeof(JavaVMExt));

                 memset(pVM, 0, sizeof(JavaVMExt));
                 pVM->funcTable = &gInvokeInterface;
                 pVM->envList = pEnv;

           ---                                                                             VM
                 /* set this up before initializing VM, so it can create some JNIEnvs */
                 gDvm.vmList = (JavaVM*) pVM;                                              ※

                 /*
                  * Create an env for main thread. We need to have something set up
                  * here because some of the class initialization we do when starting
                  * up the VM will call into native code.
                  */                                                                                 JNI
                 pEnv = (JNIEnvExt*) dvmCreateJNIEnv(NULL);
           ---
                 /* initialize VM */
                 gDvm.initializing = true;
                 if (dvmStartup(argc, argv, args->ignoreUnrecognized, (JNIEnv*)pEnv) != 0) { --- }
           ---
                 *p_env = (JNIEnv*) pEnv;
                 *p_vm = (JavaVM*) pVM;
           ---
           }
2011   6   12                                                                                              12
VM

           JavaVM             VM
                libnativehelper/include/nativehelper/jni.h
                struct JNIInvokeInterface{
                   jint    (*DestroyJavaVM)(JavaVM*);
                   jint    (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
                   jint    (*DetachCurrentThread)(JavaVM*);
                   jint    (*GetEnv)(JavaVM*, void**, jint);
                   jint    (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
                }


           JNIEnv           JNI
                libnativehelper/include/nativehelper/jni.h
                struct JNINativeInterface{}
                    VM




2011   6   12                                                                          13
VM
                struct JavaVMExt;

                typedef struct JNIEnvExt {
                   const struct JNINativeInterface* funcTable;        /* must be first */

                  const struct JNINativeInterface* baseFuncTable;

                  /* pointer to the VM we are a part of */
                  struct JavaVMExt* vm;

                  u4   envThreadId;
                  Thread* self;

                  /* if nonzero, we are in a "critical" JNI call */
                  int critical;

                  /* keep a copy of this here for speed */
                  bool forceDataCopy;

                   struct JNIEnvExt* prev;
                   struct JNIEnvExt* next;
                } JNIEnvExt;

                typedef struct JavaVMExt {
                   const struct JNIInvokeInterface* funcTable;        /* must be first */

                  const struct JNIInvokeInterface* baseFuncTable;

                  /* if multiple VMs are desired, add doubly-linked list stuff here */

                  /* per-VM feature flags */
                  bool useChecked;
                  bool warnError;
                  bool forceDataCopy;

                   /* head of list of JNIEnvs associated with this VM */
                   JNIEnvExt*       envList;
                   pthread_mutex_t envListLock;
                } JavaVMExt;



2011   6   12                                                                              14
dex                         1
       dalvik/vm/JarFile.c

       /*                                                                            classes.dex
        * Open a Jar file. It's okay if it's just a Zip archive without all of
        * the Jar trimmings, but we do insist on finding "classes.dex" inside           .odex
        * or an appropriately-named ".odex" file alongside.
        *
        * If "isBootstrap" is not set, the optimizer/verifier regards this DEX as
        * being part of a different class loader.
        */
       int dvmJarFileOpen(const char* fileName, const char* odexOutputName,
           JarFile** ppJarFile, bool isBootstrap)
       {
       ---
           /* First, look for a ".odex" alongside the jar file. It will
            * have the same name/path except for the extension.                            .odex
            */
           fd = openAlternateSuffix(fileName, "odex", O_RDONLY, &cachedName);        .odex
       ---
               /*
                * Pre-created .odex absent or stale. Look inside the jar for a
                * "classes.dex".
                */                                                                                 classes.dex
               entry = dexZipFindEntry(&archive, kDexInJarName);




2011   6   12                                                                                                    15
dex                              2
             dalvik/vm/JarFile.c
                  /*                                                                   classes.dex
                   * We've found the one we want. See if there's an up-to-date copy
                   * in the cache.
                   *
                   * On return, "fd" will be seeked just past the "opt" header.        (                fd opt
                   *
                   * If a stale .odex file is present and classes.dex exists in                            )
                   * the archive, this will *not* return an fd pointing to the         (           odex
                   * .odex file; the fd will point into dalvik-cache like any
                                                                                       classes.dex               fd odex
                   * other jar.
                   */                                                                             jar                      )
                  if (odexOutputName == NULL) {
                      cachedName = dexOptGenerateCacheFileName(fileName,
                                  kDexInJarName);
   ---
                  /*
                   * If fd points to a new file (because there was no cached version,
                   * or the cached version was stale), generate the optimized DEX.
                   * The file descriptor returned is still locked, and is positioned
                   * just past the optimization header.
                   */
                  if (newFile) {
   ---                                                                                                        DEX
                       result = dvmOptimizeDexFile(fd, dexOffset,
                               dexGetZipEntryUncompLen(&archive, entry),
                                                                                             (          odex?)
                               fileName,
                               dexGetZipEntryModTime(&archive, entry),
                               dexGetZipEntryCrc32(&archive, entry),
                                                                                           odex
                               isBootstrap);
   ---
2011     6   12                                                                                                                16
dex                             3
           dalvik/vm/JarFile.c
       ---
               /*
                * Map the cached version. This immediately rewinds the fd, so it
                * doesn't have to be seeked anywhere in particular.                                                  mmap
                */
               if (dvmDexFileOpenFromFd(fd, &pDvmDex) != 0) {
                                                                                               seek
       ---


           *ppJarFile = (JarFile*) calloc(1, sizeof(JarFile));
           (*ppJarFile)->archive = archive;
           (*ppJarFile)->cacheFileName = cachedName;
           (*ppJarFile)->pDvmDex = pDvmDex;
        ---
       (               )                                             dalvik/libdex/SysUtil.c
       }
                                                                     fd
       dalvik/DvmDex.c
       dvmDexFileOpenFromFd()                                        (writable read-only)             pDvmDex mmap
       {


                                                                     mmap
                                                                          prot=PROT_READ | PROT_WRITE
                 SHA-1                                                    flags=MAP_FILE | MAP_PRIVATE (copy-on-write)
                                                                     mprotect
       }                                                                  PROT_READ



2011       6    12                                                                                                          17
dex
           dalvik/vm/analysis/DexPrepare.c
  /*                                                                           fd
   * Given a descriptor for a file with DEX data in it, produce an
   * optimized version.
   *
   * The file pointed to by "fd" is expected to be a locked shared resource
                                                                                      OK
   * (or private); we make no efforts to enforce multi-process correctness
   * here.
   *
   * "fileName" is only used for debug output. "modWhen" and "crc" are stored
   * in the dependency set.
   *                                                                              bootstrap
   * The "isBootstrap" flag determines how the optimizer and verifier handle
   * package-scope access checks. When optimizing, we only load the bootstrap       ※
   * class DEX files and the target DEX, so the flag determines whether the
   * target DEX classes are given a (synthetic) non-NULL classLoader pointer.
   * This only really matters if the target DEX contains classes that claim to
   * be in the same package as bootstrap classes.                                               dex
   *
   * The optimizer will need to load every class in the target DEX file.
   * This is generally undesirable, so we start a subprocess to do the
   * work and wait for it to complete.
   *
   * Returns "true" on success. All data will have been written to "fd".
                                                                                            ※
   */
  bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength,
      const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)                                      fd



2011   6   12                                                                                              18
dex
           dalvik/vm/analysis/DexPrepare.c

 bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength,
     const char* fileName, u4 modWhen, u4 crc, bool isBootstrap)
 {
 ---
     pid = fork();
     if (pid == 0) {
         static const int kUseValgrind = 0;
         static const char* kDexOptBin = "/bin/dexopt";                       ※fork
         static const char* kValgrinder = "/usr/bin/valgrind";
 ---
         strcpy(execFile, androidRoot);
                                                                                                 dexopt
         strcat(execFile, kDexOptBin);                                      execv()
 ---
         if (kUseValgrind)                                                              dexopt
             execv(kValgrinder, argv);
         else
             execv(execFile, argv);
 ---
     } else {                                                                   ※fork
 ---
         /*
          * Wait for the optimization process to finish. We go into VMWAIT
          * mode here so GC suspension won't have to wait for us.
          */                                                                 VM VMWAIT
         oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT);
                                                                             ※GC
 ---
    }
 }

2011   6   12                                                                                             19
1(   )
       dalvik/
        vm/
         mterp/
                gen-mterp.py
                config-xxx              xxx
                config-yyy              yyy


                config-portstd
                rebuild.sh
                xxx/            xxx          xxx
                yyy/            yyy          yyy
                c/                            C
                out/


                                                   OP


                                 out
2011   6   12                                                    20
dalvik/vm/mterp/out/InterpC-portstd.c
                                                                             (     C             )
       /* File: portable/entry.c */
        * Main interpreter loop.
       bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState)
       {
                                                                       #define FETCH(_offset) (pc[(_offset)])
       ---
                                                                       #define INST_INST(_inst) ((_inst) & 0xff)
           /* copy state in */
                                                                       # define HANDLE_OPCODE(_op) case _op:
           curMethod = interpState->method;
                                                                       # define ADJUST_PC(_offset) do { 
           pc = interpState->pc;
                                                                            pc += _offset;               
           fp = interpState->fp;
                                                                            EXPORT_EXTRA_PC();           
       ---
                                                                         } while (false)
           methodClassDex = curMethod->clazz->pDvmDex;
                                                                       # define FINISH(_offset) { ADJUST_PC(_offset); break; }
       ---
           while (1) {
       ---
              /* fetch the next 16 bits from the instruction stream */
              inst = FETCH(0);

              switch (INST_INST(inst)) {                            PC(                  )                      (instruction)
       ---
       /* File: c/OP_NOP.c */
       HANDLE_OPCODE(OP_NOP)                                   OP
           FINISH(1);
       OP_END                                                       OP              case
       ---
                                                          PC

       ---
       }                                                                               JNI
2011    6    12                                                                                                                 21
(              )



                Zygote                 fork
                dexopt
                VM        ->fork->dex                      ->




                JNI
                JIT
                                   ↓
                           http://silentworlds.info/pukiwiki/

2011   6   12                                                   22

Más contenido relacionado

La actualidad más candente

The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
Martin Schuhfuß
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
Sri Prasanna
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Robot Media
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
priyank09
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.x
Tatsuya Maki
 
Hibernate Import.Sql I18n
Hibernate Import.Sql I18nHibernate Import.Sql I18n
Hibernate Import.Sql I18n
yifi2009
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbron
cymbron
 

La actualidad más candente (20)

Qt Rest Server
Qt Rest ServerQt Rest Server
Qt Rest Server
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
 
3
33
3
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствами
 
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
droidparts
droidpartsdroidparts
droidparts
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
Unit Testing: Special Cases
Unit Testing: Special CasesUnit Testing: Special Cases
Unit Testing: Special Cases
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
 
Deep dive into OSGi Lifecycle Layer
Deep dive into OSGi Lifecycle LayerDeep dive into OSGi Lifecycle Layer
Deep dive into OSGi Lifecycle Layer
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++
 
Non stop random2b
Non stop random2bNon stop random2b
Non stop random2b
 
OSGi Training for Carbon Developers
OSGi Training for Carbon DevelopersOSGi Training for Carbon Developers
OSGi Training for Carbon Developers
 
Memory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native CollectionsMemory Management of C# with Unity Native Collections
Memory Management of C# with Unity Native Collections
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.x
 
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, howTomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
Tomasz Polanski - Automated mobile testing 2016 - Testing: why, when, how
 
Hibernate Import.Sql I18n
Hibernate Import.Sql I18nHibernate Import.Sql I18n
Hibernate Import.Sql I18n
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbron
 

Destacado

Android life cycle
Android life cycleAndroid life cycle
Android life cycle
瑋琮 林
 

Destacado (10)

Android session 2-behestee
Android session 2-behesteeAndroid session 2-behestee
Android session 2-behestee
 
Form Handling using PHP
Form Handling using PHPForm Handling using PHP
Form Handling using PHP
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cycle
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle
 
Android intents
Android intentsAndroid intents
Android intents
 
Android Studio NDK(JNI) + OpenCV 完整教學
Android Studio NDK(JNI) + OpenCV 完整教學Android Studio NDK(JNI) + OpenCV 完整教學
Android Studio NDK(JNI) + OpenCV 完整教學
 
Android: Intent, Intent Filter, Broadcast Receivers
Android: Intent, Intent Filter, Broadcast ReceiversAndroid: Intent, Intent Filter, Broadcast Receivers
Android: Intent, Intent Filter, Broadcast Receivers
 
Android Lesson 3 - Intent
Android Lesson 3 - IntentAndroid Lesson 3 - Intent
Android Lesson 3 - Intent
 
Android - Broadcast Receiver
Android - Broadcast ReceiverAndroid - Broadcast Receiver
Android - Broadcast Receiver
 
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental pluginMastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
Mastering the NDK with Android Studio 2.0 and the gradle-experimental plugin
 

Similar a Dalvik Source Code Reading

Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
Unit Testing RPG with JUnit
Unit Testing RPG with JUnitUnit Testing RPG with JUnit
Unit Testing RPG with JUnit
Greg.Helton
 
Jenkins and Groovy
Jenkins and GroovyJenkins and Groovy
Jenkins and Groovy
Kiyotaka Oku
 
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
mercysuttle
 
OOP2017: Containerized End-2-End Testing – automate it!
OOP2017: Containerized End-2-End Testing – automate it!OOP2017: Containerized End-2-End Testing – automate it!
OOP2017: Containerized End-2-End Testing – automate it!
Tobias Schneck
 

Similar a Dalvik Source Code Reading (20)

Androidaop 170105090257
Androidaop 170105090257Androidaop 170105090257
Androidaop 170105090257
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVM
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
 
Will it blend? Java agents and OSGi
Will it blend? Java agents and OSGiWill it blend? Java agents and OSGi
Will it blend? Java agents and OSGi
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Dropwizard and Friends
Dropwizard and FriendsDropwizard and Friends
Dropwizard and Friends
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
Unit Testing RPG with JUnit
Unit Testing RPG with JUnitUnit Testing RPG with JUnit
Unit Testing RPG with JUnit
 
Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing
 
Jenkins and Groovy
Jenkins and GroovyJenkins and Groovy
Jenkins and Groovy
 
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
.settings.jsdtscope.settingsorg.eclipse.jdt.core.prefs.docx
 
Android - Anatomy of android elements & layouts
Android - Anatomy of android elements & layoutsAndroid - Anatomy of android elements & layouts
Android - Anatomy of android elements & layouts
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
How Secure Are Docker Containers?
How Secure Are Docker Containers?How Secure Are Docker Containers?
How Secure Are Docker Containers?
 
GlassFish v3 : En Route Java EE 6
GlassFish v3 : En Route Java EE 6GlassFish v3 : En Route Java EE 6
GlassFish v3 : En Route Java EE 6
 
OOP2017: Containerized End-2-End Testing – automate it!
OOP2017: Containerized End-2-End Testing – automate it!OOP2017: Containerized End-2-End Testing – automate it!
OOP2017: Containerized End-2-End Testing – automate it!
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 

Más de kishima7

Más de kishima7 (16)

Now is the time to create your own (m)Ruby computer
Now is the time to create your own (m)Ruby computerNow is the time to create your own (m)Ruby computer
Now is the time to create your own (m)Ruby computer
 
mrubyで作るマイコンボード
mrubyで作るマイコンボードmrubyで作るマイコンボード
mrubyで作るマイコンボード
 
自分だけのデバイスを作るお話
自分だけのデバイスを作るお話自分だけのデバイスを作るお話
自分だけのデバイスを作るお話
 
オリジナルmrubyデバイス作り
オリジナルmrubyデバイス作りオリジナルmrubyデバイス作り
オリジナルmrubyデバイス作り
 
mruby VM を調べてみた話
mruby VM を調べてみた話mruby VM を調べてみた話
mruby VM を調べてみた話
 
Stairway to my Family mruby
Stairway to my Family mrubyStairway to my Family mruby
Stairway to my Family mruby
 
VMを改めて学んで見る
VMを改めて学んで見るVMを改めて学んで見る
VMを改めて学んで見る
 
mruby/cで始めるM5Stack &mrubyスクリプト開発
mruby/cで始めるM5Stack &mrubyスクリプト開発mruby/cで始めるM5Stack &mrubyスクリプト開発
mruby/cで始めるM5Stack &mrubyスクリプト開発
 
Wio LTEとmruby/cでIoT
Wio LTEとmruby/cでIoTWio LTEとmruby/cでIoT
Wio LTEとmruby/cでIoT
 
Unityにmrubyを組み込んで抽選をしてみた
Unityにmrubyを組み込んで抽選をしてみたUnityにmrubyを組み込んで抽選をしてみた
Unityにmrubyを組み込んで抽選をしてみた
 
Introduction of mruby & Webruby script example
Introduction of mruby & Webruby script exampleIntroduction of mruby & Webruby script example
Introduction of mruby & Webruby script example
 
Ruby and Android
Ruby and AndroidRuby and Android
Ruby and Android
 
Google TV hack
Google TV hackGoogle TV hack
Google TV hack
 
くみこみからひとことReturns
くみこみからひとことReturnsくみこみからひとことReturns
くみこみからひとことReturns
 
ネット家電じゃなくて?
ネット家電じゃなくて?ネット家電じゃなくて?
ネット家電じゃなくて?
 
くみこみからひとこと
くみこみからひとことくみこみからひとこと
くみこみからひとこと
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Último (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 

Dalvik Source Code Reading

  • 1. Dalvik (1) @kishima http://silentworlds.info/ 2011/6/5 AndroidPF ( ) 2011 6 12 1
  • 2. ( ) Zygote fork VM dex dexopt 2011 6 12 2
  • 3. dalvik/ dalvikvm/ DalvikVM main() dexdump/ dex dexlist/ frameworks/base/cmds/app_process/ ? dexopt/ Zygote(system-server) dex dex docs/ dvz/ zygote system/core/libcutils/zygote.c dx/ zygote dex hit/ ? libdex/ dex (vm ) libnativehelper/ ? tests/ tools/ vm/ VM 2011 6 12 3
  • 4. dalvik/ vm/ alloc/ GC analysis/ arch/ compiler/ JIT hprof/ interp/ mterp jdwp/ mterp/ native/ JNI oo/ reflect/ test/ VM 2011 6 12 4
  • 5. Zygote init.rc service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system- server 2011 6 12 5
  • 6. Zygote frameworks/base/cmds/app_process/app_main.cpp int main(int argc, const char* const argv[]) { --- init // Next arg is startup classname or "--zygote" if (i < argc) { Zygote arg = argv[i++]; if (0 == strcmp("--zygote", arg)) { bool startSystemServer = (i < argc) ? strcmp(argv[i], "--start-system-server") == 0 : false; setArgv0(argv0, "zygote"); set_process_name("zygote"); runtime.start("com.android.internal.os.ZygoteInit", startSystemServer); --- 2011 6 12 6
  • 7. Zygote frameworks/base/core/jni/AndroidRuntime.cpp /* * Start the Android runtime. This involves starting the virtual machine * and calling the "static void main(String[] args)" method in the class * named by "className". */ void AndroidRuntime::start(const char* className, const bool startSystemServer) { --- /* start the virtual machine */ VM if (startVm(&mJavaVM, &env) != 0) --- /* * Start VM. This thread becomes the main thread of the VM, and will * not return until the VM exits. */ --- “com.android.internal.os.ZygoteInit” startClass = env->FindClass(slashClassName); --- startMeth = env->GetStaticMethodID(startClass, "main", "([Ljava/lang/String;)V"); --- env->CallStaticVoidMethod(startClass, startMeth, strArray); --- } JNI Java main 2011 6 12 7
  • 8. Zygote AndroidRuntime.cpp JNI frameworks/base/core/java/com/android/internal/os/ZygoteInit.java public static void main(String argv[]) { if (argv[1].equals("true")) { try { startSystemServer(); VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024); } else if (!argv[1].equals("false")) { throw new RuntimeException(argv[0] + USAGE_STRING); // Start profiling the zygote initialization. } SamplingProfilerIntegration.start(); Log.i(TAG, "Accepting command socket connections"); registerZygoteSocket(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START, if (ZYGOTE_FORK_MODE) { SystemClock.uptimeMillis()); runForkMode(); preloadClasses(); PreLoad } else { Fork? preloadResources(); runSelectLoopMode(); EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END, } SystemClock.uptimeMillis()); closeServerSocket(); // Finish profiling the zygote initialization. } catch (MethodAndArgsCaller caller) { SamplingProfilerIntegration.writeZygoteSnapshot(); caller.run(); } catch (RuntimeException ex) { // Do an initial gc to clean up after startup Log.e(TAG, "Zygote died with exception", ex); gc(); closeServerSocket(); throw ex; // If requested, start system server directly from Zygote } if (argv.length != 2) { } throw new RuntimeException(argv[0] + USAGE_STRING); } 2011 6 12 8
  • 9. dvz dalvik/dvz int main (int argc, const char **argv) { --- err = zygote_run_wait(argc - 1, argv + 1, post_run_func); system/core/libcutils/zygote.c int zygote_run_wait(int argc, const char **argv, void (*post_run_func)(int)) /dec/socket/zygote { fd = socket_local_client(ZYGOTE_SOCKET, ANDROID_SOCKET_NAMESPACE_RESERVED, AF_LOCAL); --- // The command socket is passed to the peer as close-on-exec // and will close when the peer dies zygote newargv[0] = "--peer-wait"; memcpy(newargv + 1, argv, argc * sizeof(*argv)); pid = send_request(fd, 1, argc + 1, newargv); --- } 2011 6 12 9
  • 10. system/core/libcutils/zygote.c static int send_request(int fd, int sendStdio, int argc, const char **argv) { --- struct msghdr msg; --- ret = sendmsg(fd, &msg, MSG_NOSIGNAL); sendmsg --- // replace any newlines with spaces and send the args 1.stdio For (i = 0; i < argc; i++) { --- 2.argv toprint = argv[i]; --- 3.PID ivs[0].iov_base = (char *)toprint; ivs[0].iov_len = strlen(toprint); ( fork PID ivs[1].iov_base = (char *)newline_string; // ”¥n” ) ivs[1].iov_len = 1; msg.msg_iovlen = 2; do { ret = sendmsg(fd, &msg, MSG_NOSIGNAL); } while (ret < 0 && errno == EINTR); --- // Read the pid, as a 4-byte network-order integer ivs[0].iov_base = &pid; --- ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL); 2011 6 12 10
  • 11. VM frameworks/base/core/jni/AndroidRuntime.cpp int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) { --- if (executionMode == kEMIntPortable) { JIT opt.optionString = "-Xint:portable"; mOptions.add(opt); } else if (executionMode == kEMIntFast) { opt.optionString = "-Xint:fast"; mOptions.add(opt); #if defined(WITH_JIT) } else if (executionMode == kEMJitCompiler) { opt.optionString = "-Xint:jit"; mOptions.add(opt); #endif --- /* * Initialize the VM. * * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread. * If this call succeeds, the VM is ready, and we can start issuing * JNI calls. */ if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) { VM --- } 2011 6 12 11
  • 12. VM dalvik/vm/Jni.c jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) VM { /* * Set up structures for JNIEnv and VM. */ pVM = (JavaVMExt*) malloc(sizeof(JavaVMExt)); memset(pVM, 0, sizeof(JavaVMExt)); pVM->funcTable = &gInvokeInterface; pVM->envList = pEnv; --- VM /* set this up before initializing VM, so it can create some JNIEnvs */ gDvm.vmList = (JavaVM*) pVM; ※ /* * Create an env for main thread. We need to have something set up * here because some of the class initialization we do when starting * up the VM will call into native code. */ JNI pEnv = (JNIEnvExt*) dvmCreateJNIEnv(NULL); --- /* initialize VM */ gDvm.initializing = true; if (dvmStartup(argc, argv, args->ignoreUnrecognized, (JNIEnv*)pEnv) != 0) { --- } --- *p_env = (JNIEnv*) pEnv; *p_vm = (JavaVM*) pVM; --- } 2011 6 12 12
  • 13. VM JavaVM VM libnativehelper/include/nativehelper/jni.h struct JNIInvokeInterface{ jint (*DestroyJavaVM)(JavaVM*); jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); jint (*DetachCurrentThread)(JavaVM*); jint (*GetEnv)(JavaVM*, void**, jint); jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*); } JNIEnv JNI libnativehelper/include/nativehelper/jni.h struct JNINativeInterface{} VM 2011 6 12 13
  • 14. VM struct JavaVMExt; typedef struct JNIEnvExt { const struct JNINativeInterface* funcTable; /* must be first */ const struct JNINativeInterface* baseFuncTable; /* pointer to the VM we are a part of */ struct JavaVMExt* vm; u4 envThreadId; Thread* self; /* if nonzero, we are in a "critical" JNI call */ int critical; /* keep a copy of this here for speed */ bool forceDataCopy; struct JNIEnvExt* prev; struct JNIEnvExt* next; } JNIEnvExt; typedef struct JavaVMExt { const struct JNIInvokeInterface* funcTable; /* must be first */ const struct JNIInvokeInterface* baseFuncTable; /* if multiple VMs are desired, add doubly-linked list stuff here */ /* per-VM feature flags */ bool useChecked; bool warnError; bool forceDataCopy; /* head of list of JNIEnvs associated with this VM */ JNIEnvExt* envList; pthread_mutex_t envListLock; } JavaVMExt; 2011 6 12 14
  • 15. dex 1 dalvik/vm/JarFile.c /* classes.dex * Open a Jar file. It's okay if it's just a Zip archive without all of * the Jar trimmings, but we do insist on finding "classes.dex" inside .odex * or an appropriately-named ".odex" file alongside. * * If "isBootstrap" is not set, the optimizer/verifier regards this DEX as * being part of a different class loader. */ int dvmJarFileOpen(const char* fileName, const char* odexOutputName, JarFile** ppJarFile, bool isBootstrap) { --- /* First, look for a ".odex" alongside the jar file. It will * have the same name/path except for the extension. .odex */ fd = openAlternateSuffix(fileName, "odex", O_RDONLY, &cachedName); .odex --- /* * Pre-created .odex absent or stale. Look inside the jar for a * "classes.dex". */ classes.dex entry = dexZipFindEntry(&archive, kDexInJarName); 2011 6 12 15
  • 16. dex 2 dalvik/vm/JarFile.c /* classes.dex * We've found the one we want. See if there's an up-to-date copy * in the cache. * * On return, "fd" will be seeked just past the "opt" header. ( fd opt * * If a stale .odex file is present and classes.dex exists in ) * the archive, this will *not* return an fd pointing to the ( odex * .odex file; the fd will point into dalvik-cache like any classes.dex fd odex * other jar. */ jar ) if (odexOutputName == NULL) { cachedName = dexOptGenerateCacheFileName(fileName, kDexInJarName); --- /* * If fd points to a new file (because there was no cached version, * or the cached version was stale), generate the optimized DEX. * The file descriptor returned is still locked, and is positioned * just past the optimization header. */ if (newFile) { --- DEX result = dvmOptimizeDexFile(fd, dexOffset, dexGetZipEntryUncompLen(&archive, entry), ( odex?) fileName, dexGetZipEntryModTime(&archive, entry), dexGetZipEntryCrc32(&archive, entry), odex isBootstrap); --- 2011 6 12 16
  • 17. dex 3 dalvik/vm/JarFile.c --- /* * Map the cached version. This immediately rewinds the fd, so it * doesn't have to be seeked anywhere in particular. mmap */ if (dvmDexFileOpenFromFd(fd, &pDvmDex) != 0) { seek --- *ppJarFile = (JarFile*) calloc(1, sizeof(JarFile)); (*ppJarFile)->archive = archive; (*ppJarFile)->cacheFileName = cachedName; (*ppJarFile)->pDvmDex = pDvmDex; --- ( ) dalvik/libdex/SysUtil.c } fd dalvik/DvmDex.c dvmDexFileOpenFromFd() (writable read-only) pDvmDex mmap { mmap prot=PROT_READ | PROT_WRITE SHA-1 flags=MAP_FILE | MAP_PRIVATE (copy-on-write) mprotect } PROT_READ 2011 6 12 17
  • 18. dex dalvik/vm/analysis/DexPrepare.c /* fd * Given a descriptor for a file with DEX data in it, produce an * optimized version. * * The file pointed to by "fd" is expected to be a locked shared resource OK * (or private); we make no efforts to enforce multi-process correctness * here. * * "fileName" is only used for debug output. "modWhen" and "crc" are stored * in the dependency set. * bootstrap * The "isBootstrap" flag determines how the optimizer and verifier handle * package-scope access checks. When optimizing, we only load the bootstrap ※ * class DEX files and the target DEX, so the flag determines whether the * target DEX classes are given a (synthetic) non-NULL classLoader pointer. * This only really matters if the target DEX contains classes that claim to * be in the same package as bootstrap classes. dex * * The optimizer will need to load every class in the target DEX file. * This is generally undesirable, so we start a subprocess to do the * work and wait for it to complete. * * Returns "true" on success. All data will have been written to "fd". ※ */ bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength, const char* fileName, u4 modWhen, u4 crc, bool isBootstrap) fd 2011 6 12 18
  • 19. dex dalvik/vm/analysis/DexPrepare.c bool dvmOptimizeDexFile(int fd, off_t dexOffset, long dexLength, const char* fileName, u4 modWhen, u4 crc, bool isBootstrap) { --- pid = fork(); if (pid == 0) { static const int kUseValgrind = 0; static const char* kDexOptBin = "/bin/dexopt"; ※fork static const char* kValgrinder = "/usr/bin/valgrind"; --- strcpy(execFile, androidRoot); dexopt strcat(execFile, kDexOptBin); execv() --- if (kUseValgrind) dexopt execv(kValgrinder, argv); else execv(execFile, argv); --- } else { ※fork --- /* * Wait for the optimization process to finish. We go into VMWAIT * mode here so GC suspension won't have to wait for us. */ VM VMWAIT oldStatus = dvmChangeStatus(NULL, THREAD_VMWAIT); ※GC --- } } 2011 6 12 19
  • 20. 1( ) dalvik/ vm/ mterp/ gen-mterp.py config-xxx xxx config-yyy yyy config-portstd rebuild.sh xxx/ xxx xxx yyy/ yyy yyy c/ C out/ OP out 2011 6 12 20
  • 21. dalvik/vm/mterp/out/InterpC-portstd.c ( C ) /* File: portable/entry.c */ * Main interpreter loop. bool INTERP_FUNC_NAME(Thread* self, InterpState* interpState) { #define FETCH(_offset) (pc[(_offset)]) --- #define INST_INST(_inst) ((_inst) & 0xff) /* copy state in */ # define HANDLE_OPCODE(_op) case _op: curMethod = interpState->method; # define ADJUST_PC(_offset) do { pc = interpState->pc; pc += _offset; fp = interpState->fp; EXPORT_EXTRA_PC(); --- } while (false) methodClassDex = curMethod->clazz->pDvmDex; # define FINISH(_offset) { ADJUST_PC(_offset); break; } --- while (1) { --- /* fetch the next 16 bits from the instruction stream */ inst = FETCH(0); switch (INST_INST(inst)) { PC( ) (instruction) --- /* File: c/OP_NOP.c */ HANDLE_OPCODE(OP_NOP) OP FINISH(1); OP_END OP case --- PC --- } JNI 2011 6 12 21
  • 22. ( ) Zygote fork dexopt VM ->fork->dex -> JNI JIT ↓ http://silentworlds.info/pukiwiki/ 2011 6 12 22