OSDN Git Service

Merge branch 'readonly-p4-master'
authorUrs Grob <>
Fri, 10 Apr 2009 03:23:57 +0000 (20:23 -0700)
committerThe Android Open Source Project <initial-contribution@android.com>
Fri, 10 Apr 2009 03:23:57 +0000 (20:23 -0700)
19 files changed:
README.txt
dexdump/DexDump.c
dx/README.txt
libcore/icu/src/main/native/ResourceInterface.cpp
libcore/luni/src/main/java/org/apache/harmony/luni/platform/PlatformAddressFactory.java
vm/Android.mk
vm/alloc/MarkSweep.c
vm/analysis/DexVerify.c
vm/arch/arm/CallEABI.S
vm/interp/Interp.c
vm/mterp/out/InterpAsm-x86.S
vm/mterp/x86/OP_INVOKE_DIRECT.S
vm/mterp/x86/OP_INVOKE_INTERFACE.S
vm/mterp/x86/OP_INVOKE_STATIC.S
vm/mterp/x86/OP_INVOKE_SUPER.S
vm/mterp/x86/OP_INVOKE_SUPER_QUICK.S
vm/mterp/x86/OP_INVOKE_VIRTUAL.S
vm/mterp/x86/OP_INVOKE_VIRTUAL_QUICK.S
vm/mterp/x86/footer.S

index 6955945..a7dd7da 100644 (file)
@@ -1,5 +1,5 @@
-This directory contains the Dalvik virtual machine and associated
-class library.
+This directory contains the Dalvik virtual machine and core class library,
+as well as related tools, libraries, and tests.
 
 A note about the licenses and header comments
 ---------------------------------------------
index 938f072..bd91236 100644 (file)
@@ -477,10 +477,6 @@ const char* getClassDescriptor(DexFile* pDexFile, u4 classIdx)
 void dumpInstruction(DexFile* pDexFile, const DexCode* pCode, int insnIdx,
     int insnWidth, const DecodedInstruction* pDecInsn)
 {
-    static const float gSpecialTab[16] = {
-        -2.0f, -1.0f, -0.5f, -0.25f, -0.1f, 0.1f, 0.25f, 0.5f,
-        1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 10.0f, 100.0f, 1000.0f
-    };
     const u2* insns = pCode->insns;
     int i;
 
index 5421e7b..6a20c82 100644 (file)
@@ -1,2 +1,3 @@
 Home of Dalvik eXchange, the thing that takes in class files and
-reformulates them for consumption in the VM.
+reformulates them for consumption in the VM. It also does a few other
+things; use "dx --help" to see a modicum of self-documentation.
index 5f9d442..442d688 100644 (file)
@@ -1207,7 +1207,8 @@ endOfCalendar:
         intCurrencySymbol = env->NewStringUTF("XXX");
     }
     if(currencySymbol == NULL) {
-        currencySymbol = env->NewStringUTF("\u00a4");
+        // creating a new string explicitly with the UTF-8 encoding of "\u00a4"
+        currencySymbol = env->NewStringUTF("\xc2\xa4");
     }
     counter += 2;
 
index 5c31980..9ec0fcd 100644 (file)
@@ -24,13 +24,61 @@ import java.io.IOException;
 
 public class PlatformAddressFactory {
 
-    public static PlatformAddress on(int value) {
-        return PlatformAddressFactory.on(value, PlatformAddress.UNKNOWN);
+    // BEGIN android-added
+    /**
+     * Defines the number of PlatformAddress objects to be cached. Must be a
+     * power of two. Caching PlatformAddress objects minimizes the creation
+     * of garbage and reduces the number of GC-hiccups in OpenGL animations.
+     */
+    private final static int CACHE_SIZE = 1<<8;
+
+    /**
+     * A mask with all bits set, matching the size of the cache.
+     */
+    private final static int CACHE_MASK = CACHE_SIZE - 1;
+
+    /**
+     * Defines the maximum number of probes taken per hash, used for looking
+     * up an empty cache slot or a previously stored PlatformAddress.
+     */
+    private final static int MAX_PROBES = 5;
+
+    /**
+     * A cycling index (0 to MAX_PROBES-1) used to replace elements in the cache.
+     */
+    private static int replacementIndex = 0;
+
+    /**
+     * Array of PlatformAddress references kept from garbage collection.
+     */
+    private static PlatformAddress[] cache = new PlatformAddress[CACHE_SIZE];
+    // END android-added
+
+
+    // BEGIN android-changed
+    public synchronized static PlatformAddress on(int value, long size) {
+        if (value == 0) {
+            return PlatformAddress.NULL;
+        }
+        int idx = value >> 5;
+        for (int probe = 0; probe < MAX_PROBES; probe++) {
+            PlatformAddress cachedObj = cache[(idx + probe) & CACHE_MASK];
+            if (cachedObj == null) {
+                return cache[(idx + probe) & CACHE_MASK] =
+                    new PlatformAddress(value, size);
+            }
+            if (cachedObj.osaddr == value && cachedObj.size == size) {
+                return cachedObj;
+            }
+        }
+        replacementIndex = (replacementIndex + 1) % MAX_PROBES;
+        return cache[(idx + replacementIndex) & CACHE_MASK] =
+            new PlatformAddress(value, size);
     }
+    // END android-changed
 
-    public static PlatformAddress on(int value, long size) {
-        PlatformAddress addr = (value == 0) ? PlatformAddress.NULL : new PlatformAddress(value, size);
-        return addr;
+    public static PlatformAddress on(int value) {
+        return PlatformAddressFactory.on(value, PlatformAddress.UNKNOWN);
     }
 
     public static MappedPlatformAddress mapOn(int value, long size) {
index 1c3a052..faf2b7c 100644 (file)
@@ -232,10 +232,23 @@ ifeq ($(TARGET_ARCH),arm)
                arch/arm/CallOldABI.S \
                arch/arm/CallEABI.S \
                arch/arm/HintsEABI.c
-  # TODO: select sources for ARMv4 vs. ARMv5TE
-  LOCAL_SRC_FILES += \
-               mterp/out/InterpC-armv5te.c.arm \
-               mterp/out/InterpAsm-armv5te.S
+  #
+  # The armv4 configation in mterp is actually armv4t, it's just
+  # wrongly named
+  #
+  # TODO: Rename mterp/config-armv4 and mterp/armv4 (to armv4t)
+  #       then remove this ifeq.
+  #
+  ifeq ($(TARGET_ARCH_VERSION),armv4t)
+    LOCAL_SRC_FILES += \
+               mterp/out/InterpC-armv4.c.arm \
+               mterp/out/InterpAsm-armv4.S
+  else
+    # Select architecture specific sources (armv4,armv5te etc)
+    LOCAL_SRC_FILES += \
+               mterp/out/InterpC-$(TARGET_ARCH_VERSION).c.arm \
+               mterp/out/InterpAsm-$(TARGET_ARCH_VERSION).S
+  endif
   LOCAL_SHARED_LIBRARIES += libdl
 else
   ifeq ($(TARGET_ARCH),x86)
index 0905bce..84349a9 100644 (file)
@@ -524,6 +524,17 @@ static void scanObject(const Object *obj, GcMarkContext *ctx)
     }
 #endif
 
+#if WITH_OBJECT_HEADERS
+    if (ptr2chunk(obj)->scanGeneration == gGeneration) {
+        LOGE("object 0x%08x was already scanned this generation\n",
+                (uintptr_t)obj);
+        dvmAbort();
+    }
+    ptr2chunk(obj)->oldScanGeneration = ptr2chunk(obj)->scanGeneration;
+    ptr2chunk(obj)->scanGeneration = gGeneration;
+    ptr2chunk(obj)->scanCount++;
+#endif
+
     /* Get and mark the class object for this particular instance.
      */
     clazz = obj->clazz;
@@ -544,16 +555,9 @@ static void scanObject(const Object *obj, GcMarkContext *ctx)
          */
         return;
     }
+
 #if WITH_OBJECT_HEADERS
     gMarkParent = obj;
-    if (ptr2chunk(obj)->scanGeneration == gGeneration) {
-        LOGE("object 0x%08x was already scanned this generation\n",
-                (uintptr_t)obj);
-        dvmAbort();
-    }
-    ptr2chunk(obj)->oldScanGeneration = ptr2chunk(obj)->scanGeneration;
-    ptr2chunk(obj)->scanGeneration = gGeneration;
-    ptr2chunk(obj)->scanCount++;
 #endif
 
     assert(dvmIsValidObject((Object *)clazz));
index 84f34c8..25075f4 100644 (file)
@@ -40,7 +40,7 @@ bool dvmVerificationStartup(void)
 }
 
 /*
- * Initialize some things we need for verification.
+ * Free up some things we needed for verification.
  */
 void dvmVerificationShutdown(void)
 {
index a98473f..25441f4 100644 (file)
@@ -239,7 +239,12 @@ DBG strcs   ip, [r8]                    @ DEBUG DEBUG
 
     @ call the method
     ldr     ip, [r4, #8]                @ func
+#ifdef __ARM_HAVE_BLX
     blx     ip
+#else
+    mov     lr, pc
+    bx      ip
+#endif
 
     @ We're back, result is in r0 or (for long/double) r0-r1.
     @
index 27b9582..d2643de 100644 (file)
@@ -389,6 +389,7 @@ static inline s4 s4FromSwitchData(const void* switchData) {
 static inline s4 s4FromSwitchData(const void* switchData) {
     u2* data = switchData;
     return data[0] | (((s4) data[1]) << 16);
+}
 #endif
 
 /*
index 0fd3e42..6d29a8e 100644 (file)
@@ -2852,9 +2852,7 @@ dvmAsmInstructionStart = .L_OP_NOP
 .LOP_INVOKE_DIRECT_finish:
     UNSPILL(rPC)
     testl     %ecx,%ecx                # null "this"?
-    movl      $0,%ecx
-    #jne       common_invokeMethodNoRange  # no, continue on
-    jne       common_invokeOld          # no, continue on, eax<- method, ecx<- methodCallRange
+    jne       common_invokeMethodNoRange  # no, continue on
     jmp       common_errNullObject
 
 /* ------------------------------ */
@@ -2874,10 +2872,8 @@ dvmAsmInstructionStart = .L_OP_NOP
     EXPORT_PC()
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
-    movl      $0,%ecx           # needed by common_invokeOld - revisit
     testl     %eax,%eax
-    #jne       common_invokeMethodNoRange
-    jne       common_invokeOld
+    jne       common_invokeMethodNoRange
     GET_GLUE(%ecx)
     movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
     movzwl    2(rPC),%eax
@@ -3019,9 +3015,7 @@ dvmAsmInstructionStart = .L_OP_NOP
 .LOP_INVOKE_DIRECT_RANGE_finish:
     UNSPILL(rPC)
     testl     %ecx,%ecx                # null "this"?
-    movl      $1,%ecx
-    #jne       common_invokeMethodRange  # no, continue on
-    jne       common_invokeOld          # no, continue on, eax<- method, ecx<- methodCallRange
+    jne       common_invokeMethodRange  # no, continue on
     jmp       common_errNullObject
 
 
@@ -3043,10 +3037,8 @@ dvmAsmInstructionStart = .L_OP_NOP
     EXPORT_PC()
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
-    movl      $1,%ecx           # needed by common_invokeOld - revisit
     testl     %eax,%eax
-    #jne       common_invokeMethodRange
-    jne       common_invokeOld
+    jne       common_invokeMethodRange
     GET_GLUE(%ecx)
     movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
     movzwl    2(rPC),%eax
@@ -6027,9 +6019,8 @@ dvmAsmInstructionStart = .L_OP_NOP
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC()                         # might throw later - get ready
     movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
-    movl      $0,%ecx           # pass range flag
-    #jmp       common_invokeMethodNoRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodNoRange
+
 
 
 /* ------------------------------ */
@@ -6056,9 +6047,8 @@ dvmAsmInstructionStart = .L_OP_NOP
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC()                         # might throw later - get ready
     movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
-    movl      $1,%ecx           # pass range flag
-    #jmp       common_invokeMethodRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodRange
+
 
 
 
@@ -6088,9 +6078,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC()
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
-    movl      $0,%ecx           # ecx<- range flag
-    #jmp       common_invokeMethodNoRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodNoRange
 
 
 /* ------------------------------ */
@@ -6120,9 +6108,7 @@ dvmAsmInstructionStart = .L_OP_NOP
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC()
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
-    movl      $1,%ecx           # ecx<- range flag
-    #jmp       common_invokeMethodRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodRange
 
 
 
@@ -7669,9 +7655,7 @@ dvmAsmSisterStart:
     movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
     movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
-    movl      $0,%ecx           # needed for common_invokeOld
-    #jmp       common_invokeMethodNoRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodNoRange
 
 
 /* continuation for OP_INVOKE_SUPER */
@@ -7688,9 +7672,8 @@ dvmAsmSisterStart:
     jae     .LOP_INVOKE_SUPER_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
-    movl    $0,%ecx
-    #jmp     common_invokeMethodNoRange
-    jmp     common_invokeOld
+    jmp     common_invokeMethodNoRange
+
 
     /* At this point:
      * ecx = null (needs to be resolved base method)
@@ -7753,10 +7736,8 @@ dvmAsmSisterStart:
     SPILL(rPC)
     call      dvmResolveMethod          # call(clazz,ref,flags)
     UNSPILL(rPC)
-    movl      $0,%ecx
     testl     %eax,%eax                 # got null?
-    #jne       common_invokeMethodNoRange
-    jne       common_invokeOld
+    jne       common_invokeMethodNoRange
     jmp       common_exceptionThrown
 
 
@@ -7767,9 +7748,7 @@ dvmAsmSisterStart:
     UNSPILL(rPC)
     testl      %eax,%eax
     je         common_exceptionThrown
-    movl       $0,%ecx
-    #jmp        common_invokeMethodNoRange
-    jmp        common_invokeOld
+    jmp        common_invokeMethodNoRange
 
 
 /* continuation for OP_INVOKE_VIRTUAL_RANGE */
@@ -7801,9 +7780,7 @@ dvmAsmSisterStart:
     movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
     movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
-    movl      $1,%ecx           # needed for common_invokeOld
-    #jmp       common_invokeMethodRange
-    jmp       common_invokeOld
+    jmp       common_invokeMethodRange
 
 
 /* continuation for OP_INVOKE_SUPER_RANGE */
@@ -7820,9 +7797,8 @@ dvmAsmSisterStart:
     jae     .LOP_INVOKE_SUPER_RANGE_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
-    movl    $1,%ecx
-    #jmp     common_invokeMethodRange
-    jmp     common_invokeOld
+    jmp     common_invokeMethodRange
+
 
     /* At this point:
      * ecx = null (needs to be resolved base method)
@@ -7885,10 +7861,8 @@ dvmAsmSisterStart:
     SPILL(rPC)
     call      dvmResolveMethod          # call(clazz,ref,flags)
     UNSPILL(rPC)
-    movl      $1,%ecx
     testl     %eax,%eax                 # got null?
-    #jne       common_invokeMethodRange
-    jne       common_invokeOld
+    jne       common_invokeMethodRange
     jmp       common_exceptionThrown
 
 
@@ -7899,9 +7873,7 @@ dvmAsmSisterStart:
     UNSPILL(rPC)
     testl      %eax,%eax
     je         common_exceptionThrown
-    movl       $1,%ecx
-    #jmp        common_invokeMethodRange
-    jmp        common_invokeOld
+    jmp        common_invokeMethodRange
 
 
 /* continuation for OP_FLOAT_TO_INT */
@@ -8535,11 +8507,217 @@ dvmMterpStdBail:
  */
 common_backwardBranch:
     GET_GLUE(%ecx)
-    call   common_periodicChecks      # Note: expects rPC to be preserved
+    call   common_periodicChecks  # Note: expects rPC to be preserved
     ADVANCE_PC_INDEXED(rINST_FULL)
     FETCH_INST()
     GOTO_NEXT
 
+
+
+/*
+ * Common code for method invocation with range.
+ *
+ * On entry:
+ *   eax = Method* methodToCall
+ *   rINST trashed, must reload
+ */
+
+common_invokeMethodRange:
+.LinvokeNewRange:
+
+   /*
+    * prepare to copy args to "outs" area of current frame
+    */
+
+    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- AA
+    movzwl      4(rPC), %ecx            # %ecx<- CCCC
+    SPILL(rPC)
+    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
+    test        rINST_FULL, rINST_FULL
+    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
+    jz          .LinvokeArgsDone        # no args; jump to args done
+
+
+   /*
+    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea)
+    * (very few methods have > 10 args; could unroll for common cases)
+    */
+
+    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
+    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
+    shll        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
+    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
+    shrl        $2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
+1:
+    movl        (%ecx), %ebx            # %ebx<- vCCCC
+    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
+    subl        $1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
+    movl        %ebx, (%edx)            # *outs<- vCCCC
+    lea         4(%edx), %edx           # outs++
+    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
+    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
+    jmp         .LinvokeArgsDone        # continue
+
+   /*
+    * %eax is "Method* methodToCall", the method we're trying to call
+    * prepare to copy args to "outs" area of current frame
+    */
+
+common_invokeMethodNoRange:
+.LinvokeNewNoRange:
+    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- BA
+    SPILL(rPC)
+    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
+    shrl        $4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
+    je          .LinvokeArgsDone        # no args; jump to args done
+    movzwl      4(rPC), %ecx            # %ecx<- GFED
+    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
+
+   /*
+    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
+    */
+
+.LinvokeNonRange:
+    cmp         $2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
+    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
+    jl          1f                      # handle 1 arg
+    je          2f                      # handle 2 args
+    cmp         $4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
+    jl          3f                      # handle 3 args
+    je          4f                      # handle 4 args
+5:
+    andl        $15, rINST_FULL        # rINST<- A
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, rINST_FULL, 4), %ecx # %ecx<- vA
+    movl        %ecx, (%edx)            # *outs<- vA
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+4:
+    shr         $12, %ecx              # %ecx<- G
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
+    movl        %ecx, (%edx)            # *outs<- vG
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+3:
+    and         $0x0f00, %ecx          # %ecx<- 0F00
+    shr         $8, %ecx               # %ecx<- F
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
+    movl        %ecx, (%edx)            # *outs<- vF
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+2:
+    and         $0x00f0, %ecx          # %ecx<- 00E0
+    shr         $4, %ecx               # %ecx<- E
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
+    movl        %ecx, (%edx)            # *outs<- vE
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+1:
+    and         $0x000f, %ecx          # %ecx<- 000D
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
+    movl        %ecx, -4(%edx)          # *--outs<- vD
+0:
+
+   /*
+    * %eax is "Method* methodToCall", the method we're trying to call
+    * find space for the new stack frame, check for overflow
+    */
+
+.LinvokeArgsDone:
+    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
+    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
+    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
+    shl         $2, %edx               # %edx<- update offset
+    SAVEAREA_FROM_FP(%eax,rFP)          # %eax<- &StackSaveArea
+    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
+    GET_GLUE(%edx)                      # %edx<- pMterpGlue
+    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
+    subl        $sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
+    movl        offGlue_interpStackEnd(%edx), %edx # %edx<- glue->interpStackEnd
+    movl        %edx, LOCAL2_OFFSET(%ebp)       # LOCAL2_OFFSET<- glue->interpStackEnd
+    shl         $2, %ecx               # %ecx<- update offset for outsSize
+    movl        %eax, %edx              # %edx<- newSaveArea
+    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
+    cmp         LOCAL2_OFFSET(%ebp), %eax       # compare interpStackEnd and bottom
+    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
+    jl          .LstackOverflow         # handle frame overflow
+
+   /*
+    * set up newSaveArea
+    */
+
+#ifdef EASY_GDB
+    SAVEAREA_FROM_FP(%ecx,rFP)          # %ecx<- &StackSaveArea
+    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
+#endif
+    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
+    movl        rPC_SPILL(%ebp), %ecx
+    movl        %ecx, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
+    testl       $ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
+    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
+    jne         .LinvokeNative          # handle native call
+
+   /*
+    * Update "glue" values for the new method
+    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
+    */
+
+    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
+    movl        %eax, offGlue_method(%ecx) # glue->method<- methodToCall
+    movl        %edx, offGlue_methodClassDex(%ecx) # glue->methodClassDex<- method->clazz->pDvmDex
+    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
+    movl        offGlue_self(%ecx), %eax # %eax<- glue->self
+    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- newFP
+    FETCH_INST()
+    GOTO_NEXT                           # jump to methodToCall->insns
+
+   /*
+    * Prep for the native call
+    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea
+    */
+
+.LinvokeNative:
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
+    movl        offGlue_self(%ecx), %ecx        # %ecx<- glue->self
+    movl        offThread_jniLocal_nextEntry(%ecx), %eax # %eax<- glue->self->thread->refNext
+    movl        %eax, offStackSaveArea_localRefTop(%edx) # newSaveArea->localRefTop<- refNext
+    movl        %edx, OUT_ARG4(%esp)    # save newSaveArea
+    movl        LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP
+    movl        %edx, offThread_curFrame(%ecx)  # glue->self->curFrame<- newFP
+    movl        %ecx, OUT_ARG3(%esp)    # save glue->self
+    movl        %ecx, OUT_ARG2(%esp)    # push parameter glue->self
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        OUT_ARG1(%esp), %eax    # %eax<- methodToCall
+    lea         offGlue_retval(%ecx), %ecx # %ecx<- &retval
+    movl        %ecx, OUT_ARG0(%esp)    # push parameter pMterpGlue
+    push        %edx                    # push parameter newFP
+
+    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
+    lea         4(%esp), %esp
+    movl        OUT_ARG4(%esp), %ecx    # %ecx<- newSaveArea
+    movl        OUT_ARG3(%esp), %eax    # %eax<- glue->self
+    movl        offStackSaveArea_localRefTop(%ecx), %edx # %edx<- newSaveArea->localRefTop
+    cmp         $0, offThread_exception(%eax) # check for exception
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
+    movl        %edx, offThread_jniLocal_nextEntry(%eax) # glue->self<- newSaveArea->localRefTop
+    UNSPILL(rPC)
+    jne         common_exceptionThrown  # handle exception
+    FETCH_INST_WORD(3)
+    ADVANCE_PC(3)
+    GOTO_NEXT                           # jump to next instruction
+
+.LstackOverflow:
+    GET_GLUE(%eax)                      # %eax<- pMterpGlue
+    movl        offGlue_self(%eax), %eax # %eax<- glue->self
+    movl        %eax, OUT_ARG0(%esp)    # push parameter self
+    call        dvmHandleStackOverflow  # call: (Thread* self)
+    UNSPILL(rPC)                        # return: void
+    jmp         common_exceptionThrown  # handle exception
+
+
 /*
  * Common invoke code (old-style).
  * TUNING:  Rewrite along lines of new armv5 code?
index a772540..f423dc3 100644 (file)
@@ -30,9 +30,7 @@
 .L${opcode}_finish:
     UNSPILL(rPC)
     testl     %ecx,%ecx                # null "this"?
-    movl      $$$isrange,%ecx
-    #jne       common_invokeMethod${routine}  # no, continue on
-    jne       common_invokeOld          # no, continue on, eax<- method, ecx<- methodCallRange
+    jne       common_invokeMethod${routine}  # no, continue on
     jmp       common_errNullObject
 %break
 
index 02dc76f..1631177 100644 (file)
@@ -35,7 +35,5 @@
     UNSPILL(rPC)
     testl      %eax,%eax
     je         common_exceptionThrown
-    movl       $$$isrange,%ecx
-    #jmp        common_invokeMethod${routine}
-    jmp        common_invokeOld
+    jmp        common_invokeMethod${routine}
 
index c65fc1f..40dac06 100644 (file)
     EXPORT_PC()
     movl      offDvmDex_pResMethods(%ecx),%ecx  # ecx<- pDvmDex->pResMethods
     movl      (%ecx,%eax,4),%eax        # eax<- resolved methodToCall
-    movl      $$$isrange,%ecx           # needed by common_invokeOld - revisit
     testl     %eax,%eax
-    #jne       common_invokeMethod${routine}
-    jne       common_invokeOld
+    jne       common_invokeMethod${routine}
     GET_GLUE(%ecx)
     movl      offGlue_method(%ecx),%ecx # ecx<- glue->method
     movzwl    2(rPC),%eax
@@ -33,9 +31,7 @@
     SPILL(rPC)
     call      dvmResolveMethod          # call(clazz,ref,flags)
     UNSPILL(rPC)
-    movl      $$$isrange,%ecx
     testl     %eax,%eax                 # got null?
-    #jne       common_invokeMethod${routine}
-    jne       common_invokeOld
+    jne       common_invokeMethod${routine}
     jmp       common_exceptionThrown
 
index d0a6ad6..013fc01 100644 (file)
@@ -40,9 +40,8 @@
     jae     .L${opcode}_nsm           # method not present in superclass
     movl    offClassObject_vtable(%eax),%eax   # eax<- ...clazz->super->vtable
     movl    (%eax,%ecx,4),%eax        # eax<- vtable[methodIndex]
-    movl    $$$isrange,%ecx
-    #jmp     common_invokeMethod${routine}
-    jmp     common_invokeOld
+    jmp     common_invokeMethod${routine}
+
 
     /* At this point:
      * ecx = null (needs to be resolved base method)
index b050c82..7545eb0 100644 (file)
@@ -23,7 +23,5 @@
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- vtable
     EXPORT_PC()
     movl      (%ecx,%eax,4),%eax        # eax<- super->vtable[BBBB]
-    movl      $$$isrange,%ecx           # ecx<- range flag
-    #jmp       common_invokeMethod${routine}
-    jmp       common_invokeOld
+    jmp       common_invokeMethod${routine}
 
index 6d32a81..20d9120 100644 (file)
@@ -52,7 +52,5 @@
     movl      offObject_clazz(%ecx),%ecx  # ecx<- thisPtr->clazz
     movl      offClassObject_vtable(%ecx),%ecx # ecx<- thisPtr->clazz->vtable
     movl      (%ecx,%eax,4),%eax        # eax<- vtable[methodIndex]
-    movl      $$$isrange,%ecx           # needed for common_invokeOld
-    #jmp       common_invokeMethod${routine}
-    jmp       common_invokeOld
+    jmp       common_invokeMethod${routine}
 
index d197f29..f36ed2d 100644 (file)
@@ -20,7 +20,6 @@
     movl      offClassObject_vtable(%eax),%eax # eax<- thisPtr->clazz->vtable
     EXPORT_PC()                         # might throw later - get ready
     movl      (%eax,%ecx,4),%eax        # eax<- vtable[BBBB]
-    movl      $$$isrange,%ecx           # pass range flag
-    #jmp       common_invokeMethod${routine}
-    jmp       common_invokeOld
+    jmp       common_invokeMethod${routine}
+
 
index a3efc0e..d86207a 100644 (file)
  */
 common_backwardBranch:
     GET_GLUE(%ecx)
-    call   common_periodicChecks      # Note: expects rPC to be preserved
+    call   common_periodicChecks  # Note: expects rPC to be preserved
     ADVANCE_PC_INDEXED(rINST_FULL)
     FETCH_INST()
     GOTO_NEXT
 
+
+
+/*
+ * Common code for method invocation with range.
+ *
+ * On entry:
+ *   eax = Method* methodToCall
+ *   rINST trashed, must reload
+ */
+
+common_invokeMethodRange:
+.LinvokeNewRange:
+
+   /*
+    * prepare to copy args to "outs" area of current frame
+    */
+
+    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- AA
+    movzwl      4(rPC), %ecx            # %ecx<- CCCC
+    SPILL(rPC)
+    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
+    test        rINST_FULL, rINST_FULL
+    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- AA
+    jz          .LinvokeArgsDone        # no args; jump to args done
+
+
+   /*
+    * %eax=methodToCall, %ecx=CCCC, LOCAL0_OFFSET(%ebp)=count, %edx=&outs (&stackSaveArea)
+    * (very few methods have > 10 args; could unroll for common cases)
+    */
+
+    movl        %ebx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- save %ebx
+    lea         (rFP, %ecx, 4), %ecx    # %ecx<- &vCCCC
+    shll        $$2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
+    subl        LOCAL0_OFFSET(%ebp), %edx       # %edx<- update &outs
+    shrl        $$2, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- offset
+1:
+    movl        (%ecx), %ebx            # %ebx<- vCCCC
+    lea         4(%ecx), %ecx           # %ecx<- &vCCCC++
+    subl        $$1, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET<- LOCAL0_OFFSET--
+    movl        %ebx, (%edx)            # *outs<- vCCCC
+    lea         4(%edx), %edx           # outs++
+    jne         1b                      # loop if count (LOCAL0_OFFSET(%ebp)) not zero
+    movl        LOCAL1_OFFSET(%ebp), %ebx       # %ebx<- restore %ebx
+    jmp         .LinvokeArgsDone        # continue
+
+   /*
+    * %eax is "Method* methodToCall", the method we're trying to call
+    * prepare to copy args to "outs" area of current frame
+    */
+
+common_invokeMethodNoRange:
+.LinvokeNewNoRange:
+    movzbl      1(rPC),rINST_FULL       # rINST_FULL<- BA
+    SPILL(rPC)
+    movl        rINST_FULL, LOCAL0_OFFSET(%ebp) # LOCAL0_OFFSET(%ebp)<- BA
+    shrl        $$4, LOCAL0_OFFSET(%ebp)        # LOCAL0_OFFSET(%ebp)<- B
+    je          .LinvokeArgsDone        # no args; jump to args done
+    movzwl      4(rPC), %ecx            # %ecx<- GFED
+    SAVEAREA_FROM_FP(%edx,rFP)          # %edx<- &StackSaveArea
+
+   /*
+    * %eax=methodToCall, %ecx=GFED, LOCAL0_OFFSET(%ebp)=count, %edx=outs
+    */
+
+.LinvokeNonRange:
+    cmp         $$2, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 2
+    movl        %ecx, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- GFED
+    jl          1f                      # handle 1 arg
+    je          2f                      # handle 2 args
+    cmp         $$4, LOCAL0_OFFSET(%ebp)        # compare LOCAL0_OFFSET(%ebp) to 4
+    jl          3f                      # handle 3 args
+    je          4f                      # handle 4 args
+5:
+    andl        $$15, rINST_FULL        # rINST<- A
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, rINST_FULL, 4), %ecx # %ecx<- vA
+    movl        %ecx, (%edx)            # *outs<- vA
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+4:
+    shr         $$12, %ecx              # %ecx<- G
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vG
+    movl        %ecx, (%edx)            # *outs<- vG
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+3:
+    and         $$0x0f00, %ecx          # %ecx<- 0F00
+    shr         $$8, %ecx               # %ecx<- F
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vF
+    movl        %ecx, (%edx)            # *outs<- vF
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+2:
+    and         $$0x00f0, %ecx          # %ecx<- 00E0
+    shr         $$4, %ecx               # %ecx<- E
+    lea         -4(%edx), %edx          # %edx<- update &outs; &outs--
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vE
+    movl        %ecx, (%edx)            # *outs<- vE
+    movl        LOCAL1_OFFSET(%ebp), %ecx       # %ecx<- GFED
+1:
+    and         $$0x000f, %ecx          # %ecx<- 000D
+    movl        (rFP, %ecx, 4), %ecx    # %ecx<- vD
+    movl        %ecx, -4(%edx)          # *--outs<- vD
+0:
+
+   /*
+    * %eax is "Method* methodToCall", the method we're trying to call
+    * find space for the new stack frame, check for overflow
+    */
+
+.LinvokeArgsDone:
+    movzwl      offMethod_registersSize(%eax), %edx # %edx<- methodToCall->regsSize
+    movzwl      offMethod_outsSize(%eax), %ecx # %ecx<- methodToCall->outsSize
+    movl        %eax, LOCAL0_OFFSET(%ebp)       # LOCAL0_OFFSET<- methodToCall
+    shl         $$2, %edx               # %edx<- update offset
+    SAVEAREA_FROM_FP(%eax,rFP)          # %eax<- &StackSaveArea
+    subl        %edx, %eax              # %eax<- newFP; (old savearea - regsSize)
+    GET_GLUE(%edx)                      # %edx<- pMterpGlue
+    movl        %eax, LOCAL1_OFFSET(%ebp)       # LOCAL1_OFFSET(%ebp)<- &outs
+    subl        $$sizeofStackSaveArea, %eax # %eax<- newSaveArea (stack save area using newFP)
+    movl        offGlue_interpStackEnd(%edx), %edx # %edx<- glue->interpStackEnd
+    movl        %edx, LOCAL2_OFFSET(%ebp)       # LOCAL2_OFFSET<- glue->interpStackEnd
+    shl         $$2, %ecx               # %ecx<- update offset for outsSize
+    movl        %eax, %edx              # %edx<- newSaveArea
+    sub         %ecx, %eax              # %eax<- bottom; (newSaveArea - outsSize)
+    cmp         LOCAL2_OFFSET(%ebp), %eax       # compare interpStackEnd and bottom
+    movl        LOCAL0_OFFSET(%ebp), %eax       # %eax<- restore methodToCall
+    jl          .LstackOverflow         # handle frame overflow
+
+   /*
+    * set up newSaveArea
+    */
+
+#ifdef EASY_GDB
+    SAVEAREA_FROM_FP(%ecx,rFP)          # %ecx<- &StackSaveArea
+    movl        %ecx, offStackSaveArea_prevSave(%edx) # newSaveArea->prevSave<- &outs
+#endif
+    movl        rFP, offStackSaveArea_prevFrame(%edx) # newSaveArea->prevFrame<- rFP
+    movl        rPC_SPILL(%ebp), %ecx
+    movl        %ecx, offStackSaveArea_savedPc(%edx) # newSaveArea->savedPc<- rPC
+    testl       $$ACC_NATIVE, offMethod_accessFlags(%eax) # check for native call
+    movl        %eax, offStackSaveArea_method(%edx) # newSaveArea->method<- method to call
+    jne         .LinvokeNative          # handle native call
+
+   /*
+    * Update "glue" values for the new method
+    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFp
+    */
+
+    movl        offMethod_clazz(%eax), %edx # %edx<- method->clazz
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        offClassObject_pDvmDex(%edx), %edx # %edx<- method->clazz->pDvmDex
+    movl        %eax, offGlue_method(%ecx) # glue->method<- methodToCall
+    movl        %edx, offGlue_methodClassDex(%ecx) # glue->methodClassDex<- method->clazz->pDvmDex
+    movl        offMethod_insns(%eax), rPC # rPC<- methodToCall->insns
+    movl        offGlue_self(%ecx), %eax # %eax<- glue->self
+    movl        LOCAL1_OFFSET(%ebp), rFP # rFP<- newFP
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- newFP
+    FETCH_INST()
+    GOTO_NEXT                           # jump to methodToCall->insns
+
+   /*
+    * Prep for the native call
+    * %eax=methodToCall, LOCAL1_OFFSET(%ebp)=newFP, %edx=newSaveArea
+    */
+
+.LinvokeNative:
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        %eax, OUT_ARG1(%esp)    # push parameter methodToCall
+    movl        offGlue_self(%ecx), %ecx        # %ecx<- glue->self
+    movl        offThread_jniLocal_nextEntry(%ecx), %eax # %eax<- glue->self->thread->refNext
+    movl        %eax, offStackSaveArea_localRefTop(%edx) # newSaveArea->localRefTop<- refNext
+    movl        %edx, OUT_ARG4(%esp)    # save newSaveArea
+    movl        LOCAL1_OFFSET(%ebp), %edx # %edx<- newFP
+    movl        %edx, offThread_curFrame(%ecx)  # glue->self->curFrame<- newFP
+    movl        %ecx, OUT_ARG3(%esp)    # save glue->self
+    movl        %ecx, OUT_ARG2(%esp)    # push parameter glue->self
+    GET_GLUE(%ecx)                      # %ecx<- pMterpGlue
+    movl        OUT_ARG1(%esp), %eax    # %eax<- methodToCall
+    lea         offGlue_retval(%ecx), %ecx # %ecx<- &retval
+    movl        %ecx, OUT_ARG0(%esp)    # push parameter pMterpGlue
+    push        %edx                    # push parameter newFP
+
+    call        *offMethod_nativeFunc(%eax) # call methodToCall->nativeFunc
+    lea         4(%esp), %esp
+    movl        OUT_ARG4(%esp), %ecx    # %ecx<- newSaveArea
+    movl        OUT_ARG3(%esp), %eax    # %eax<- glue->self
+    movl        offStackSaveArea_localRefTop(%ecx), %edx # %edx<- newSaveArea->localRefTop
+    cmp         $$0, offThread_exception(%eax) # check for exception
+    movl        rFP, offThread_curFrame(%eax) # glue->self->curFrame<- rFP
+    movl        %edx, offThread_jniLocal_nextEntry(%eax) # glue->self<- newSaveArea->localRefTop
+    UNSPILL(rPC)
+    jne         common_exceptionThrown  # handle exception
+    FETCH_INST_WORD(3)
+    ADVANCE_PC(3)
+    GOTO_NEXT                           # jump to next instruction
+
+.LstackOverflow:
+    GET_GLUE(%eax)                      # %eax<- pMterpGlue
+    movl        offGlue_self(%eax), %eax # %eax<- glue->self
+    movl        %eax, OUT_ARG0(%esp)    # push parameter self
+    call        dvmHandleStackOverflow  # call: (Thread* self)
+    UNSPILL(rPC)                        # return: void
+    jmp         common_exceptionThrown  # handle exception
+
+
 /*
  * Common invoke code (old-style).
  * TUNING:  Rewrite along lines of new armv5 code?