SlideShare ist ein Scribd-Unternehmen logo
1 von 22
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Andere mochten auch

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
 

Andere mochten auch (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Mehr von 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
 

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

Kürzlich hochgeladen

Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 

Kürzlich hochgeladen (20)

Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 

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