Enable FEATURE_HIJACK for ARM (dotnet/coreclr#5404)
authorJonghyun Park <parjong@gmail.com>
Thu, 2 Jun 2016 13:57:13 +0000 (22:57 +0900)
committerJan Kotas <jkotas@microsoft.com>
Thu, 2 Jun 2016 13:57:13 +0000 (06:57 -0700)
Currently, FEATURE_HIJACK is disabled for ARM, and thus CoreCLR got
stuck if GC is invoked from JITed code.

This commit attempts to port FEATURE_HIJACK from ARM (windows) in order
to fix dotnet/coreclr#5403.

Commit migrated from https://github.com/dotnet/coreclr/commit/c4075441c86e1073e2f48e61be3ed5c58f6d27d0

src/coreclr/clrdefinitions.cmake
src/coreclr/src/vm/arm/asmhelpers.S
src/coreclr/src/vm/gccover.cpp

index 0b34e57..ea65682 100644 (file)
@@ -114,9 +114,9 @@ if(CLR_CMAKE_PLATFORM_UNIX)
 endif(CLR_CMAKE_PLATFORM_UNIX)
 add_definitions(-DFEATURE_EXCEPTIONDISPATCHINFO)
 # NetBSD doesn't implement this feature
-if(NOT CLR_CMAKE_PLATFORM_UNIX_ARM AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+if(NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
     add_definitions(-DFEATURE_HIJACK)
-endif(NOT CLR_CMAKE_PLATFORM_UNIX_ARM AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+endif(NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
 add_definitions(-DFEATURE_HOST_ASSEMBLY_RESOLVER)
 add_definitions(-DFEATURE_ICASTABLE)
 if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
index 7b614e7..df77f1a 100644 (file)
@@ -1360,3 +1360,54 @@ DelayLoad_Helper\suffix:
     DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj
 
 #endif // FEATURE_READYTORUN
+
+#ifdef FEATURE_HIJACK
+
+// ------------------------------------------------------------------
+// Hijack function for functions which return a reference type
+        NESTED_ENTRY OnHijackObjectTripThread, _TEXT, NoHandler
+        PROLOG_PUSH "{r0,r4-r11,lr}"
+
+        CHECK_STACK_ALIGNMENT
+
+        mov r0, sp
+        bl OnHijackObjectWorker
+
+        EPILOG_POP "{r0,r4-r11,pc}"
+        NESTED_END OnHijackObjectTripThread, _TEXT
+
+// ------------------------------------------------------------------
+// Hijack function for functions which return an interior pointer within an object allocated in managed heap
+        NESTED_ENTRY OnHijackInteriorPointerTripThread, _TEXT, NoHandler
+        PROLOG_PUSH "{r0,r4-r11,lr}"
+
+        CHECK_STACK_ALIGNMENT
+
+        mov r0, sp
+        bl C_FUNC(OnHijackInteriorPointerWorker)
+
+        EPILOG_POP "{r0,r4-r11,pc}"
+        NESTED_END OnHijackInteriorPointerTripThread, _TEXT
+
+// ------------------------------------------------------------------
+// Hijack function for functions which return a value type
+        NESTED_ENTRY OnHijackScalarTripThread, _TEXT, NoHandler
+        PROLOG_PUSH "{r0,r4-r11,lr}"
+
+        PROLOG_VPUSH "{d0-d3}"    // saving as d0-d3 can have the floating point return value
+        PROLOG_PUSH "{r1}"        // saving as r1 can have partial return value when return is > 32 bits
+        alloc_stack 4             // 8 byte align
+
+        CHECK_STACK_ALIGNMENT
+
+        add r0, sp, #40
+        bl C_FUNC(OnHijackScalarWorker)
+
+        free_stack 4
+        EPILOG_POP "{r1}"
+        EPILOG_VPOP "{d0-d3}"
+
+        EPILOG_POP "{r0,r4-r11,pc}"
+        NESTED_END OnHijackScalarTripThread, _TEXT
+#endif
+
index 0b5bf34..c5ffc4c 100644 (file)
@@ -1133,7 +1133,11 @@ bool IsGcCoverageInterrupt(LPVOID ip)
     }
 
     // Now it's safe to dereference the IP to check the instruction
+#ifdef _TARGET_ARM_    
+    UINT16 instructionCode = *reinterpret_cast<UINT16 *>(ip);
+#else
     UINT8 instructionCode = *reinterpret_cast<UINT8 *>(ip);
+#endif 
     switch (instructionCode)
     {
         case INTERRUPT_INSTR: