[WTF] Remove CPU(HPPA) in StackBounds by using runtime stack direction test
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Nov 2017 14:09:50 +0000 (14:09 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 18 Nov 2017 14:09:50 +0000 (14:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=179859

Reviewed by JF Bastien.

Currently, we know that CPU(HPPA)'s stack direction is upward! But listing
CPU architectures here is not a scalable way.

Instead, we use runtime stack direction test. By doing so, we can handle
such a strange architecture without listing the CPU to Platform.h. This paves
the way to dropping many CPUs in Platform.h by replacing them with CPU(UNKNOWN)[1].

We also fix StackBounds::isGrowingDownward().

[1]: https://bugs.webkit.org/show_bug.cgi?id=179243

* wtf/StackBounds.cpp:
(WTF::StackBounds::stackDirection):
(WTF::testStackDirection2):
(WTF::testStackDirection):
(WTF::StackBounds::newThreadStackBounds):
(WTF::StackBounds::currentThreadStackBoundsInternal):
* wtf/StackBounds.h:
(WTF::StackBounds::isGrowingDownward const):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@225015 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/StackBounds.cpp
Source/WTF/wtf/StackBounds.h

index e073fdb..6671f6f 100644 (file)
@@ -1,3 +1,30 @@
+2017-11-18  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [WTF] Remove CPU(HPPA) in StackBounds by using runtime stack direction test
+        https://bugs.webkit.org/show_bug.cgi?id=179859
+
+        Reviewed by JF Bastien.
+
+        Currently, we know that CPU(HPPA)'s stack direction is upward! But listing
+        CPU architectures here is not a scalable way.
+
+        Instead, we use runtime stack direction test. By doing so, we can handle
+        such a strange architecture without listing the CPU to Platform.h. This paves
+        the way to dropping many CPUs in Platform.h by replacing them with CPU(UNKNOWN)[1].
+
+        We also fix StackBounds::isGrowingDownward().
+
+        [1]: https://bugs.webkit.org/show_bug.cgi?id=179243
+
+        * wtf/StackBounds.cpp:
+        (WTF::StackBounds::stackDirection):
+        (WTF::testStackDirection2):
+        (WTF::testStackDirection):
+        (WTF::StackBounds::newThreadStackBounds):
+        (WTF::StackBounds::currentThreadStackBoundsInternal):
+        * wtf/StackBounds.h:
+        (WTF::StackBounds::isGrowingDownward const):
+
 2017-11-17  Chris Dumez  <cdumez@apple.com>
 
         Use a strongly typed identifier for SWServer::Connection
index afb088a..5990d46 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "config.h"
 #include "StackBounds.h"
+#include <mutex>
+#include <wtf/NoTailCalls.h>
 
 #if OS(DARWIN)
 
 
 namespace WTF {
 
+#if CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS)
+ALWAYS_INLINE StackBounds::StackDirection StackBounds::stackDirection()
+{
+    return StackDirection::Downward;
+}
+#else
+static NEVER_INLINE NOT_TAIL_CALLED StackBounds::StackDirection testStackDirection2(volatile const int* pointer)
+{
+    volatile int stackValue = 42;
+    return (pointer < &stackValue) ? StackBounds::StackDirection::Upward : StackBounds::StackDirection::Downward;
+}
+
+static NEVER_INLINE NOT_TAIL_CALLED StackBounds::StackDirection testStackDirection()
+{
+    NO_TAIL_CALLS();
+    volatile int stackValue = 42;
+    return testStackDirection2(&stackValue);
+}
+
+NEVER_INLINE StackBounds::StackDirection StackBounds::stackDirection()
+{
+    static StackBounds::StackDirection result = StackBounds::StackDirection::Downward;
+    static std::once_flag onceKey;
+    std::call_once(onceKey, [] {
+        NO_TAIL_CALLS();
+        result = testStackDirection();
+    });
+    return result;
+}
+#endif
+
 #if OS(DARWIN)
 
 StackBounds StackBounds::newThreadStackBounds(PlatformThreadHandle thread)
 {
+    ASSERT(stackDirection() == StackDirection::Downward);
     void* origin = pthread_get_stackaddr_np(thread);
     rlim_t size = pthread_get_stacksize_np(thread);
     void* bound = static_cast<char*>(origin) - size;
@@ -54,6 +88,7 @@ StackBounds StackBounds::newThreadStackBounds(PlatformThreadHandle thread)
 
 StackBounds StackBounds::currentThreadStackBoundsInternal()
 {
+    ASSERT(stackDirection() == StackDirection::Downward);
     if (pthread_main_np()) {
         // FIXME: <rdar://problem/13741204>
         // pthread_get_size lies to us when we're the main thread, use get_rlimit instead
@@ -76,11 +111,11 @@ StackBounds StackBounds::newThreadStackBounds(PlatformThreadHandle thread)
     stack_t stack;
     pthread_stackseg_np(thread, &stack);
     void* origin = stack.ss_sp;
-#if CPU(HPPA)
-    void* bound = static_cast<char*>(origin) + stack.ss_size;
-#else
-    void* bound = static_cast<char*>(origin) - stack.ss_size;
-#endif
+    void* bound = nullptr;
+    if (stackDirection() == StackDirection::Upward)
+        bound = static_cast<char*>(origin) + stack.ss_size;
+    else
+        bound = static_cast<char*>(origin) - stack.ss_size;
     return StackBounds { origin, bound };
 }
 
@@ -105,6 +140,10 @@ StackBounds StackBounds::newThreadStackBounds(PlatformThreadHandle thread)
     ASSERT(bound);
     pthread_attr_destroy(&sattr);
     void* origin = static_cast<char*>(bound) + stackSize;
+    // pthread_attr_getstack's bound is the lowest accessible pointer of the stack.
+    // If stack grows up, origin and bound in this code should be swapped.
+    if (stackDirection() == StackDirection::Upward)
+        std::swap(origin, bound);
     return StackBounds { origin, bound };
 }
 
@@ -119,6 +158,7 @@ StackBounds StackBounds::currentThreadStackBoundsInternal()
 
 StackBounds StackBounds::currentThreadStackBoundsInternal()
 {
+    ASSERT(stackDirection() == StackDirection::Downward);
     MEMORY_BASIC_INFORMATION stackOrigin = { 0 };
     VirtualQuery(&stackOrigin, &stackOrigin, sizeof(stackOrigin));
     // stackOrigin.AllocationBase points to the reserved stack memory base address.
index 5234cd2..13f6be6 100644 (file)
@@ -41,6 +41,8 @@ class StackBounds {
     const static size_t s_defaultAvailabilityDelta = 64 * 1024;
 
 public:
+    enum class StackDirection { Upward, Downward };
+
     static constexpr StackBounds emptyBounds() { return StackBounds(); }
 
 #if HAVE(STACK_BOUNDS_FOR_NEW_THREAD)
@@ -121,7 +123,7 @@ public:
     bool isGrowingDownward() const
     {
         ASSERT(m_origin && m_bound);
-        return true;
+        return m_bound <= m_origin;
     }
 
 private:
@@ -137,6 +139,8 @@ private:
     {
     }
 
+    static StackDirection stackDirection();
+
     WTF_EXPORT_PRIVATE static StackBounds currentThreadStackBoundsInternal();
 
     void checkConsistency() const