SlideShare une entreprise Scribd logo
1  sur  22
Télécharger pour lire hors ligne
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

Contenu connexe

Tendances

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 – IPC2012Martin Schuhfuß
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)Sri Prasanna
 
Антон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиАнтон Наумович, Система автоматической крэш-аналитики своими средствами
Антон Наумович, Система автоматической крэш-аналитики своими средствамиSergey Platonov
 
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門
Introduction httpClient on Java11 / Java11時代のHTTPアクセス再入門tamtam180
 
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 hassleAnton Arhipov
 
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 & OCMockRobot Media
 
Unit Testing: Special Cases
Unit Testing: Special CasesUnit Testing: Special Cases
Unit Testing: Special CasesCiklum Ukraine
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrencypriyank09
 
Deep dive into OSGi Lifecycle Layer
Deep dive into OSGi Lifecycle LayerDeep dive into OSGi Lifecycle Layer
Deep dive into OSGi Lifecycle LayerAruna Karunarathna
 
Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Антон Нонко, Классические строки в C++
Антон Нонко, Классические строки в C++Sergey Platonov
 
Non stop random2b
Non stop random2bNon stop random2b
Non stop random2bphanhung20
 
OSGi Training for Carbon Developers
OSGi Training for Carbon DevelopersOSGi Training for Carbon Developers
OSGi Training for Carbon DevelopersAruna Karunarathna
 
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 CollectionsYoshifumi Kawai
 
Automated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xAutomated%20testing%20with%20Espresso2.x
Automated%20testing%20with%20Espresso2.xTatsuya Maki
 
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, howTomasz Polanski
 
Hibernate Import.Sql I18n
Hibernate Import.Sql I18nHibernate Import.Sql I18n
Hibernate Import.Sql I18nyifi2009
 
Exercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera CymbronExercícios Netbeans - Vera Cymbron
Exercícios Netbeans - Vera Cymbroncymbron
 

Tendances (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
 

En vedette

Android session 2-behestee
Android session 2-behesteeAndroid session 2-behestee
Android session 2-behesteeHussain Behestee
 
Form Handling using PHP
Form Handling using PHPForm Handling using PHP
Form Handling using PHPNisa Soomro
 
Android Life Cycle
Android Life CycleAndroid Life Cycle
Android Life Cyclemssaman
 
Android life cycle
Android life cycleAndroid life cycle
Android life cycle瑋琮 林
 
Android Studio NDK(JNI) + OpenCV 完整教學
Android Studio NDK(JNI) + OpenCV 完整教學Android Studio NDK(JNI) + OpenCV 完整教學
Android Studio NDK(JNI) + OpenCV 完整教學Wei-Xiang Wang
 
Android: Intent, Intent Filter, Broadcast Receivers
Android: Intent, Intent Filter, Broadcast ReceiversAndroid: Intent, Intent Filter, Broadcast Receivers
Android: Intent, Intent Filter, Broadcast ReceiversCodeAndroid
 
Android Lesson 3 - Intent
Android Lesson 3 - IntentAndroid Lesson 3 - Intent
Android Lesson 3 - IntentDaniela Da Cruz
 
Android - Broadcast Receiver
Android - Broadcast ReceiverAndroid - Broadcast Receiver
Android - Broadcast ReceiverYong Heui Cho
 
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 pluginXavier Hallade
 

En vedette (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
 

Similaire à Dalvik Source Code Reading

Androidaop 170105090257
Androidaop 170105090257Androidaop 170105090257
Androidaop 170105090257newegg
 
Native Java with GraalVM
Native Java with GraalVMNative Java with GraalVM
Native Java with GraalVMSylvain Wallez
 
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
 
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 OSGiRobert Munteanu
 
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?Doug Hawkins
 
Dropwizard and Friends
Dropwizard and FriendsDropwizard and Friends
Dropwizard and FriendsYun Zhi Lin
 
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'15Murat Yener
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
Unit Testing RPG with JUnit
Unit Testing RPG with JUnitUnit Testing RPG with JUnit
Unit Testing RPG with JUnitGreg.Helton
 
Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)Asynchronous Module Definition (AMD)
Asynchronous Module Definition (AMD)xMartin12
 
201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programing201913046 wahyu septiansyah network programing
201913046 wahyu septiansyah network programingwahyuseptiansyah
 
Jenkins and Groovy
Jenkins and GroovyJenkins and Groovy
Jenkins and GroovyKiyotaka 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.docxmercysuttle
 
How Secure Are Docker Containers?
How Secure Are Docker Containers?How Secure Are Docker Containers?
How Secure Are Docker Containers?Ben Hall
 
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
 
Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)William Farrell
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 

Similaire à 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
 

Plus de kishima7

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 computerkishima7
 
mrubyで作るマイコンボード
mrubyで作るマイコンボードmrubyで作るマイコンボード
mrubyで作るマイコンボードkishima7
 
自分だけのデバイスを作るお話
自分だけのデバイスを作るお話自分だけのデバイスを作るお話
自分だけのデバイスを作るお話kishima7
 
オリジナルmrubyデバイス作り
オリジナルmrubyデバイス作りオリジナルmrubyデバイス作り
オリジナルmrubyデバイス作りkishima7
 
mruby VM を調べてみた話
mruby VM を調べてみた話mruby VM を調べてみた話
mruby VM を調べてみた話kishima7
 
Stairway to my Family mruby
Stairway to my Family mrubyStairway to my Family mruby
Stairway to my Family mrubykishima7
 
VMを改めて学んで見る
VMを改めて学んで見るVMを改めて学んで見る
VMを改めて学んで見るkishima7
 
mruby/cで始めるM5Stack &mrubyスクリプト開発
mruby/cで始めるM5Stack &mrubyスクリプト開発mruby/cで始めるM5Stack &mrubyスクリプト開発
mruby/cで始めるM5Stack &mrubyスクリプト開発kishima7
 
Wio LTEとmruby/cでIoT
Wio LTEとmruby/cでIoTWio LTEとmruby/cでIoT
Wio LTEとmruby/cでIoTkishima7
 
Unityにmrubyを組み込んで抽選をしてみた
Unityにmrubyを組み込んで抽選をしてみたUnityにmrubyを組み込んで抽選をしてみた
Unityにmrubyを組み込んで抽選をしてみたkishima7
 
Introduction of mruby & Webruby script example
Introduction of mruby & Webruby script exampleIntroduction of mruby & Webruby script example
Introduction of mruby & Webruby script examplekishima7
 
Ruby and Android
Ruby and AndroidRuby and Android
Ruby and Androidkishima7
 
Google TV hack
Google TV hackGoogle TV hack
Google TV hackkishima7
 
くみこみからひとことReturns
くみこみからひとことReturnsくみこみからひとことReturns
くみこみからひとことReturnskishima7
 
ネット家電じゃなくて?
ネット家電じゃなくて?ネット家電じゃなくて?
ネット家電じゃなくて?kishima7
 
くみこみからひとこと
くみこみからひとことくみこみからひとこと
くみこみからひとことkishima7
 

Plus 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
 
ネット家電じゃなくて?
ネット家電じゃなくて?ネット家電じゃなくて?
ネット家電じゃなくて?
 
くみこみからひとこと
くみこみからひとことくみこみからひとこと
くみこみからひとこと
 

Dernier

How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesDavid Newbury
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Brian Pichman
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding TeamAdam Moalla
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.YounusS2
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UbiTrack UK
 

Dernier (20)

How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
20150722 - AGV
20150722 - AGV20150722 - AGV
20150722 - AGV
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Linked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond OntologiesLinked Data in Production: Moving Beyond Ontologies
Linked Data in Production: Moving Beyond Ontologies
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )Building Your Own AI Instance (TBLC AI )
Building Your Own AI Instance (TBLC AI )
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team9 Steps For Building Winning Founding Team
9 Steps For Building Winning Founding Team
 
Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.Basic Building Blocks of Internet of Things.
Basic Building Blocks of Internet of Things.
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
UWB Technology for Enhanced Indoor and Outdoor Positioning in Physiological M...
 

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