diff --git a/AK/Forward.h b/AK/Forward.h index d4c33aed92..cbf3819934 100644 --- a/AK/Forward.h +++ b/AK/Forward.h @@ -39,6 +39,7 @@ class JsonObject; class JsonValue; class LogStream; class SharedBuffer; +class StackInfo; class String; class StringBuilder; class StringImpl; @@ -160,6 +161,7 @@ using AK::RefPtr; using AK::SharedBuffer; using AK::SinglyLinkedList; using AK::Span; +using AK::StackInfo; using AK::String; using AK::StringBuilder; using AK::StringImpl; diff --git a/AK/StackInfo.cpp b/AK/StackInfo.cpp new file mode 100644 index 0000000000..96f06d93be --- /dev/null +++ b/AK/StackInfo.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#ifdef __serenity__ +# include +#elif __linux__ or __APPLE__ +# include +#endif + +namespace AK { + +StackInfo::StackInfo() +{ +#ifdef __serenity__ + if (get_stack_bounds(&m_base, &m_size) < 0) { + perror("get_stack_bounds"); + ASSERT_NOT_REACHED(); + } +#elif __linux__ + pthread_attr_t attr = {}; + if (int rc = pthread_getattr_np(pthread_self(), &attr) != 0) { + fprintf(stderr, "pthread_getattr_np: %s\n", strerror(-rc)); + ASSERT_NOT_REACHED(); + } + if (int rc = pthread_attr_getstack(&attr, (void**)&m_base, &m_size) != 0) { + fprintf(stderr, "pthread_attr_getstack: %s\n", strerror(-rc)); + ASSERT_NOT_REACHED(); + } + pthread_attr_destroy(&attr); +#elif __APPLE__ + m_base = (FlatPtr)pthread_get_stackaddr_np(pthread_self()); + pthread_attr_t attr = {}; + if (int rc = pthread_attr_getstacksize(&attr, &m_size) != 0) { + fprintf(stderr, "pthread_attr_getstacksize: %s\n", strerror(-rc)); + ASSERT_NOT_REACHED(); + } + pthread_attr_destroy(&attr); +#else + ASSERT_NOT_REACHED(); +#endif + + m_top = m_base + m_size; +} + +} diff --git a/AK/StackInfo.h b/AK/StackInfo.h new file mode 100644 index 0000000000..db3ca11e5a --- /dev/null +++ b/AK/StackInfo.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, the SerenityOS developers. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace AK { + +class StackInfo { +public: + StackInfo(); + + FlatPtr base() const { return m_base; } + FlatPtr top() const { return m_top; } + size_t size() const { return m_size; } + size_t size_free() const + { + FlatPtr dummy; + return reinterpret_cast(&dummy) - m_base; + } + +private: + FlatPtr m_base; + FlatPtr m_top; + size_t m_size; +}; + +} + +using AK::StackInfo; diff --git a/Libraries/LibJS/Heap/Heap.cpp b/Libraries/LibJS/Heap/Heap.cpp index c6e3756a99..02b9347f12 100644 --- a/Libraries/LibJS/Heap/Heap.cpp +++ b/Libraries/LibJS/Heap/Heap.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -35,17 +36,8 @@ #include #include #include -#include -#ifdef __serenity__ -# include -#elif __linux__ or __APPLE__ -# include -#endif - -#ifdef __serenity__ //#define HEAP_DEBUG -#endif namespace JS { @@ -151,39 +143,10 @@ void Heap::gather_conservative_roots(HashTable& roots) for (size_t i = 0; i < ((size_t)sizeof(buf)) / sizeof(FlatPtr); i += sizeof(FlatPtr)) possible_pointers.set(raw_jmp_buf[i]); - FlatPtr stack_base; - size_t stack_size; - -#ifdef __serenity__ - if (get_stack_bounds(&stack_base, &stack_size) < 0) { - perror("get_stack_bounds"); - ASSERT_NOT_REACHED(); - } -#elif __linux__ - pthread_attr_t attr = {}; - if (int rc = pthread_getattr_np(pthread_self(), &attr) != 0) { - fprintf(stderr, "pthread_getattr_np: %s\n", strerror(-rc)); - ASSERT_NOT_REACHED(); - } - if (int rc = pthread_attr_getstack(&attr, (void**)&stack_base, &stack_size) != 0) { - fprintf(stderr, "pthread_attr_getstack: %s\n", strerror(-rc)); - ASSERT_NOT_REACHED(); - } - pthread_attr_destroy(&attr); -#elif __APPLE__ - stack_base = (FlatPtr)pthread_get_stackaddr_np(pthread_self()); - pthread_attr_t attr = {}; - if (int rc = pthread_attr_getstacksize(&attr, &stack_size) != 0) { - fprintf(stderr, "pthread_attr_getstacksize: %s\n", strerror(-rc)); - ASSERT_NOT_REACHED(); - } - pthread_attr_destroy(&attr); -#endif - FlatPtr stack_reference = reinterpret_cast(&dummy); - FlatPtr stack_top = stack_base + stack_size; + auto& stack_info = m_vm.stack_info(); - for (FlatPtr stack_address = stack_reference; stack_address < stack_top; stack_address += sizeof(FlatPtr)) { + for (FlatPtr stack_address = stack_reference; stack_address < stack_info.top(); stack_address += sizeof(FlatPtr)) { auto data = *reinterpret_cast(stack_address); possible_pointers.set(data); } diff --git a/Libraries/LibJS/Runtime/VM.h b/Libraries/LibJS/Runtime/VM.h index 8c86830906..7dc955bfeb 100644 --- a/Libraries/LibJS/Runtime/VM.h +++ b/Libraries/LibJS/Runtime/VM.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -165,6 +166,8 @@ public: Value last_value() const { return m_last_value; } void set_last_value(Badge, Value value) { m_last_value = value; } + const StackInfo& stack_info() const { return m_stack_info; }; + bool underscore_is_last_value() const { return m_underscore_is_last_value; } void set_underscore_is_last_value(bool b) { m_underscore_is_last_value = b; } @@ -248,6 +251,8 @@ private: ScopeType m_unwind_until { ScopeType::None }; FlyString m_unwind_until_label; + StackInfo m_stack_info; + bool m_underscore_is_last_value { false }; HashMap m_global_symbol_map;