Преглед изворни кода

Assorted Linux fixes

- Turn off fpo- stack walking depends on it on retail builds
- Speed up debug builds by improving performance of IsAddressOnStack
- Add support for debug and retail builds being in different directories
Hitesh Kanwathirtha пре 9 година
родитељ
комит
abad8a98d7
5 измењених фајлова са 44 додато и 6 уклоњено
  1. 4 0
      CMakeLists.txt
  2. 9 1
      build.sh
  3. 1 0
      lib/Common/CommonPal.h
  4. 1 5
      lib/Runtime/Base/ThreadContext.cpp
  5. 29 0
      pal/src/thread/thread.cpp

+ 4 - 0
CMakeLists.txt

@@ -110,6 +110,10 @@ if(CLR_CMAKE_PLATFORM_UNIX)
         -fdelayed-template-parsing"
     )
 
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
+        -fno-omit-frame-pointer"
+    )
+  
     # CXX / CC COMPILER FLAGS
     add_compile_options(
         -fms-extensions

+ 9 - 1
build.sh

@@ -147,8 +147,16 @@ fi
 
 pushd BuildLinux > /dev/null
 
+build_directory="${BUILD_TYPE,,}"
+if [ ! -d "$build_directory" ]; then
+    SAFE_RUN `mkdir $build_directory`
+fi
+
+pushd $build_directory > /dev/null
+
 echo Generating $BUILD_TYPE makefiles
-cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
+cmake $CMAKE_GEN $CC_PREFIX $ICU_PATH -DCMAKE_BUILD_TYPE=$BUILD_TYPE ../..
 
 $MAKE $MULTICORE_BUILD 2>&1 | tee build.log
 popd > /dev/null
+popd > /dev/null

+ 1 - 0
lib/Common/CommonPal.h

@@ -365,6 +365,7 @@ BOOL WINAPI GetModuleHandleEx(
 );
 
 int GetCurrentThreadStackLimits(ULONG_PTR* lowLimit, ULONG_PTR* highLimit);
+bool IsAddressOnStack(ULONG_PTR address);
 
 errno_t rand_s(unsigned int* randomValue);
 

+ 1 - 5
lib/Runtime/Base/ThreadContext.cpp

@@ -1431,11 +1431,7 @@ ThreadContext::IsOnStack(void const *ptr)
     bool isOnStack = (void*)lowLimit <= ptr && ptr < (void*)highLimit;
     return isOnStack;
 #elif !defined(_MSC_VER)
-    ULONG_PTR lowLimit = 0;
-    ULONG_PTR highLimit = 0;
-    ::GetCurrentThreadStackLimits(&lowLimit, &highLimit);
-    bool isOnStack = (void*)lowLimit <= ptr && ptr < (void*)highLimit;
-    return isOnStack;
+    return ::IsAddressOnStack((ULONG_PTR) ptr);
 #else
     AssertMsg(FALSE, "IsOnStack -- not implemented yet case");
     Js::Throw::NotImplemented();

+ 29 - 0
pal/src/thread/thread.cpp

@@ -2820,3 +2820,32 @@ void GetCurrentThreadStackLimits(ULONG_PTR* lowLimit, ULONG_PTR* highLimit)
     *highLimit = (ULONG_PTR) stackbase;
 #endif
 }
+
+static thread_local ULONG_PTR s_cachedThreadHighLimit = 0;
+
+bool IsAddressOnStack(ULONG_PTR address)
+{
+    // Assumption: Stack always grows, never shrinks and the high limit is stable
+    // Assumption: pthread_getattr_np is slow, so we need to cache the current stack
+    // bounds to speed up checking if a given address is on the stack
+    // The semantics of IsAddressOnStack is that we care if a given address is
+    // in the range of the current stack pointer
+    if (s_cachedThreadHighLimit == 0)
+    {
+        ULONG_PTR lowLimit, highLimit;
+        GetCurrentThreadStackLimits(&lowLimit, &highLimit);
+
+        s_cachedThreadHighLimit = highLimit;
+    }
+
+    ULONG_PTR currentStackPtr = 0;
+
+    asm("mov %%rsp, %0;":"=r"(currentStackPtr));
+
+    if (currentStackPtr <= address && address < s_cachedThreadHighLimit)
+    {
+        return true;
+    }
+
+    return false;
+}