OSDN Git Service

am 80d118ae: Revert "[JIT] Fix volatile test" - breaks build
authorJoe Onorato <joeo@google.com>
Fri, 8 Apr 2011 22:36:31 +0000 (15:36 -0700)
committerAndroid Git Automerger <android-git-automerger@android.com>
Fri, 8 Apr 2011 22:36:31 +0000 (15:36 -0700)
* commit '80d118aefbba31b7658299bf19f5ca72473390cd':
  Revert "[JIT] Fix volatile test" - breaks build

79 files changed:
docs/dex-format.html
dx/src/com/android/dx/rop/code/PlainInsn.java
libdex/SysUtil.h
vm/AllocTracker.h
vm/Atomic.h
vm/BitVector.h
vm/Common.h
vm/Dalvik.h
vm/Ddm.h
vm/Debugger.h
vm/Dvm.mk
vm/DvmDex.h
vm/Exception.h
vm/Globals.h
vm/Hash.h
vm/IndirectRefTable.h
vm/Init.h
vm/InlineNative.h
vm/Intern.h
vm/JarFile.h
vm/Jni.c
vm/JniInternal.h
vm/LinearAlloc.h
vm/Misc.h
vm/Native.h
vm/PointerSet.h
vm/Profile.h
vm/Properties.h
vm/RawDexFile.h
vm/ReferenceTable.h
vm/SignalCatcher.h
vm/StdioConverter.h
vm/Sync.h
vm/Thread.c
vm/Thread.h
vm/UtfString.h
vm/alloc/Alloc.cpp [moved from vm/alloc/Alloc.c with 100% similarity]
vm/alloc/Alloc.h
vm/alloc/CardTable.cpp [moved from vm/alloc/CardTable.c with 100% similarity]
vm/alloc/CardTable.h
vm/alloc/Copying.cpp [moved from vm/alloc/Copying.c with 100% similarity]
vm/alloc/DdmHeap.cpp [moved from vm/alloc/DdmHeap.c with 99% similarity]
vm/alloc/DdmHeap.h
vm/alloc/Heap.cpp [moved from vm/alloc/Heap.c with 99% similarity]
vm/alloc/Heap.h
vm/alloc/HeapBitmap.cpp [moved from vm/alloc/HeapBitmap.c with 100% similarity]
vm/alloc/HeapBitmap.h
vm/alloc/HeapDebug.cpp [moved from vm/alloc/HeapDebug.c with 100% similarity]
vm/alloc/HeapDebug.h
vm/alloc/HeapInternal.h
vm/alloc/HeapSource.cpp [moved from vm/alloc/HeapSource.c with 99% similarity]
vm/alloc/MarkSweep.cpp [moved from vm/alloc/MarkSweep.c with 99% similarity]
vm/alloc/Verify.cpp [moved from vm/alloc/Verify.c with 100% similarity]
vm/alloc/Visit.cpp [moved from vm/alloc/Visit.c with 100% similarity]
vm/alloc/Visit.h
vm/alloc/VisitInlines.h
vm/alloc/WriteBarrier.h
vm/analysis/CodeVerify.h
vm/analysis/RegisterMap.h
vm/compiler/Compiler.h
vm/compiler/Dataflow.h
vm/compiler/Loop.c
vm/hprof/Hprof.cpp [moved from vm/hprof/Hprof.c with 100% similarity]
vm/hprof/Hprof.h
vm/hprof/HprofClass.cpp [moved from vm/hprof/HprofClass.c with 100% similarity]
vm/hprof/HprofHeap.cpp [moved from vm/hprof/HprofHeap.c with 98% similarity]
vm/hprof/HprofOutput.cpp [moved from vm/hprof/HprofOutput.c with 100% similarity]
vm/hprof/HprofString.cpp [moved from vm/hprof/HprofString.c with 100% similarity]
vm/interp/Jit.h
vm/interp/Stack.h
vm/native/InternalNative.h
vm/native/InternalNativePriv.h
vm/oo/AccessCheck.h
vm/oo/Array.h
vm/oo/Class.h
vm/oo/Object.h
vm/oo/ObjectInlines.h
vm/oo/Resolve.h
vm/oo/TypeCheck.h

index 5a71b59..81c0b36 100644 (file)
@@ -315,7 +315,7 @@ uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int
 
 <h2><code>access_flags</code> Definitions</h2>
 <h4>embedded in <code>class_def_item</code>,
-<code>field_item</code>, <code>method_item</code>, and
+<code>encoded_field</code>, <code>encoded_method</code>, and
 <code>InnerClass</code></h4>
 
 <p>Bitfields of these flags are used to indicate the accessibility and
@@ -2017,7 +2017,7 @@ be ordered by initial offset and must not overlap.</p>
 </table>
 
 <h2><code>code_item</code></h2>
-<h4>referenced from <code>method_item</code></h4>
+<h4>referenced from <code>encoded_method</code></h4>
 <h4>appears in the <code>data</code> section</h4>
 <h4>alignment: 4 bytes</h4>
 
index 027249f..3b52efa 100644 (file)
@@ -106,31 +106,41 @@ public final class PlainInsn
 
         TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();
 
-        // TODO: Check for reverse subtraction, where first source is constant
         if (!lastType.isConstant()) {
-            return this;
-        }
-
-        Constant cst = (Constant) lastType;
-
-        RegisterSpecList newSources = sources.withoutLast();
-
-        Rop newRop;
-        try {
-            // Check for constant subtraction and flip them to be addition
-            int opcode = getOpcode().getOpcode();
-            if (opcode == RegOps.SUB && cst instanceof CstInteger) {
-                opcode = RegOps.ADD;
-                cst = CstInteger.make(-((CstInteger)cst).getValue());
+            // Check for reverse subtraction, where first source is constant
+            TypeBearer firstType = sources.get(0).getTypeBearer();
+            if (szSources == 2 && firstType.isConstant()) {
+                Constant cst = (Constant) firstType;
+                RegisterSpecList newSources = sources.withoutFirst();
+                Rop newRop = Rops.ropFor(getOpcode().getOpcode(), getResult(),
+                                             newSources, cst);
+                return new PlainCstInsn(newRop, getPosition(), getResult(),
+                                            newSources, cst);
             }
-            newRop = Rops.ropFor(opcode, getResult(), newSources, cst);
-        } catch (IllegalArgumentException ex) {
-            // There's no rop for this case
             return this;
-        }
+        } else {
+
+            Constant cst = (Constant) lastType;
+
+            RegisterSpecList newSources = sources.withoutLast();
+
+            Rop newRop;
+            try {
+                // Check for constant subtraction and flip it to be addition
+                int opcode = getOpcode().getOpcode();
+                if (opcode == RegOps.SUB && cst instanceof CstInteger) {
+                    opcode = RegOps.ADD;
+                    cst = CstInteger.make(-((CstInteger)cst).getValue());
+                }
+                newRop = Rops.ropFor(opcode, getResult(), newSources, cst);
+            } catch (IllegalArgumentException ex) {
+                // There's no rop for this case
+                return this;
+            }
 
-        return new PlainCstInsn(newRop, getPosition(),
-                getResult(), newSources, cst);
+            return new PlainCstInsn(newRop, getPosition(),
+                    getResult(), newSources, cst);
+        }
     }
 
 
index 4de0289..1f704f4 100644 (file)
 
 #include <sys/types.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * System page size.  Normally you're expected to get this from
  * sysconf(_SC_PAGESIZE) or some system-specific define (usually PAGESIZE
@@ -119,4 +123,8 @@ int sysWriteFully(int fd, const void* buf, size_t count, const char* logMsg);
  */
 int sysCopyFileToFile(int outFd, int inFd, size_t count);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_SYSUTIL*/
index 84ac9b8..b6d668d 100644 (file)
 #ifndef _DALVIK_ALLOCTRACKER
 #define _DALVIK_ALLOCTRACKER
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* initialization */
 bool dvmAllocTrackerStartup(void);
 void dvmAllocTrackerShutdown(void);
@@ -60,4 +64,8 @@ bool dvmGenerateTrackedAllocationReport(u1** pData, size_t* pDataLen);
  */
 void dvmDumpTrackedAllocations(bool enable);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_ALLOCTRACKER*/
index 6c3a66f..713c5b4 100644 (file)
 #include <cutils/atomic.h>          /* use common Android atomic ops */
 #include <cutils/atomic-inline.h>   /* and some uncommon ones */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * NOTE: Two "quasiatomic" operations on the exact same memory address
  * are guaranteed to operate atomically with respect to each other,
@@ -52,4 +56,8 @@ int64_t dvmQuasiAtomicRead64(volatile const int64_t* addr);
 int dvmQuasiAtomicCas64(int64_t oldvalue, int64_t newvalue,
         volatile int64_t* addr);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_ATOMIC*/
index d1a0ca3..0d23350 100644 (file)
 #ifndef _DALVIK_BITVECTOR
 #define _DALVIK_BITVECTOR
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Expanding bitmap, used for tracking resources.  Bits are numbered starting
  * from zero.
@@ -100,4 +104,8 @@ void dvmBitVectorIteratorInit(BitVector* pBits, BitVectorIterator* iterator);
 /* Return the next position set to 1. -1 means end-of-vector reached */
 int dvmBitVectorIteratorNext(BitVectorIterator* iterator);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_BITVECTOR*/
index 7d8424e..0ec9ec4 100644 (file)
 # define LOG_TAG "dalvikvm"
 #endif
 
+#include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <assert.h>
+#include <endian.h>
+#include "utils/Log.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #if !defined(NDEBUG) && defined(WITH_DALVIK_ASSERT)
 # undef assert
@@ -67,8 +75,6 @@
 /*
  * These match the definitions in the VM specification.
  */
-#ifdef HAVE_STDINT_H
-# include <stdint.h>    /* C99 */
 typedef uint8_t             u1;
 typedef uint16_t            u2;
 typedef uint32_t            u4;
@@ -77,16 +83,6 @@ typedef int8_t              s1;
 typedef int16_t             s2;
 typedef int32_t             s4;
 typedef int64_t             s8;
-#else
-typedef unsigned char       u1;
-typedef unsigned short      u2;
-typedef unsigned int        u4;
-typedef unsigned long long  u8;
-typedef signed char         s1;
-typedef signed short        s2;
-typedef signed int          s4;
-typedef signed long long    s8;
-#endif
 
 /*
  * Storage for primitive types and object references.
@@ -108,55 +104,10 @@ typedef union JValue {
     void*   l;
 } JValue;
 
-/*
- * The <stdbool.h> definition uses _Bool, a type known to the compiler.
- */
-#ifdef HAVE_STDBOOL_H
-# include <stdbool.h>   /* C99 */
-#else
-# ifndef __bool_true_false_are_defined
-typedef enum { false=0, true=!false } bool;
-# define __bool_true_false_are_defined 1
-# endif
-#endif
-
 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
 
-
-#if defined(HAVE_ENDIAN_H)
-# include <endian.h>
-#else /*not HAVE_ENDIAN_H*/
-# define __BIG_ENDIAN 4321
-# define __LITTLE_ENDIAN 1234
-# if defined(HAVE_LITTLE_ENDIAN)
-#  define __BYTE_ORDER __LITTLE_ENDIAN
-# else
-#  define __BYTE_ORDER __BIG_ENDIAN
-# endif
-#endif /*not HAVE_ENDIAN_H*/
-
-
-#if 0
-/*
- * Pretend we have the Android logging macros.  These are replaced by the
- * Android logging implementation.
- */
-#define ANDROID_LOG_DEBUG 3
-#define LOGV(...)    LOG_PRI(2, 0, __VA_ARGS__)
-#define LOGD(...)    LOG_PRI(3, 0, __VA_ARGS__)
-#define LOGI(...)    LOG_PRI(4, 0, __VA_ARGS__)
-#define LOGW(...)    LOG_PRI(5, 0, __VA_ARGS__)
-#define LOGE(...)    LOG_PRI(6, 0, __VA_ARGS__)
-#define MIN_LOG_LEVEL   2
-
-#define LOG_PRI(priority, tag, ...) do {                            \
-        if (priority >= MIN_LOG_LEVEL) {                            \
-            dvmFprintf(stdout, "%s:%-4d ", __FILE__, __LINE__);     \
-            dvmFprintf(stdout, __VA_ARGS__);                        \
-        }                                                           \
-    } while(0)
-#else
-# include "utils/Log.h"
+#ifdef __cplusplus
+}
 #endif
 
 #endif /*_DALVIK_COMMON*/
index 534ea2d..a47388a 100644 (file)
@@ -20,8 +20,6 @@
 #ifndef _DALVIK_DALVIK
 #define _DALVIK_DALVIK
 
-#include <pthread.h>
-
 #include "Common.h"
 #include "Inlines.h"
 #include "Misc.h"
index 01f5d18..af7f6e1 100644 (file)
--- a/vm/Ddm.h
+++ b/vm/Ddm.h
 #ifndef _DALVIK_DDM
 #define _DALVIK_DDM
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Handle a packet full of DDM goodness.
  *
@@ -84,4 +88,8 @@ ArrayObject* dvmDdmGetStackTraceById(u4 threadId);
  */
 ArrayObject* dvmDdmGetRecentAllocations(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_DDM*/
index 9a45b39..dd9679f 100644 (file)
 #ifndef _DALVIK_DEBUGGER
 #define _DALVIK_DEBUGGER
 
+#include <pthread.h>
 #include "Common.h"
 #include "Misc.h"
 #include "jdwp/Jdwp.h"
-#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* fwd decl */
 struct Object;
@@ -307,4 +311,8 @@ void dvmDbgDdmSendChunkV(int type, const struct iovec* iov, int iovcnt);
 #define CHUNK_TYPE(_name) \
     ((_name)[0] << 24 | (_name)[1] << 16 | (_name)[2] << 8 | (_name)[3])
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_DEBUGGER*/
index d655a3a..add2207 100644 (file)
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -116,14 +116,14 @@ LOCAL_SRC_FILES := \
        Sync.c \
        Thread.c \
        UtfString.c \
-       alloc/Alloc.c \
-       alloc/CardTable.c \
-       alloc/HeapBitmap.c.arm \
-       alloc/HeapDebug.c \
-       alloc/Heap.c.arm \
-       alloc/DdmHeap.c \
-       alloc/Verify.c \
-       alloc/Visit.c \
+       alloc/Alloc.cpp \
+       alloc/CardTable.cpp \
+       alloc/HeapBitmap.cpp.arm \
+       alloc/HeapDebug.cpp \
+       alloc/Heap.cpp.arm \
+       alloc/DdmHeap.cpp \
+       alloc/Verify.cpp \
+       alloc/Visit.cpp \
        analysis/CodeVerify.c \
        analysis/DexPrepare.c \
        analysis/DexVerify.c \
@@ -132,11 +132,11 @@ LOCAL_SRC_FILES := \
        analysis/RegisterMap.c \
        analysis/VerifySubs.c \
        analysis/VfyBasicBlock.c \
-       hprof/Hprof.c \
-       hprof/HprofClass.c \
-       hprof/HprofHeap.c \
-       hprof/HprofOutput.c \
-       hprof/HprofString.c \
+       hprof/Hprof.cpp \
+       hprof/HprofClass.cpp \
+       hprof/HprofHeap.cpp \
+       hprof/HprofOutput.cpp \
+       hprof/HprofString.cpp \
        interp/Interp.c.arm \
        interp/Stack.c \
        jdwp/ExpandBuf.c \
@@ -195,11 +195,11 @@ WITH_COPYING_GC := $(strip $(WITH_COPYING_GC))
 ifeq ($(WITH_COPYING_GC),true)
   LOCAL_CFLAGS += -DWITH_COPYING_GC
   LOCAL_SRC_FILES += \
-       alloc/Copying.c.arm
+       alloc/Copying.cpp.arm
 else
   LOCAL_SRC_FILES += \
-       alloc/HeapSource.c \
-       alloc/MarkSweep.c.arm
+       alloc/HeapSource.cpp \
+       alloc/MarkSweep.cpp.arm
 endif
 
 WITH_JIT := $(strip $(WITH_JIT))
index ad82e54..937f09d 100644 (file)
 #ifndef _DALVIK_DVMDEX
 #define _DALVIK_DVMDEX
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #include "libdex/DexFile.h"
 
 /* extern */
@@ -158,4 +162,8 @@ INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
     pDvmDex->pResFields[fieldIdx] = field;
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_DVMDEX*/
index 509d3b2..40f3482 100644 (file)
 #ifndef _DALVIK_EXCEPTION
 #define _DALVIK_EXCEPTION
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Create a Throwable and throw an exception in the current thread (where
  * "throwing" just means "set the thread's exception pointer").
@@ -483,4 +487,8 @@ void dvmThrowVerifyError(const char* descriptor);
  */
 void dvmThrowVirtualMachineError(const char* msg);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_EXCEPTION*/
index faafcc6..163ce99 100644 (file)
 #include <stdarg.h>
 #include <pthread.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define MAX_BREAKPOINTS 20      /* used for a debugger optimization */
 
 /* private structures */
@@ -959,4 +963,8 @@ extern int gDvmICHitCount;
 
 #endif
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_GLOBALS*/
index cfd7544..2c6bd5e 100644 (file)
--- a/vm/Hash.h
+++ b/vm/Hash.h
 #ifndef _DALVIK_HASH
 #define _DALVIK_HASH
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* compute the hash of an item with a specific type */
 typedef u4 (*HashCompute)(const void* item);
 
@@ -218,4 +222,8 @@ typedef u4 (*HashCalcFunc)(const void* item);
 void dvmHashTableProbeCount(HashTable* pHashTable, HashCalcFunc calcFunc,
     HashCompareFunc cmpFunc);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_HASH*/
index 7248a7b..36d18ba 100644 (file)
 
 #ifndef _DALVIK_INDIRECTREFTABLE
 #define _DALVIK_INDIRECTREFTABLE
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Maintain a table of indirect references.  Used for local/global JNI
  * references.
@@ -389,4 +394,8 @@ bool dvmRemoveFromIndirectRefTable(IndirectRefTable* pRef, u4 cookie,
  */
 void dvmDumpIndirectRefTable(const IndirectRefTable* pRef, const char* descr);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INDIRECTREFTABLE*/
index ef56f26..9e38da9 100644 (file)
--- a/vm/Init.h
+++ b/vm/Init.h
 #ifndef _DALVIK_INIT
 #define _DALVIK_INIT
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Standard VM initialization, usually invoked through JNI.
  */
@@ -78,4 +82,8 @@ int dvmFprintf(FILE* fp, const char* format, ...)
 #endif
     ;
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INIT*/
index 4ca90e2..4f86cef 100644 (file)
 #ifndef _DALVIK_INLINENATIVE
 #define _DALVIK_INLINENATIVE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* startup/shutdown */
 bool dvmInlineNativeStartup(void);
 void dvmInlineNativeShutdown(void);
@@ -121,4 +125,8 @@ bool dvmPerformInlineOp4Dbg(u4 arg0, u4 arg1, u4 arg2, u4 arg3,
  */
 Method* dvmResolveInlineNative(int opIndex);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INLINENATIVE*/
index 6630b69..b6e669a 100644 (file)
 #ifndef _DALVIK_INTERN
 #define _DALVIK_INTERN
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool dvmStringInternStartup(void);
 void dvmStringInternShutdown(void);
 StringObject* dvmLookupInternedString(StringObject* strObj);
@@ -26,4 +30,8 @@ StringObject* dvmLookupImmortalInternedString(StringObject* strObj);
 bool dvmIsWeakInternedString(const StringObject* strObj);
 void dvmGcDetachDeadInternedStrings(int (*isUnmarkedObject)(void *));
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INTERN*/
index 36849ec..0569ee2 100644 (file)
 #ifndef _DALVIK_JARFILE
 #define _DALVIK_JARFILE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * This represents an open, scanned Jar file.  (It's actually for any Zip
  * archive that happens to hold a Dex file.)
@@ -68,4 +72,8 @@ typedef enum DexCacheStatus {
  */
 DexCacheStatus dvmDexCacheStatus(const char *fileName);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_JARFILE*/
index 6f96132..5bff882 100644 (file)
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -2130,7 +2130,7 @@ static jfieldID GetStaticFieldID(JNIEnv* env, jclass jclazz,
         assert(dvmCheckException(_self));
         id = NULL;
     } else {
-        id = (jfieldID) dvmFindStaticField(clazz, name, sig);
+        id = (jfieldID) dvmFindStaticFieldHier(clazz, name, sig);
         if (id == NULL) {
             dvmThrowExceptionFmt(gDvm.exNoSuchFieldError,
                 "no static field with name='%s' signature='%s' in class %s",
index bc88cad..d81373f 100644 (file)
 
 #include "jni.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* system init/shutdown */
 bool dvmJniStartup(void);
 void dvmJniShutdown(void);
@@ -197,4 +201,8 @@ void dvmReleaseJniMonitors(Thread* self);
  */
 void dvmDumpJniReferenceTables(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_JNIINTERNAL*/
index aa33fe1..c06d2ab 100644 (file)
 #ifndef _DALVIK_LINEARALLOC
 #define _DALVIK_LINEARALLOC
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * If this is set, we create additional data structures and make many
  * additional mprotect() calls.
@@ -117,4 +121,8 @@ void dvmLinearAllocDump(Object* classLoader);
  */
 bool dvmLinearAllocContains(const void* start, size_t length);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_LINEARALLOC*/
index c1c3d47..8981824 100644 (file)
--- a/vm/Misc.h
+++ b/vm/Misc.h
 #ifndef _DALVIK_MISC
 #define _DALVIK_MISC
 
-#include "Inlines.h"
-
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/time.h>
+#include "Inlines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
  * Used to shut up the compiler when a parameter isn't used.
@@ -299,4 +302,8 @@ bool dvmGetThreadStats(ProcStatData* pData, pid_t tid);
  */
 const char* dvmPathToAbsolutePortion(const char* path);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_MISC*/
index f60ccce..7599bcc 100644 (file)
 #ifndef _DALVIK_NATIVE
 #define _DALVIK_NATIVE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Method description; equivalent to a JNI struct.
  */
@@ -119,4 +123,8 @@ void dvmLogNativeMethodEntry(const Method* method, const u4* newFp);
 void dvmLogNativeMethodExit(const Method* method, struct Thread* self,
         const JValue retval);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_NATIVE*/
index ffc0635..6e43f67 100644 (file)
 #ifndef _DALVIK_POINTERSET
 #define _DALVIK_POINTERSET
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct PointerSet;   /* private */
 typedef struct PointerSet PointerSet;
 
@@ -92,4 +96,8 @@ void dvmPointerSetIntersect(PointerSet* pSet, const void** ptrArray, int count);
  */
 void dvmPointerSetDump(const PointerSet* pSet);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_POINTERSET*/
index b821394..12063b9 100644 (file)
 
 #include <stdio.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct Thread;      // extern
 
 
@@ -171,4 +175,8 @@ enum {
 #define METHOD_ACTION(_method)  (((unsigned int)(_method)) & METHOD_ACTION_MASK)
 #define METHOD_COMBINE(_method, _action)    ((_method) | (_action))
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_PROFILE*/
index 138be41..6226d7f 100644 (file)
 #ifndef _DALVIK_PROPERTIES
 #define _DALVIK_PROPERTIES
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Initialization.
  */
 bool dvmPropertiesStartup(void);
 void dvmPropertiesShutdown(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_PROPERTIES*/
index cbcb3b6..f2c1b68 100644 (file)
 #ifndef _DALVIK_RAWDEXFILE
 #define _DALVIK_RAWDEXFILE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Structure representing a "raw" DEX file, in its unswapped unoptimized
  * state.
@@ -68,4 +72,8 @@ INLINE const char* dvmGetRawDexFileCacheFileName(RawDexFile* pRawDexFile) {
     return pRawDexFile->cacheFileName;
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_RAWDEXFILE*/
index f434f55..35bc61b 100644 (file)
 #ifndef _DALVIK_REFERENCETABLE
 #define _DALVIK_REFERENCETABLE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Table definition.
  *
@@ -122,4 +126,8 @@ void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr);
 void dvmDumpReferenceTableContents(Object* const* refs, size_t count,
     const char* descr);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_REFERENCETABLE*/
index ece052c..f9e1dd7 100644 (file)
 #ifndef _DALVIK_SIGNALCATCHER
 #define _DALVIK_SIGNALCATCHER
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool dvmSignalCatcherStartup(void);
 void dvmSignalCatcherShutdown(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_SIGNALCATCHER*/
index ffbf807..37384eb 100644 (file)
 #ifndef _DALVIK_STDOUTCONVERTER
 #define _DALVIK_STDOUTCONVERTER
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool dvmStdioConverterStartup(void);
 void dvmStdioConverterShutdown(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_STDOUTCONVERTER*/
index 520366e..a039483 100644 (file)
--- a/vm/Sync.h
+++ b/vm/Sync.h
 #ifndef _DALVIK_SYNC
 #define _DALVIK_SYNC
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Monitor shape field.  Used to distinguish immediate thin locks from
  * indirecting fat locks.
@@ -157,4 +161,8 @@ bool dvmHoldsLock(struct Thread* thread, struct Object* obj);
 int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
                          s8 msec, s4 nsec);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_SYNC*/
index 087c2e0..62f95aa 100644 (file)
@@ -557,7 +557,7 @@ void dvmSlayDaemons(void)
         }
 
         char* threadName = dvmGetThreadName(target);
-        LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
+        LOGV("threadid=%d: suspending daemon id=%d name='%s'\n",
             threadId, target->threadId, threadName);
         free(threadName);
 
@@ -618,7 +618,7 @@ void dvmSlayDaemons(void)
             }
 
             if (allSuspended) {
-                LOGD("threadid=%d: all daemons have suspended\n", threadId);
+                LOGV("threadid=%d: all daemons have suspended\n", threadId);
                 break;
             } else {
                 if (!complained) {
index d84682f..c42a9e8 100644 (file)
@@ -26,6 +26,9 @@
 #include <errno.h>
 #include <cutils/sched_policy.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #if defined(CHECK_MUTEX) && !defined(__USE_UNIX98)
 /* glibc lacks this unless you #define __USE_UNIX98 */
@@ -71,7 +74,7 @@ void dvmThreadShutdown(void);
 void dvmSlayDaemons(void);
 
 
-#define kJniLocalRefMin         32
+#define kJniLocalRefMin         64
 #define kJniLocalRefMax         512     /* arbitrary; should be plenty */
 #define kInternalRefDefault     32      /* equally arbitrary */
 #define kInternalRefMax         4096    /* mainly a sanity check */
@@ -595,4 +598,8 @@ void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock);
  */
 void dvmNukeThread(Thread* thread);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_THREAD*/
index 793d8bc..f0413a4 100644 (file)
 #ifndef _DALVIK_STRING
 #define _DALVIK_STRING
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * (This is private to UtfString.c, but we cheat a bit and also use it
  * for InlineNative.c.  Not really worth creating a separate header.)
@@ -145,4 +149,8 @@ const u2* dvmStringChars(StringObject* jstr);
  */
 int dvmHashcmpStrings(const void* vstrObj1, const void* vstrObj2);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_STRING*/
similarity index 100%
rename from vm/alloc/Alloc.c
rename to vm/alloc/Alloc.cpp
index aeba3f5..fc62ed0 100644 (file)
 
 #include <stddef.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Initialization.
  */
@@ -143,4 +147,8 @@ void dvmClearGrowthLimit(void);
  */
 bool dvmIsHeapAddress(void *address);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_ALLOC_ALLOC*/
similarity index 100%
rename from vm/alloc/CardTable.c
rename to vm/alloc/CardTable.cpp
index 96131d1..1c15a54 100644 (file)
 #ifndef _DALVIK_ALLOC_CARDTABLE
 #define _DALVIK_ALLOC_CARDTABLE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define GC_CARD_SHIFT 7
 #define GC_CARD_SIZE (1 << GC_CARD_SHIFT)
 #define GC_CARD_CLEAN 0
@@ -70,4 +74,8 @@ void dvmMarkCard(const void *addr);
  */
 void dvmVerifyCardTable(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_ALLOC_CARDTABLE*/
similarity index 100%
rename from vm/alloc/Copying.c
rename to vm/alloc/Copying.cpp
similarity index 99%
rename from vm/alloc/DdmHeap.c
rename to vm/alloc/DdmHeap.cpp
index b377b1b..8008113 100644 (file)
@@ -357,7 +357,7 @@ enum HpsgWhat {
  */
 #define HPSx_CHUNK_SIZE (16384 - 16)
 
-void dlmalloc_walk_heap(void(*)(const void*, size_t, const void*, size_t, void*),void*);
+extern "C" void dlmalloc_walk_heap(void(*)(const void*, size_t, const void*, size_t, void*),void*);
 
 static void
 walkHeap(bool merge, bool native)
index c3e11dc..32b96f9 100644 (file)
 #ifndef _DALVIK_ALLOC_DDMHEAP
 #define _DALVIK_ALLOC_DDMHEAP
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Sends the current heap info to the DDM server.
  * Should be called after a GC when gcHeap->ddmHpifWhen
@@ -38,4 +42,8 @@ void dvmDdmSendHeapInfo(int reason, bool shouldLock);
  */
 void dvmDdmSendHeapSegments(bool shouldLock, bool native);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  // _DALVIK_ALLOC_DDMHEAP
similarity index 99%
rename from vm/alloc/Heap.c
rename to vm/alloc/Heap.cpp
index f38eb12..9ca0ebf 100644 (file)
@@ -37,7 +37,7 @@
 static const GcSpec kGcForMallocSpec = {
     true,  /* isPartial */
     false,  /* isConcurrent */
-    PRESERVE,
+    true,  /* doPreserve */
     "GC_FOR_ALLOC"
 };
 
@@ -46,7 +46,7 @@ const GcSpec *GC_FOR_MALLOC = &kGcForMallocSpec;
 static const GcSpec kGcConcurrentSpec  = {
     true,  /* isPartial */
     true,  /* isConcurrent */
-    PRESERVE,
+    true,  /* doPreserve */
     "GC_CONCURRENT"
 };
 
@@ -55,7 +55,7 @@ const GcSpec *GC_CONCURRENT = &kGcConcurrentSpec;
 static const GcSpec kGcExplicitSpec = {
     false,  /* isPartial */
     true,  /* isConcurrent */
-    PRESERVE,
+    true,  /* doPreserve */
     "GC_EXPLICIT"
 };
 
@@ -64,7 +64,7 @@ const GcSpec *GC_EXPLICIT = &kGcExplicitSpec;
 static const GcSpec kGcBeforeOomSpec = {
     false,  /* isPartial */
     false,  /* isConcurrent */
-    CLEAR,
+    false,  /* doPreserve */
     "GC_BEFORE_OOM"
 };
 
@@ -622,7 +622,7 @@ void dvmCollectGarbageInternal(const GcSpec* spec)
      * weakly-reachable objects discovered while tracing.
      */
     dvmHeapProcessReferences(&gcHeap->softReferences,
-                             spec->softReferencePolicy == CLEAR,
+                             spec->doPreserve == false,
                              &gcHeap->weakReferences,
                              &gcHeap->finalizerReferences,
                              &gcHeap->phantomReferences);
index 01a50d2..4333486 100644 (file)
@@ -25,7 +25,7 @@ typedef struct {
   /* If true, the trace is run concurrently with the mutator. */
   bool isConcurrent;
   /* Toggles for the soft reference clearing policy. */
-  enum { CLEAR, PRESERVE } softReferencePolicy;
+  bool doPreserve;
   /* A name for this garbage collection mode. */
   const char *reason;
 } GcSpec;
index fecc2a9..dd374cc 100644 (file)
 #include <limits.h>
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define HB_OBJECT_ALIGNMENT 8
 #define HB_BITS_PER_WORD (sizeof(unsigned long) * CHAR_BIT)
 
@@ -127,4 +131,8 @@ void dvmHeapBitmapSweepWalk(const HeapBitmap *liveHb, const HeapBitmap *markHb,
                             uintptr_t base, uintptr_t max,
                             BitmapSweepCallback *callback, void *callbackArg);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DALVIK_HEAP_BITMAP */
similarity index 100%
rename from vm/alloc/HeapDebug.c
rename to vm/alloc/HeapDebug.cpp
index f36b7ab..3dd1d54 100644 (file)
 #ifndef _DALVIK_HEAPDEBUG
 #define _DALVIK_HEAPDEBUG
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef enum HeapDebugInfoType {
     kVirtualHeapSize = 0,
     kNativeHeapSize = 1,
@@ -29,4 +33,8 @@ typedef enum HeapDebugInfoType {
  */
 int dvmGetHeapDebugInfo(HeapDebugInfoType info);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  // _DALVIK_HEAPDEBUG
index 1d1be07..8529422 100644 (file)
@@ -85,7 +85,10 @@ void dvmUnlockHeap(void);
 #define LOGD_HEAP(...)    LOG(LOG_DEBUG, HEAP_LOG_TAG, __VA_ARGS__)
 #endif
 #define LOGI_HEAP(...) \
-    (!gDvm.zygote ? LOG(LOG_INFO, HEAP_LOG_TAG, __VA_ARGS__) : (void)0)
+    do { \
+        if (!gDvm.zygote) { LOG(LOG_INFO, HEAP_LOG_TAG, __VA_ARGS__); } \
+    } while (0)
+
 #define LOGW_HEAP(...)    LOG(LOG_WARN, HEAP_LOG_TAG, __VA_ARGS__)
 #define LOGE_HEAP(...)    LOG(LOG_ERROR, HEAP_LOG_TAG, __VA_ARGS__)
 
similarity index 99%
rename from vm/alloc/HeapSource.c
rename to vm/alloc/HeapSource.cpp
index 4b61358..50303b7 100644 (file)
  */
 
 #include <cutils/mspace.h>
-#include <stdint.h>     // for SIZE_MAX
+#include <stdint.h>
 #include <sys/mman.h>
 #include <errno.h>
 
+#define SIZE_MAX UINT_MAX  // TODO: get SIZE_MAX from stdint.h
+
 #include "Dalvik.h"
 #include "alloc/Heap.h"
 #include "alloc/HeapInternal.h"
@@ -27,8 +29,8 @@
 #include "alloc/HeapBitmapInlines.h"
 
 // TODO: find a real header file for these.
-extern int dlmalloc_trim(size_t);
-extern void dlmalloc_walk_free_pages(void(*)(void*, void*, void*), void*);
+extern "C" int dlmalloc_trim(size_t);
+extern "C" void dlmalloc_walk_free_pages(void(*)(void*, void*, void*), void*);
 
 static void snapIdealFootprint(void);
 static void setIdealFootprint(size_t max);
similarity index 99%
rename from vm/alloc/MarkSweep.c
rename to vm/alloc/MarkSweep.cpp
index 8e924d5..9b527cb 100644 (file)
@@ -144,7 +144,7 @@ static void markObject(const Object *obj, GcMarkContext *ctx)
  * marking.  Marks white objects but does not push them on the mark
  * stack.
  */
-static void rootMarkObjectVisitor(void *addr, RootType type, u4 thread,
+static void rootMarkObjectVisitor(void *addr, u4 thread, RootType type,
                                   void *arg)
 {
     Object *obj;
@@ -363,7 +363,7 @@ void dvmHeapMarkRootSet()
  * Callback applied to root references during root remarking.  Marks
  * white objects and pushes them on the mark stack.
  */
-static void rootReMarkObjectVisitor(void *addr, RootType type, u4 thread,
+static void rootReMarkObjectVisitor(void *addr, u4 thread, RootType type,
                                     void *arg)
 {
     Object *obj;
@@ -492,7 +492,7 @@ static void scanArrayObject(const Object *obj, GcMarkContext *ctx)
     markObject((const Object *)obj->clazz, ctx);
     if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
         const ArrayObject *array = (const ArrayObject *)obj;
-        const Object **contents = (const Object **)array->contents;
+        const Object **contents = (const Object **)(void *)array->contents;
         size_t i;
         for (i = 0; i < array->length; ++i) {
             markObject(contents[i], ctx);
similarity index 100%
rename from vm/alloc/Verify.c
rename to vm/alloc/Verify.cpp
similarity index 100%
rename from vm/alloc/Visit.c
rename to vm/alloc/Visit.cpp
index a66839d..1616889 100644 (file)
 
 #include "Dalvik.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef enum {
   ROOT_UNKNOWN = 0,
   ROOT_JNI_GLOBAL,
@@ -58,4 +62,8 @@ void dvmVisitObject(Visitor *visitor, Object *obj, void *arg);
  */
 void dvmVisitRoots(RootVisitor *visitor, void *arg);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DALVIK_ALLOC_VISIT */
index 7f90678..eb889af 100644 (file)
@@ -120,7 +120,7 @@ static void visitArrayObject(Visitor *visitor, Object *obj, void *arg)
     (*visitor)(&obj->clazz, arg);
     if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISOBJECTARRAY)) {
         ArrayObject *array = (ArrayObject *)obj;
-        Object **contents = (Object **)array->contents;
+        Object **contents = (Object **)(void *)array->contents;
         size_t i;
         for (i = 0; i < array->length; ++i) {
             (*visitor)(&contents[i], arg);
index dd8f129..4c660a0 100644 (file)
 #ifndef _DALVIK_ALLOC_WRITEBARRIER
 #define _DALVIK_ALLOC_WRITEBARRIER
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Note writes to the heap. These functions must be called if a field
  * of an Object in the heap changes, and before any GC safe-point. The
@@ -50,4 +54,8 @@ INLINE void dvmWriteBarrierArray(const ArrayObject *obj,
     dvmMarkCard((Object *)obj);
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DALVIK_ALLOC_WRITEBARRIER */
index 9369537..4fbf700 100644 (file)
@@ -23,6 +23,9 @@
 #include "analysis/VerifySubs.h"
 #include "analysis/VfyBasicBlock.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
  * Enumeration for register type values.  The "hi" piece of a 64-bit value
@@ -322,4 +325,8 @@ void dvmFreeUninitInstanceMap(UninitInstanceMap* uninitMap);
  */
 bool dvmVerifyCodeFlow(VerifierData* vdata);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_CODEVERIFY*/
index 886d0b0..becb1de 100644 (file)
 #include "analysis/VerifySubs.h"
 #include "analysis/CodeVerify.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Format enumeration for RegisterMap data area.
  */
@@ -263,4 +267,8 @@ INLINE const RegisterMap* dvmGetExpandedRegisterMap(Method* method)
 /* dump stats gathered during register map creation process */
 void dvmRegisterMapDumpStats(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_REGISTERMAP*/
index 35d34b3..384cb14 100644 (file)
  * limitations under the License.
  */
 
-#include <Thread.h>
-#include <setjmp.h>
-
 #ifndef _DALVIK_VM_COMPILER
 #define _DALVIK_VM_COMPILER
 
+#include <setjmp.h>
+#include "Thread.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Uncomment the following to enable JIT signature breakpoint
  * #define SIGNATURE_BREAKPOINT
@@ -241,4 +245,9 @@ void *dvmCompilerGetInterpretTemplate();
 JitInstructionSetType dvmCompilerGetInterpretTemplateSet();
 u8 dvmGetRegResourceMask(int reg);
 void dvmDumpCFG(struct CompilationUnit *cUnit, const char *dirPrefix);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _DALVIK_VM_COMPILER */
index f3d3984..e573d8b 100644 (file)
@@ -102,12 +102,16 @@ typedef struct SSARepresentation {
     bool *fpDef;
 } SSARepresentation;
 
+/*
+ * An induction variable is represented by "m*i + c", where i is a basic
+ * induction variable.
+ */
 typedef struct InductionVariableInfo {
     int ssaReg;
     int basicSSAReg;
-    int m;
-    int c;
-    int inc;
+    int m;      // multiplier
+    int c;      // constant
+    int inc;    // loop incriment
 } InductionVariableInfo;
 
 typedef struct ArrayAccessInfo {
index ba8714c..54517e4 100644 (file)
@@ -118,20 +118,59 @@ static BasicBlock *findPredecessorBlock(const CompilationUnit *cUnit,
     }
 }
 
+/* Used for normalized loop exit condition checks */
+static Opcode negateOpcode(Opcode opcode)
+{
+    switch (opcode) {
+        /* reg/reg cmp */
+        case OP_IF_EQ:
+            return OP_IF_NE;
+        case OP_IF_NE:
+            return OP_IF_EQ;
+        case OP_IF_LT:
+            return OP_IF_GE;
+        case OP_IF_GE:
+            return OP_IF_LT;
+        case OP_IF_GT:
+            return OP_IF_LE;
+        case OP_IF_LE:
+            return OP_IF_GT;
+        /* reg/zero cmp */
+        case OP_IF_EQZ:
+            return OP_IF_NEZ;
+        case OP_IF_NEZ:
+            return OP_IF_EQZ;
+        case OP_IF_LTZ:
+            return OP_IF_GEZ;
+        case OP_IF_GEZ:
+            return OP_IF_LTZ;
+        case OP_IF_GTZ:
+            return OP_IF_LEZ;
+        case OP_IF_LEZ:
+            return OP_IF_GTZ;
+        default:
+            LOGE("opcode %d cannot be negated", opcode);
+            dvmAbort();
+            break;
+    }
+    return -1;
+}
+
 /*
  * A loop is considered optimizable if:
- * 1) It has one basic induction variable
- * 2) The loop back branch compares the BIV with a constant
- * 3) If it is a count-up loop, the condition is GE/GT, or LE/LT/LEZ/LTZ for
- *    a count-down loop.
+ * 1) It has one basic induction variable.
+ * 2) The loop back branch compares the BIV with a constant.
+ * 3) We need to normalize the loop exit condition so that the loop is exited
+ *    via the taken path.
+ * 4) If it is a count-up loop, the condition is GE/GT. Otherwise it is
+ *    LE/LT/LEZ/LTZ for a count-down loop.
  *
- * Return false if the loop is not optimizable.
+ * Return false for loops that fail the above tests.
  */
 static bool isSimpleCountedLoop(CompilationUnit *cUnit)
 {
     unsigned int i;
-    BasicBlock *loopBranch = findPredecessorBlock(cUnit,
-                                  cUnit->entryBlock->fallThrough);
+    BasicBlock *loopBackBlock = cUnit->entryBlock->fallThrough;
     LoopAnalysis *loopAnalysis = cUnit->loopAnalysis;
 
     if (loopAnalysis->numBasicIV != 1) return false;
@@ -150,67 +189,104 @@ static bool isSimpleCountedLoop(CompilationUnit *cUnit)
         }
     }
 
-    MIR *branch = loopBranch->lastMIRInsn;
+    /* Find the block that ends with a branch to exit the loop */
+    while (true) {
+        loopBackBlock = findPredecessorBlock(cUnit, loopBackBlock);
+        /* Loop structure not recognized as counted blocks */
+        if (loopBackBlock == NULL) {
+            return false;
+        }
+        /* Unconditional goto - continue to trace up the predecessor chain */
+        if (loopBackBlock->taken == NULL) {
+            continue;
+        }
+        break;
+    }
+
+    MIR *branch = loopBackBlock->lastMIRInsn;
     Opcode opcode = branch->dalvikInsn.opcode;
 
-    /*
-     * If the instruction is not accessing the IV as the first operand, return
-     * false.
-     */
-    if (branch->ssaRep->numUses == 0 || branch->ssaRep->numDefs != 0) {
+    /* Last instruction is not a conditional branch - bail */
+    if (dexGetFlagsFromOpcode(opcode) != (kInstrCanContinue|kInstrCanBranch)) {
         return false;
     }
 
-    /*
-     * If the first operand of the comparison is not the basic induction
-     * variable, return false.
-     */
-    if (branch->ssaRep->uses[0] != loopAnalysis->ssaBIV) {
-        return false;
-    }
+    int endSSAReg;
+    int endDalvikReg;
 
-    if (loopAnalysis->isCountUpLoop) {
-        /*
-         * If the condition op is not > or >=, this is not an optimization
-         * candidate.
-         */
-        if (opcode != OP_IF_GT && opcode != OP_IF_GE) {
+    /* reg/reg comparison */
+    if (branch->ssaRep->numUses == 2) {
+        if (branch->ssaRep->uses[0] == loopAnalysis->ssaBIV) {
+            endSSAReg = branch->ssaRep->uses[1];
+        } else if (branch->ssaRep->uses[1] == loopAnalysis->ssaBIV) {
+            endSSAReg = branch->ssaRep->uses[0];
+            opcode = negateOpcode(opcode);
+        } else {
             return false;
         }
+        endDalvikReg = dvmConvertSSARegToDalvik(cUnit, endSSAReg);
         /*
          * If the comparison is not between the BIV and a loop invariant,
-         * return false. endReg is loop invariant if one of the following is
-         * true:
+         * return false. endDalvikReg is loop invariant if one of the
+         * following is true:
          * - It is not defined in the loop (ie DECODE_SUB returns 0)
          * - It is reloaded with a constant
          */
-        int endReg = dvmConvertSSARegToDalvik(cUnit, branch->ssaRep->uses[1]);
-        if (DECODE_SUB(endReg) != 0 &&
-            !dvmIsBitSet(cUnit->isConstantV, branch->ssaRep->uses[1])) {
+        if ((DECODE_SUB(endDalvikReg) != 0) &&
+            !dvmIsBitSet(cUnit->isConstantV, endSSAReg)) {
             return false;
         }
-        loopAnalysis->endConditionReg = DECODE_REG(endReg);
+    /* Compare against zero */
+    } else if (branch->ssaRep->numUses == 1) {
+        if (branch->ssaRep->uses[0] == loopAnalysis->ssaBIV) {
+            /* Keep the compiler happy */
+            endDalvikReg = -1;
+        } else {
+            return false;
+        }
+    } else {
+        return false;
+    }
+
+    /* Normalize the loop exit check as "if (iv op end) exit;" */
+    if (loopBackBlock->taken->blockType == kDalvikByteCode) {
+        opcode = negateOpcode(opcode);
+    }
+
+    if (loopAnalysis->isCountUpLoop) {
+        /*
+         * If the normalized condition op is not > or >=, this is not an
+         * optimization candidate.
+         */
+        switch (opcode) {
+            case OP_IF_GT:
+            case OP_IF_GE:
+                break;
+            default:
+                return false;
+        }
+        loopAnalysis->endConditionReg = DECODE_REG(endDalvikReg);
     } else  {
         /*
-         * If the condition op is not < or <=, this is not an optimization
-         * candidate.
+         * If the normalized condition op is not < or <=, this is not an
+         * optimization candidate.
          */
-        if (opcode == OP_IF_LT || opcode == OP_IF_LE) {
-            /*
-             * If the comparison is not between the BIV and a loop invariant,
-             * return false.
-             */
-            int endReg = dvmConvertSSARegToDalvik(cUnit,
-                                                  branch->ssaRep->uses[1]);
-
-            if (DECODE_SUB(endReg) != 0) {
+        switch (opcode) {
+            case OP_IF_LT:
+            case OP_IF_LE:
+                loopAnalysis->endConditionReg = DECODE_REG(endDalvikReg);
+                break;
+            case OP_IF_LTZ:
+            case OP_IF_LEZ:
+                break;
+            default:
                 return false;
-            }
-            loopAnalysis->endConditionReg = DECODE_REG(endReg);
-        } else if (opcode != OP_IF_LTZ && opcode != OP_IF_LEZ) {
-            return false;
         }
     }
+    /*
+     * Remember the normalized opcode, which will be used to determine the end
+     * value used for the yanked range checks.
+     */
     loopAnalysis->loopBranchOpcode = opcode;
     return true;
 }
@@ -432,7 +508,6 @@ static void genHoistedChecks(CompilationUnit *cUnit)
                 dvmCompilerAbort(cUnit);
             }
         }
-
     }
 }
 
similarity index 100%
rename from vm/hprof/Hprof.c
rename to vm/hprof/Hprof.cpp
index c62dd9c..1721a6e 100644 (file)
 
 #include "Dalvik.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define HPROF_ID_SIZE (sizeof (u4))
 
 #define UNIQUE_ERROR() \
@@ -144,7 +148,7 @@ typedef struct hprof_context_t {
 
 
 /*
- * HprofString.c functions
+ * HprofString.cpp functions
  */
 
 hprof_string_id hprofLookupStringId(const char *str);
@@ -156,7 +160,7 @@ int hprofShutdown_String(void);
 
 
 /*
- * HprofClass.c functions
+ * HprofClass.cpp functions
  */
 
 hprof_class_object_id hprofLookupClassId(const ClassObject *clazz);
@@ -168,7 +172,7 @@ int hprofShutdown_Class(void);
 
 
 /*
- * HprofHeap.c functions
+ * HprofHeap.cpp functions
  */
 
 int hprofStartHeapDump(hprof_context_t *ctx);
@@ -182,7 +186,7 @@ int hprofMarkRootObject(hprof_context_t *ctx,
 int hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj);
 
 /*
- * HprofOutput.c functions
+ * HprofOutput.cpp functions
  */
 
 void hprofContextInit(hprof_context_t *ctx, char *fileName, int fd,
@@ -215,18 +219,17 @@ int hprofAddU8ListToRecord(hprof_record_t *rec,
             hprofAddU4ListToRecord((rec), (const u4 *)(values), (numValues))
 
 /*
- * Hprof.c functions
+ * Hprof.cpp functions
  */
 
 hprof_context_t* hprofStartup(const char *outputFileName, int fd,
     bool directToDdms);
 bool hprofShutdown(hprof_context_t *ctx);
 void hprofFreeContext(hprof_context_t *ctx);
-
-/*
- * HprofVisit.c functions
- */
-
 int hprofDumpHeap(const char* fileName, int fd, bool directToDdms);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif  // _DALVIK_HPROF_HPROF
similarity index 98%
rename from vm/hprof/HprofHeap.c
rename to vm/hprof/HprofHeap.cpp
index ee24a7a..8ec0100 100644 (file)
@@ -129,7 +129,7 @@ hprofMarkRootObject(hprof_context_t *ctx, const Object *obj, jobject jniObj)
 {
     hprof_record_t *rec = &ctx->curRec;
     int err;
-    hprof_heap_tag_t heapTag = ctx->gcScanState;
+    hprof_heap_tag_t heapTag = (hprof_heap_tag_t)ctx->gcScanState;
 
     if (heapTag == 0) {
         return 0;
@@ -382,7 +382,7 @@ hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj)
                 /* Dump the elements, which are always objects or NULL.
                  */
                 hprofAddIdListToRecord(rec,
-                        (const hprof_object_id *)aobj->contents, length);
+                        (const hprof_object_id *)(void *)aobj->contents, length);
             } else {
                 hprof_basic_type t;
                 size_t size;
@@ -410,10 +410,10 @@ hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj)
                     hprofAddU1ListToRecord(rec, (const u1 *)aobj->contents,
                             length);
                 } else if (size == 2) {
-                    hprofAddU2ListToRecord(rec, (const u2 *)aobj->contents,
+                    hprofAddU2ListToRecord(rec, (const u2 *)(void *)aobj->contents,
                             length);
                 } else if (size == 4) {
-                    hprofAddU4ListToRecord(rec, (const u4 *)aobj->contents,
+                    hprofAddU4ListToRecord(rec, (const u4 *)(void *)aobj->contents,
                             length);
                 } else if (size == 8) {
                     hprofAddU8ListToRecord(rec, (const u8 *)aobj->contents,
index 7dbe9ac..67b9b4a 100644 (file)
 #include "InterpDefs.h"
 #include "mterp/common/jit-config.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define JIT_MAX_TRACE_LEN 100
 
 #if defined (WITH_SELF_VERIFICATION)
@@ -166,4 +170,8 @@ void dvmJitUpdateThreadStateSingle(Thread* threead);
 void dvmJitUpdateThreadStateAll(void);
 void dvmJitResumeTranslation(Thread* self, const u2* pc, const u4* fp);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INTERP_JIT*/
index 10c04a0..403cae2 100644 (file)
@@ -23,6 +23,9 @@
 #include "jni.h"
 #include <stdarg.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /*
 Stack layout
@@ -279,4 +282,8 @@ void dvmCleanupStackOverflow(Thread* self, const Object* exception);
 void dvmDumpThreadStack(const DebugOutputTarget* target, Thread* thread);
 void dvmDumpRunningThreadStack(const DebugOutputTarget* target, Thread* thread);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_INTERP_STACK*/
index 7c82dc0..4d32de2 100644 (file)
 #ifndef _DALVIK_NATIVE_INTERNALNATIVE
 #define _DALVIK_NATIVE_INTERNALNATIVE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Some setup for internal native functions.
  */
@@ -29,4 +33,8 @@ DalvikNativeFunc dvmLookupInternalNativeMethod(const Method* method);
 /* exception-throwing stub for abstract methods (DalvikNativeFunc) */
 void dvmAbstractMethodStub(const u4* args, JValue* pResult);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_NATIVE_INTERNALNATIVE*/
index 440e60d..35ab44c 100644 (file)
 #ifndef _DALVIK_NATIVE_INTERNALNATIVEPRIV
 #define _DALVIK_NATIVE_INTERNALNATIVEPRIV
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Return macros.  Note we use "->i" instead of "->z" for boolean; this
  * is because the interpreter expects everything to be a 32-bit value.
@@ -112,4 +116,8 @@ extern const DalvikNativeMethod dvm_org_apache_harmony_dalvik_ddmc_DdmVmInternal
 extern const DalvikNativeMethod dvm_org_apache_harmony_dalvik_NativeTestTarget[];
 extern const DalvikNativeMethod dvm_sun_misc_Unsafe[];
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_NATIVE_INTERNALNATIVEPRIV*/
index 105c9e1..8633d89 100644 (file)
 #ifndef _DALVIK_OO_ACCESSCHECK
 #define _DALVIK_OO_ACCESSCHECK
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Determine whether the "accessFrom" class is allowed to get at "clazz".
  */
@@ -40,4 +44,8 @@ bool dvmCheckFieldAccess(const ClassObject* accessFrom, const Field* field);
  */
 bool dvmInSamePackage(const ClassObject* class1, const ClassObject* class2);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_ACCESSCHECK*/
index 9a873e6..585f896 100644 (file)
 #ifndef _DALVIK_OO_ARRAY
 #define _DALVIK_OO_ARRAY
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* width of an object reference, for arrays of objects */
 #define kObjectArrayRefWidth    sizeof(Object*)
 
@@ -167,4 +171,8 @@ size_t dvmArrayObjectSize(const ArrayObject *array);
  */
 size_t dvmArrayClassElementWidth(const ClassObject* clazz);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_ARRAY*/
index 3ad44bd..43a3954 100644 (file)
 #ifndef _DALVIK_OO_CLASS
 #define _DALVIK_OO_CLASS
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * The classpath and bootclasspath differ in that only the latter is
  * consulted when looking for classes needed by the VM.  When searching
@@ -285,4 +289,8 @@ int dvmCompareNameDescriptorAndMethod(const char* name,
  */
 size_t dvmClassObjectSize(const ClassObject *clazz);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_CLASS*/
index b32d5b9..86c0b95 100644 (file)
 #ifndef _DALVIK_OO_OBJECT
 #define _DALVIK_OO_OBJECT
 
-#include <Atomic.h>
-
 #include <stddef.h>
+#include "Atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* fwd decl */
 struct DataObject;
@@ -779,4 +782,8 @@ INLINE u4 dvmGetMethodInsnsSize(const Method* meth) {
 /* debugging */
 void dvmDumpObject(const Object* obj);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_OBJECT*/
index ef01834..1579a56 100644 (file)
 #ifndef _DALVIK_OO_OBJECTINLINES
 #define _DALVIK_OO_OBJECTINLINES
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * Store a single value in the array, and if the value isn't null,
  * note in the write barrier.
@@ -354,4 +358,8 @@ INLINE void dvmSetStaticFieldObjectVolatile(StaticField* sfield, Object* val) {
     }
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_OBJECTINLINES*/
index 70b2294..1403e77 100644 (file)
 #ifndef _DALVIK_OO_RESOLVE
 #define _DALVIK_OO_RESOLVE
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /*
  * "Direct" and "virtual" methods are stored independently.  The type of call
  * used to invoke the method determines which list we search, and whether
@@ -92,4 +96,8 @@ StringObject* dvmResolveString(const ClassObject* referrer, u4 stringIdx);
  */
 const char* dvmMethodTypeStr(MethodType methodType);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_RESOLVE*/
index 1397998..07bae47 100644 (file)
 #ifndef _DALVIK_OO_TYPECHECK
 #define _DALVIK_OO_TYPECHECK
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* VM startup/shutdown */
 bool dvmInstanceofStartup(void);
 void dvmInstanceofShutdown(void);
@@ -75,4 +79,8 @@ INLINE int dvmIsSubClass(const ClassObject* sub, const ClassObject* clazz) {
 bool dvmCanPutArrayElement(const ClassObject* elemClass,
     const ClassObject* arrayClass);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /*_DALVIK_OO_TYPECHECK*/