OSDN Git Service

Fix the protection of code cache for x86 JIT
authorJun Tian <jun.j.tian@intel.com>
Tue, 6 Aug 2013 07:03:15 +0000 (15:03 +0800)
committerElliott Hughes <enh@google.com>
Fri, 9 Aug 2013 23:57:16 +0000 (16:57 -0700)
During generation of code into code cache
an unprotected region of memory does not correspond to
protected one, The patch fixes that.

Author: Katkov Serguei <serguei.i.katkov@intel.com>

(cherry picked from commit 74a62214ef262380371bc21be2a1c42295046fb2)

Change-Id: I362a10897564b987c8a3b2dfc9ded8f0a9efd56a

vm/compiler/Compiler.cpp
vm/compiler/codegen/x86/CodegenInterface.cpp

index e18e6e6..f5b96b1 100644 (file)
@@ -213,14 +213,6 @@ bool dvmCompilerSetupCodeCache(void)
     /* Only flush the part in the code cache that is being used now */
     dvmCompilerCacheFlush((intptr_t) gDvmJit.codeCache,
                           (intptr_t) gDvmJit.codeCache + templateSize, 0);
-
-    int result = mprotect(gDvmJit.codeCache, gDvmJit.codeCacheSize,
-                          PROTECT_CODE_CACHE_ATTRS);
-
-    if (result == -1) {
-        ALOGE("Failed to remove the write permission for the code cache");
-        dvmAbort();
-    }
 #else
     gDvmJit.codeCacheByteUsed = 0;
     stream = (char*)gDvmJit.codeCache + gDvmJit.codeCacheByteUsed;
@@ -232,6 +224,14 @@ bool dvmCompilerSetupCodeCache(void)
     ALOGV("stream = %p after initJIT", stream);
 #endif
 
+    int result = mprotect(gDvmJit.codeCache, gDvmJit.codeCacheSize,
+                          PROTECT_CODE_CACHE_ATTRS);
+
+    if (result == -1) {
+        ALOGE("Failed to remove the write permission for the code cache");
+        dvmAbort();
+    }
+
     return true;
 }
 
index 451c5e5..337bd61 100644 (file)
@@ -1085,14 +1085,14 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit, JitTranslationInfo *info)
 
     info->codeAddress = NULL;
     stream = (char*)gDvmJit.codeCache + gDvmJit.codeCacheByteUsed;
+    streamStart = stream; /* trace start before alignment */
 
     // TODO: compile into a temporary buffer and then copy into the code cache.
     // That would let us leave the code cache unprotected for a shorter time.
     size_t unprotected_code_cache_bytes =
-            gDvmJit.codeCacheSize - gDvmJit.codeCacheByteUsed - CODE_CACHE_PADDING;
-    UNPROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+            gDvmJit.codeCacheSize - gDvmJit.codeCacheByteUsed;
+    UNPROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
 
-    streamStart = stream; /* trace start before alignment */
     stream += EXTRA_BYTES_FOR_CHAINING; /* This is needed for chaining. Add the bytes before the alignment */
     stream = (char*)(((unsigned int)stream + 0xF) & ~0xF); /* Align trace to 16-bytes */
     streamMethodStart = stream; /* code start */
@@ -1252,7 +1252,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit, JitTranslationInfo *info)
             if(cg_ret < 0) {
                 endOfTrace(true/*freeOnly*/);
                 cUnit->baseAddr = NULL;
-                PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
                 return;
             }
         } else {
@@ -1293,7 +1293,7 @@ void dvmCompilerMIR2LIR(CompilationUnit *cUnit, JitTranslationInfo *info)
                     gDvmJit.codeCacheFull = true;
                     cUnit->baseAddr = NULL;
                     endOfTrace(true/*freeOnly*/);
-                    PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                    PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
                     return;
                 }
             }
@@ -1387,7 +1387,7 @@ gen_fallthrough:
                 gDvmJit.codeCacheFull = true;
                 cUnit->baseAddr = NULL;
                 endOfTrace(true); /* need to free structures */
-                PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+                PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
                 return;
             }
         }
@@ -1403,7 +1403,7 @@ gen_fallthrough:
          */
         ALOGI("JIT code cache full after endOfTrace (trace uses %uB)", (stream - streamStart));
         cUnit->baseAddr = NULL;
-        PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+        PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
         return;
     }
 
@@ -1425,7 +1425,7 @@ gen_fallthrough:
         ALOGI("JIT code cache full after ChainingCellCounts (trace uses %uB)", (stream - streamStart));
         gDvmJit.codeCacheFull = true;
         cUnit->baseAddr = NULL;
-        PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+        PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
         return;
     }
 
@@ -1434,7 +1434,7 @@ gen_fallthrough:
     *pOffset = streamCountStart - streamMethodStart; /* from codeAddr */
     pOffset[1] = streamChainingStart - streamMethodStart;
 
-    PROTECT_CODE_CACHE(stream, unprotected_code_cache_bytes);
+    PROTECT_CODE_CACHE(streamStart, unprotected_code_cache_bytes);
 
     gDvmJit.codeCacheByteUsed += (stream - streamStart);
     if (cUnit->printMe) {