From 56c47f24d53a64e7fe2d9fb801a63c22e84e52cb Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Wed, 28 Nov 2012 07:52:08 +0000 Subject: [PATCH] context: merge from trunk (replace align_stack() by assembler; remove stack-allocator) [SVN r81611] --- build/Jamfile.v2 | 37 ++-- doc/context.qbk | 1 - doc/stack.qbk | 188 +----------------- example/exit.cpp | 48 +++-- example/jump.cpp | 22 +- .../simple_stack_allocator.hpp | 0 example/transfer.cpp | 15 +- include/boost/context/all.hpp | 3 - .../context/detail/fcontext_x86_64_win.hpp | 19 +- include/boost/context/fcontext.hpp | 5 - .../boost/context/guarded_stack_allocator.hpp | 55 ----- include/boost/context/utils.hpp | 41 ---- performance/performance.cpp | 32 +-- src/asm/jump_i386_ms_pe_masm.asm | 1 - src/asm/jump_ppc32_sysv_elf_gas.S | 100 +++++----- src/asm/jump_ppc64_sysv_elf_gas.S | 2 +- src/asm/jump_x86_64_ms_pe_masm.asm | 91 +++++---- src/asm/make_arm_aapcs_elf_gas.S | 31 +-- src/asm/make_i386_ms_pe_masm.asm | 25 +-- src/asm/make_i386_sysv_elf_gas.S | 26 +-- src/asm/make_i386_sysv_macho_gas.S | 24 +-- src/asm/make_mips32_o32_elf_gas.S | 26 +-- src/asm/make_ppc32_sysv_elf_gas.S | 54 +++-- src/asm/make_ppc64_sysv_elf_gas.S | 28 +-- src/asm/make_x86_64_ms_pe_masm.asm | 58 ++---- src/asm/make_x86_64_sysv_elf_gas.S | 25 +-- src/asm/make_x86_64_sysv_macho_gas.S | 20 +- src/fcontext.cpp | 36 ---- src/guarded_stack_allocator_posix.cpp | 152 -------------- src/guarded_stack_allocator_windows.cpp | 156 --------------- src/utils_posix.cpp | 39 ---- src/utils_windows.cpp | 48 ----- test/test_context.cpp | 88 ++++---- 33 files changed, 353 insertions(+), 1143 deletions(-) rename {include/boost/context => example}/simple_stack_allocator.hpp (100%) delete mode 100644 include/boost/context/guarded_stack_allocator.hpp delete mode 100644 include/boost/context/utils.hpp delete mode 100644 src/fcontext.cpp delete mode 100644 src/guarded_stack_allocator_posix.cpp delete mode 100644 src/guarded_stack_allocator_windows.cpp delete mode 100644 src/utils_posix.cpp delete mode 100644 src/utils_windows.cpp diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 3116cca..1342da4 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -281,7 +281,8 @@ alias asm_context_sources ; alias asm_context_sources - : asm/make_i386_ms_pe_masm.asm + : seh.cpp + asm/make_i386_ms_pe_masm.asm asm/jump_i386_ms_pe_masm.asm : ms 32 @@ -292,7 +293,8 @@ alias asm_context_sources ; alias asm_context_sources - : asm/make_i386_ms_pe_masm.asm + : seh.cpp + asm/make_i386_ms_pe_masm.asm asm/jump_i386_ms_pe_masm.asm : ms 32 @@ -303,7 +305,8 @@ alias asm_context_sources ; alias asm_context_sources - : [ make asm/make_i386_ms_pe_masm.o : asm/make_i386_ms_pe_masm.asm : @masm ] + : seh.cpp + [ make asm/make_i386_ms_pe_masm.o : asm/make_i386_ms_pe_masm.asm : @masm ] [ make asm/jump_i386_ms_pe_masm.o : asm/jump_i386_ms_pe_masm.asm : @masm ] : ms 32 @@ -385,7 +388,8 @@ alias asm_context_sources ; alias asm_context_sources - : asm/make_x86_64_ms_pe_masm.asm + : seh.cpp + asm/make_x86_64_ms_pe_masm.asm asm/jump_x86_64_ms_pe_masm.asm : ms 64 @@ -396,7 +400,8 @@ alias asm_context_sources ; alias asm_context_sources - : asm/make_x86_64_ms_pe_masm.asm + : seh.cpp + asm/make_x86_64_ms_pe_masm.asm asm/jump_x86_64_ms_pe_masm.asm : ms 64 @@ -407,7 +412,8 @@ alias asm_context_sources ; alias asm_context_sources - : [ make asm/make_x86_64_ms_pe_masm.o : asm/make_x86_64_ms_pe_masm.asm : @masm64 ] + : seh.cpp + [ make asm/make_x86_64_ms_pe_masm.o : asm/make_x86_64_ms_pe_masm.asm : @masm64 ] [ make asm/jump_x86_64_ms_pe_masm.o : asm/jump_x86_64_ms_pe_masm.asm : @masm64 ] : ms 64 @@ -418,36 +424,17 @@ alias asm_context_sources explicit asm_context_sources ; - alias select_asm_context_sources : asm_context_sources : [ architecture.architecture ] [ architecture.address-model ] ; - -alias context_sources - : fcontext.cpp - seh.cpp - guarded_stack_allocator_windows.cpp - utils_windows.cpp - : windows - ; - -alias context_sources - : fcontext.cpp - guarded_stack_allocator_posix.cpp - utils_posix.cpp - ; - explicit context_sources ; - lib boost_context : select_asm_context_sources - context_sources : shared:BOOST_CONTEXT_DYN_LINK=1 ; - boost-install boost_context ; diff --git a/doc/context.qbk b/doc/context.qbk index a47e5ac..dde293a 100644 --- a/doc/context.qbk +++ b/doc/context.qbk @@ -41,7 +41,6 @@ [def __threads__ ['threads]] [def __tls__ ['thread-local storage]] [def __stack_allocator__ ['StackAllocator]] -[def __stack_allocator_concept__ ['StackAllocator concept]] [def __fcontext__ ['fcontext_t]] [def __ucontext__ ['ucontext_t]] diff --git a/doc/stack.qbk b/doc/stack.qbk index 497cec7..5d179a7 100644 --- a/doc/stack.qbk +++ b/doc/stack.qbk @@ -1,5 +1,4 @@ -[/ - Copyright Oliver Kowalke 2009. +[/ Copyright Oliver Kowalke 2009. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt @@ -8,190 +7,19 @@ [section:stack Stack allocation] A __fcontext__ requires a stack which will be allocated/deallocated -by a __stack_allocator__. -__boost_context__ provides the default implementation `stack_allocator` but a -customized __stack_allocator__ can be used instead. +by a __stack_allocator__ (examples contain an implementation +of [@boost:/libs/context/example/simple_stack_allocator.hpp +simple_stack_allocator]). -[heading __stack_allocator_concept__] -A __stack_allocator__ must satisfy the __stack_allocator_concept__ requirements -shown in the following table, in which `a` is an object of a -__stack_allocator__ type, `p` is a `void *`, and `s` is a `std::size_t`: - -[table - [[expression][return type][notes]] - [ - [`a.allocate( s)`] - [`void *`] - [returns a pointer to `s` bytes allocated from the stack] - ] - [ - [`a.deallocate( p, s)`] - [`void`] - [deallocates `s` bytes of memory beginning at `p`, - a pointer previously returned by `a.allocate()`] - ] -] - -[important The implementation of `allocate()` might include logic to protect +[note The implementation of a __stack_allocator__ might include logic to protect against exceeding the context's available stack size rather than leaving it as undefined behaviour.] -[important Calling `deallocate()` with a pointer not returned by `allocate()` -results in undefined behaviour.] - [note The stack is not required to be aligned; alignment takes place inside -`make_fcontext()`.] +__make_fcontext__.] -[note Depending on the architecture `allocate()` returns an address from the -top of the stack (growing downwards) or the bottom of the stack (growing +[note Depending on the architecture __stack_allocator__ returns an address from +the top of the stack (grows downwards) or the bottom of the stack (grows upwards).] - -[section:guarded_stack_allocator Class `guarded_stack_allocator`] - -__boost_context__ provides the class `guarded_stack_allocator` which models -the __stack_allocator_concept__ concept. -It appends a __guard_page__ at the end of each stack to protect against exceeding -the stack. If the guard page is accessed (read or write operation) a -segmentation fault/access violation is generated by the operating system. - -[note The appended `guard page` is [*not] mapped to physical memory, only -virtual addresses are used.] - - class guarded_stack_allocator - { - static bool is_stack_unbound(); - - static std::size_t maximum_stacksize(); - - static std::size_t default_stacksize(); - - static std::size_t minimum_stacksize(); - - void * allocate( std::size_t size); - - void deallocate( void * sp, std::size_t size); - } - -[heading `static bool is_stack_unbound()`] -[variablelist -[[Returns:] [Returns `true` if the environment defines no limit for the size of a stack.]] -] - -[heading `static std::size_t maximum_stacksize()`] -[variablelist -[[Preconditions:] [`is_stack_unbound()` returns `false`.]] -[[Returns:] [Returns the maximum size in bytes of stack defined by the environment.]] -] - -[heading `static std::size_t default_stacksize()`] -[variablelist -[[Returns:] [Returns a default stack size, which may be platform specific. -If the stack is unbound then the present implementation returns the maximum of -`64 kB` and `minimum_stacksize()`.]] -] - -[heading `static std::size_t minimum_stacksize()`] -[variablelist -[[Returns:] [Returns the minimum size in bytes of stack defined by the -environment (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).]] -] - -[heading `void * allocate( std::size_t size)`] -[variablelist -[[Preconditions:] [`minimum_stacksize() > size` and -`! is_stack_unbound() && ( maximum_stacksize() < size)`.]] -[[Effects:] [Allocates memory of `size` Bytes and appends one guard page at the -end of the allocated memory.]] -[[Returns:] [Returns pointer to the start address of the new stack. Depending -on the architecture the stack grows downwards/upwards the returned address is -the highest/lowest address of the stack.]] -] - -[heading `void deallocate( void * sp, std::size_t size)`] -[variablelist -[[Preconditions:] [`sp` is valid, `minimum_stacksize() > size` and -`! is_stack_unbound() && ( maximum_stacksize() < size)`.]] -[[Effects:] [Deallocates the stack space.]] -] - -[endsect] - - -[section:simple_stack_allocator Template `simple_stack_allocator< size_t, size_t, size_t >`] - -__boost_context__ provides the class `simple_stack_allocator` which models -the __stack_allocator_concept__ concept. The template arguments define the -limits for the stack size. -The class simply allocates memory on the heap via `calloc()` - in contrast to -`guarded_stack_allocator` no guard page is appended. - -[important The user is responsible for valid stack limits (e.g. maximum, minimum -and default stacksize.] - - template< size_t Max, size_t Default, size_t Min > - class simple_stack_allocator - { - static std::size_t maximum_stacksize(); - - static std::size_t default_stacksize(); - - static std::size_t minimum_stacksize(); - - void * allocate( std::size_t size); - - void deallocate( void * sp, std::size_t size); - } - -[heading `static std::size_t maximum_stacksize()`] -[variablelist -[[Returns:] [Returns the maximum size in bytes of stack defined by the first -tempalte argument.]] -] - -[heading `static std::size_t default_stacksize()`] -[variablelist -[[Returns:] [Returns a default stack size in bytes defined by the second -template argument.]] -] - -[heading `static std::size_t minimum_stacksize()`] -[variablelist -[[Returns:] [Returns the minimum size in bytes of stack defined by the -third template argument.]] -] - -[heading `void * allocate( std::size_t size)`] -[variablelist -[[Preconditions:] [`minimum_stacksize() > size` and -`maximum_stacksize() < size`.]] -[[Effects:] [Allocates memory of `size` bytes (memory is set to NULL).]] -[[Returns:] [Returns pointer to the start address of the new stack. Depending -on the architecture the stack grows downwards/upwards the returned address is -the highest/lowest address of the stack.]] -] - -[heading `void deallocate( void * sp, std::size_t size)`] -[variablelist -[[Preconditions:] [`sp` is valid, `minimum_stacksize() > size` and -`maximum_stacksize() < size`.]] -[[Effects:] [Deallocates the stack space.]] -] - -[endsect] - - -[section:pagesize Free function `pagesize()`] - - std::size_t pagesize(); - -[heading `std::size_t pagesize()`] -[variablelist -[[Returns:] [Returns the size of a page in bytes.]] -] - -This function - -[endsect] - [endsect] diff --git a/example/exit.cpp b/example/exit.cpp index 2feb818..f55a79d 100644 --- a/example/exit.cpp +++ b/example/exit.cpp @@ -12,43 +12,53 @@ #include #include +#include "simple_stack_allocator.hpp" + namespace ctx = boost::context; +typedef ctx::simple_stack_allocator< + 8 * 1024 * 1024, // 8MB + 64 * 1024, // 64kB + 8 * 1024 // 8kB +> stack_allocator; + ctx::fcontext_t * fc1; ctx::fcontext_t * fc2; void f1( intptr_t) { - std::cout << "f1: entered" << std::endl; - std::cout << "f1: call jump_fcontext( fc1, fc2, 0)" << std::endl; - ctx::jump_fcontext( fc1, fc2, 0); - std::cout << "f1: return" << std::endl; + std::cout << "f1: entered" << std::endl; + std::cout << "f1: call jump_fcontext( fc1, fc2, 0)" << std::endl; + ctx::jump_fcontext( fc1, fc2, 0); + std::cout << "f1: return" << std::endl; } void f2( intptr_t) { - std::cout << "f2: entered" << std::endl; - std::cout << "f2: call jump_fcontext( fc2, fc1, 0)" << std::endl; - ctx::jump_fcontext( fc2, fc1, 0); - BOOST_ASSERT( false && ! "f2: never returns"); + std::cout << "f2: entered" << std::endl; + std::cout << "f2: call jump_fcontext( fc2, fc1, 0)" << std::endl; + ctx::jump_fcontext( fc2, fc1, 0); + BOOST_ASSERT( false && ! "f2: never returns"); } int main( int argc, char * argv[]) { - ctx::fcontext_t fcm; - ctx::guarded_stack_allocator alloc; + std::cout << "size: 0x" << std::hex << sizeof( ctx::fcontext_t) << std::endl; - void * sp1 = alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()); - fc1 = ctx::make_fcontext( sp1, ctx::guarded_stack_allocator::default_stacksize(), f1); + ctx::fcontext_t fcm; + stack_allocator alloc; - void * sp2 = alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()); - fc2 = ctx::make_fcontext( sp2, ctx::guarded_stack_allocator::default_stacksize(), f2); + void * sp1 = alloc.allocate( stack_allocator::default_stacksize()); + fc1 = ctx::make_fcontext( sp1, stack_allocator::default_stacksize(), f1); - std::cout << "main: call start_fcontext( & fcm, fc1, 0)" << std::endl; - ctx::jump_fcontext( & fcm, fc1, 0); + void * sp2 = alloc.allocate( stack_allocator::default_stacksize()); + fc2 = ctx::make_fcontext( sp2, stack_allocator::default_stacksize(), f2); - std::cout << "main: done" << std::endl; - BOOST_ASSERT( false && ! "main: never returns"); + std::cout << "main: call start_fcontext( & fcm, fc1, 0)" << std::endl; + ctx::jump_fcontext( & fcm, fc1, 0); - return EXIT_SUCCESS; + std::cout << "main: done" << std::endl; + BOOST_ASSERT( false && ! "main: never returns"); + + return EXIT_SUCCESS; } diff --git a/example/jump.cpp b/example/jump.cpp index 57cb8c2..d43e1a6 100644 --- a/example/jump.cpp +++ b/example/jump.cpp @@ -12,8 +12,16 @@ #include #include +#include "simple_stack_allocator.hpp" + namespace ctx = boost::context; +typedef ctx::simple_stack_allocator< + 8 * 1024 * 1024, // 8MB + 64 * 1024, // 64kB + 8 * 1024 // 8kB +> stack_allocator; + ctx::fcontext_t fcm; ctx::fcontext_t * fc1 = 0; ctx::fcontext_t * fc2 = 0; @@ -37,21 +45,21 @@ void f2( intptr_t) int main( int argc, char * argv[]) { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; - void * base1 = alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()); + void * base1 = alloc.allocate( stack_allocator::default_stacksize()); BOOST_ASSERT( base1); - fc1 = ctx::make_fcontext( base1, ctx::guarded_stack_allocator::default_stacksize(), f1); + fc1 = ctx::make_fcontext( base1, stack_allocator::default_stacksize(), f1); BOOST_ASSERT( fc1); BOOST_ASSERT( base1 == fc1->fc_stack.sp); - BOOST_ASSERT( ctx::guarded_stack_allocator::default_stacksize() == fc1->fc_stack.size); + BOOST_ASSERT( stack_allocator::default_stacksize() == fc1->fc_stack.size); - void * base2 = alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()); + void * base2 = alloc.allocate( stack_allocator::default_stacksize()); BOOST_ASSERT( base2); - fc2 = ctx::make_fcontext( base2, ctx::guarded_stack_allocator::default_stacksize(), f2); + fc2 = ctx::make_fcontext( base2, stack_allocator::default_stacksize(), f2); BOOST_ASSERT( fc2); BOOST_ASSERT( base2 == fc2->fc_stack.sp); - BOOST_ASSERT( ctx::guarded_stack_allocator::default_stacksize() == fc2->fc_stack.size); + BOOST_ASSERT( stack_allocator::default_stacksize() == fc2->fc_stack.size); std::cout << "main: call start_fcontext( & fcm, fc1, 0)" << std::endl; ctx::jump_fcontext( & fcm, fc1, 0); diff --git a/include/boost/context/simple_stack_allocator.hpp b/example/simple_stack_allocator.hpp similarity index 100% rename from include/boost/context/simple_stack_allocator.hpp rename to example/simple_stack_allocator.hpp diff --git a/example/transfer.cpp b/example/transfer.cpp index 2e2deb4..5aac4c9 100644 --- a/example/transfer.cpp +++ b/example/transfer.cpp @@ -13,8 +13,16 @@ #include #include +#include "simple_stack_allocator.hpp" + namespace ctx = boost::context; +typedef ctx::simple_stack_allocator< + 8 * 1024 * 1024, // 8MB + 64 * 1024, // 64kB + 8 * 1024 // 8kB +> stack_allocator; + ctx::fcontext_t fcm; ctx::fcontext_t * fc1; @@ -31,11 +39,10 @@ void f1( intptr_t param) int main( int argc, char * argv[]) { - typedef ctx::simple_stack_allocator< 256 * 1024, 64 * 1024, 8 * 1024 > alloc_t; - alloc_t alloc; + stack_allocator alloc; - void * sp = alloc.allocate(alloc_t::default_stacksize()); - fc1 = ctx::make_fcontext( sp, alloc_t::default_stacksize(), f1); + void * sp = alloc.allocate( stack_allocator::default_stacksize() ); + fc1 = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f1); pair_t p( std::make_pair( 2, 7) ); int res = ( int) ctx::jump_fcontext( & fcm, fc1, ( intptr_t) & p); diff --git a/include/boost/context/all.hpp b/include/boost/context/all.hpp index cbb63af..6bf7e8f 100644 --- a/include/boost/context/all.hpp +++ b/include/boost/context/all.hpp @@ -8,8 +8,5 @@ #define BOOST_CONTEXT_ALL_H #include -#include -#include -#include #endif // BOOST_CONTEXT_ALL_H diff --git a/include/boost/context/detail/fcontext_x86_64_win.hpp b/include/boost/context/detail/fcontext_x86_64_win.hpp index 56d671a..833e3d0 100644 --- a/include/boost/context/detail/fcontext_x86_64_win.hpp +++ b/include/boost/context/detail/fcontext_x86_64_win.hpp @@ -45,29 +45,12 @@ struct stack_t {} }; -struct fp_t -{ - boost::uint32_t fc_freg[2]; - void * fc_xmm; - char fc_buffer[175]; - - fp_t() : - fc_freg(), - fc_xmm( 0), - fc_buffer() - { - fc_xmm = fc_buffer; - if ( 0 != ( ( ( uintptr_t) fc_xmm) & 15) ) - fc_xmm = ( char *) ( ( ( ( uintptr_t) fc_xmm) + 15) & ~0x0F); - } -}; - struct fcontext_t { boost::uint64_t fc_greg[10]; stack_t fc_stack; void * fc_local_storage; - fp_t fc_fp; + boost::uint64_t fc_fp[24]; fcontext_t() : fc_greg(), diff --git a/include/boost/context/fcontext.hpp b/include/boost/context/fcontext.hpp index 9e8cda6..e47bd07 100644 --- a/include/boost/context/fcontext.hpp +++ b/include/boost/context/fcontext.hpp @@ -61,11 +61,6 @@ namespace boost { namespace context { -namespace detail { - -extern "C" BOOST_CONTEXT_DECL void * BOOST_CONTEXT_CALLDECL align_stack( void * vp); - -} extern "C" BOOST_CONTEXT_DECL intptr_t BOOST_CONTEXT_CALLDECL jump_fcontext( fcontext_t * ofc, fcontext_t const* nfc, intptr_t vp, bool preserve_fpu = true); diff --git a/include/boost/context/guarded_stack_allocator.hpp b/include/boost/context/guarded_stack_allocator.hpp deleted file mode 100644 index 92cf323..0000000 --- a/include/boost/context/guarded_stack_allocator.hpp +++ /dev/null @@ -1,55 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_CONTEXT_GUARDED_STACK_ALLOCATOR_H -#define BOOST_CONTEXT_GUARDED_STACK_ALLOCATOR_H - -#include - -#if ! defined (BOOST_WINDOWS) -extern "C" { -#include -} -#endif - -//#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L - -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace context { - -class BOOST_CONTEXT_DECL guarded_stack_allocator -{ -public: - static bool is_stack_unbound(); - - static std::size_t default_stacksize(); - - static std::size_t minimum_stacksize(); - - static std::size_t maximum_stacksize(); - - void * allocate( std::size_t) const; - - void deallocate( void *, std::size_t) const; -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -//#endif - -#endif // BOOST_CONTEXT_GUARDED_STACK_ALLOCATOR_H diff --git a/include/boost/context/utils.hpp b/include/boost/context/utils.hpp deleted file mode 100644 index 4b6a2bc..0000000 --- a/include/boost/context/utils.hpp +++ /dev/null @@ -1,41 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#ifndef BOOST_CONTEXT_UTILS_H -#define BOOST_CONTEXT_UTILS_H - -#include - -#if ! defined (BOOST_WINDOWS) -extern "C" { -#include -} -#endif - -//#if defined (BOOST_WINDOWS) || _POSIX_C_SOURCE >= 200112L - -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace context { - -BOOST_CONTEXT_DECL std::size_t pagesize(); - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -//#endif - -#endif // BOOST_CONTEXT_UTILS_H diff --git a/performance/performance.cpp b/performance/performance.cpp index 1d4e6e4..998518c 100644 --- a/performance/performance.cpp +++ b/performance/performance.cpp @@ -19,6 +19,8 @@ #include #include +#include "../example/simple_stack_allocator.hpp" + #ifdef BOOST_USE_UCONTEXT #include #endif @@ -32,6 +34,12 @@ namespace ctx = boost::context; +typedef ctx::simple_stack_allocator< + 8 * 1024 * 1024, // 8MB + 64 * 1024, // 64kB + 8 * 1024 // 8kB +> stack_allocator; + bool pres_fpu = false; #define CALL_FCONTEXT(z,n,unused) ctx::jump_fcontext( & fcm, fc, 7, pres_fpu); @@ -65,10 +73,10 @@ static void f3() #ifdef BOOST_CONTEXT_CYCLE cycle_t test_fcontext_cycle( cycle_t ov) { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; fc = ctx::make_fcontext( - alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()), - ctx::guarded_stack_allocator::default_stacksize(), + alloc.allocate(stack_allocator::default_stacksize()), + stack_allocator::default_stacksize(), f1); ctx::jump_fcontext( & fcm, fc, 7, pres_fpu); @@ -91,11 +99,11 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~) # ifdef BOOST_USE_UCONTEXT cycle_t test_ucontext_cycle( cycle_t ov) { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; ::getcontext( & uc); - uc.uc_stack.ss_sp = alloc.allocate(ctx::guarded_stack_allocator_stacksize()); - uc.uc_stack.ss_size = ctx::guarded_stack_allocator_stacksize(); + uc.uc_stack.ss_sp = alloc.allocate(stack_allocator::default_stacksize()); + uc.uc_stack.ss_size = stack_allocator::default_stacksize(); ::makecontext( & uc, f2, 7); // cache warum-up @@ -137,10 +145,10 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FUNCTION, ~) #if _POSIX_C_SOURCE >= 199309L zeit_t test_fcontext_zeit( zeit_t ov) { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; fc = ctx::make_fcontext( - alloc.allocate(ctx::guarded_stack_allocator::default_stacksize()), - ctx::guarded_stack_allocator::default_stacksize(), + alloc.allocate(stack_allocator::default_stacksize()), + stack_allocator::default_stacksize(), f1); ctx::jump_fcontext( & fcm, fc, 7, pres_fpu); @@ -163,11 +171,11 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_FCONTEXT, ~) # ifdef BOOST_USE_UCONTEXT zeit_t test_ucontext_zeit( zeit_t ov) { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; ::getcontext( & uc); - uc.uc_stack.ss_sp = alloc.allocate(ctx::guarded_stack_allocator_stacksize()); - uc.uc_stack.ss_size = ctx::guarded_stack_allocator_stacksize(); + uc.uc_stack.ss_sp = alloc.allocate(stack_allocator::default_stacksize()); + uc.uc_stack.ss_size = stack_allocator::default_stacksize(); ::makecontext( & uc, f2, 7); // cache warum-up diff --git a/src/asm/jump_i386_ms_pe_masm.asm b/src/asm/jump_i386_ms_pe_masm.asm index f1e0bb1..ed38109 100644 --- a/src/asm/jump_i386_ms_pe_masm.asm +++ b/src/asm/jump_i386_ms_pe_masm.asm @@ -44,7 +44,6 @@ .XMM .model flat, c _exit PROTO, value:SDWORD -align_stack PROTO, vp:DWORD seh_fcontext PROTO, except:DWORD, frame:DWORD, context:DWORD, dispatch:DWORD .code diff --git a/src/asm/jump_ppc32_sysv_elf_gas.S b/src/asm/jump_ppc32_sysv_elf_gas.S index d8048fa..fc866f0 100644 --- a/src/asm/jump_ppc32_sysv_elf_gas.S +++ b/src/asm/jump_ppc32_sysv_elf_gas.S @@ -29,37 +29,37 @@ * | CR | LR | PC | | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 23 | 24 | | * + * | 23 | 24 | 25 | | * * ------------------------------------------------------------- * - * | 92 | 96 | | * + * | 92 | 96 | 100 | | * * ------------------------------------------------------------- * - * | sp | size| | * + * | sp | size|| | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | * + * | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | * * ------------------------------------------------------------- * - * | 100 | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | * + * | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | 140 | * * ------------------------------------------------------------- * * | F14 | F15 | F16 | F17 | F18 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | * + * | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | * * ------------------------------------------------------------- * - * | 140 | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | * + * | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | 180 | * * ------------------------------------------------------------- * * | F19 | F20 | F21 | F22 | F23 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | * + * | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * * ------------------------------------------------------------- * - * | 180 | 184 | 188 | 192 | 196 | 200 | 204 | 208 | 212 | 216 | * + * | 184 | 188 | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * * ------------------------------------------------------------- * * | F24 | F25 | F26 | F27 | F28 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | | * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | | * * ------------------------------------------------------------- * - * | 220 | 224 | 228 | 232 | 236 | 240 | 244 | 248 | | * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | | * * ------------------------------------------------------------- * * | F29 | F30 | F31 | fpscr | | * * ------------------------------------------------------------- * @@ -101,46 +101,46 @@ jump_fcontext: cmpwi cr7, %r6, 0 # test if fpu env should be preserved beq cr7, 1f - stfd %f14, 100(%r3) # save F14 - stfd %f15, 108(%r3) # save F15 - stfd %f16, 116(%r3) # save F16 - stfd %f17, 124(%r3) # save F17 - stfd %f18, 132(%r3) # save F18 - stfd %f19, 140(%r3) # save F19 - stfd %f20, 148(%r3) # save F20 - stfd %f21, 156(%r3) # save F21 - stfd %f22, 164(%r3) # save F22 - stfd %f23, 172(%r3) # save F23 - stfd %f24, 180(%r3) # save F24 - stfd %f25, 188(%r3) # save F25 - stfd %f26, 196(%r3) # save F26 - stfd %f27, 204(%r3) # save F27 - stfd %f28, 212(%r3) # save F28 - stfd %f29, 220(%r3) # save F29 - stfd %f30, 228(%r3) # save F30 - stfd %f31, 236(%r3) # save F31 + stfd %f14, 104(%r3) # save F14 + stfd %f15, 112(%r3) # save F15 + stfd %f16, 120(%r3) # save F16 + stfd %f17, 128(%r3) # save F17 + stfd %f18, 136(%r3) # save F18 + stfd %f19, 144(%r3) # save F19 + stfd %f20, 152(%r3) # save F20 + stfd %f21, 160(%r3) # save F21 + stfd %f22, 168(%r3) # save F22 + stfd %f23, 176(%r3) # save F23 + stfd %f24, 184(%r3) # save F24 + stfd %f25, 192(%r3) # save F25 + stfd %f26, 200(%r3) # save F26 + stfd %f27, 208(%r3) # save F27 + stfd %f28, 216(%r3) # save F28 + stfd %f29, 224(%r3) # save F29 + stfd %f30, 232(%r3) # save F30 + stfd %f31, 240(%r3) # save F31 mffs %f0 # load FPSCR - stfd %f0, 244(%r3) # save FPSCR + stfd %f0, 248(%r3) # save FPSCR - lfd %f14, 100(%r4) # restore F14 - lfd %f15, 108(%r4) # restore F15 - lfd %f16, 116(%r4) # restore F16 - lfd %f17, 124(%r4) # restore F17 - lfd %f18, 132(%r4) # restore F18 - lfd %f19, 140(%r4) # restore F19 - lfd %f20, 148(%r4) # restore F20 - lfd %f21, 156(%r4) # restore F21 - lfd %f22, 164(%r4) # restore F22 - lfd %f23, 172(%r4) # restore F23 - lfd %f24, 180(%r4) # restore F24 - lfd %f25, 188(%r4) # restore F25 - lfd %f26, 196(%r4) # restore F26 - lfd %f27, 204(%r4) # restore F27 - lfd %f28, 212(%r4) # restore F28 - lfd %f29, 220(%r4) # restore F29 - lfd %f30, 228(%r4) # restore F30 - lfd %f31, 236(%r4) # restore F31 - lfd %f0, 244(%r4) # load FPSCR + lfd %f14, 104(%r4) # restore F14 + lfd %f15, 112(%r4) # restore F15 + lfd %f16, 120(%r4) # restore F16 + lfd %f17, 128(%r4) # restore F17 + lfd %f18, 136(%r4) # restore F18 + lfd %f19, 144(%r4) # restore F19 + lfd %f20, 152(%r4) # restore F20 + lfd %f21, 160(%r4) # restore F21 + lfd %f22, 168(%r4) # restore F22 + lfd %f23, 176(%r4) # restore F23 + lfd %f24, 184(%r4) # restore F24 + lfd %f25, 192(%r4) # restore F25 + lfd %f26, 200(%r4) # restore F26 + lfd %f27, 208(%r4) # restore F27 + lfd %f28, 216(%r4) # restore F28 + lfd %f29, 224(%r4) # restore F29 + lfd %f30, 232(%r4) # restore F30 + lfd %f31, 240(%r4) # restore F31 + lfd %f0, 248(%r4) # load FPSCR mtfsf 0xff, %f0 # restore FPSCR 1: @@ -170,7 +170,7 @@ jump_fcontext: lwz %r0, 84(%r4) # load LR mtlr %r0 # restore LR - mr. %r3, %r5 # use third arg as return value after jump + mr %r3, %r5 # use third arg as return value after jump # and as first arg in context function lwz %r0, 88(%r4) # load PC diff --git a/src/asm/jump_ppc64_sysv_elf_gas.S b/src/asm/jump_ppc64_sysv_elf_gas.S index c002a46..2bc0861 100644 --- a/src/asm/jump_ppc64_sysv_elf_gas.S +++ b/src/asm/jump_ppc64_sysv_elf_gas.S @@ -191,7 +191,7 @@ jump_fcontext: ld %r0, 168(%r4) # load LR mtlr %r0 # restore LR - mr. %r3, %r5 # use third arg as return value after jump + mr %r3, %r5 # use third arg as return value after jump # and as first arg in context function ld %r0, 176(%r4) # load PC diff --git a/src/asm/jump_x86_64_ms_pe_masm.asm b/src/asm/jump_x86_64_ms_pe_masm.asm index 3d164b2..a17a6e8 100644 --- a/src/asm/jump_x86_64_ms_pe_masm.asm +++ b/src/asm/jump_x86_64_ms_pe_masm.asm @@ -40,50 +40,49 @@ ; | fbr_strg | | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 28 | 29 | 30 | 31 | | +; | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ; ---------------------------------------------------------------------------------- -; | 0x70 | 0x74 | 0x78 | 0x7c | | +; | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | 0x88 | 0x8c | ; ---------------------------------------------------------------------------------- -; | fc_mxcsr|fc_x87_cw| | | +; | fc_mxcsr|fc_x87_cw| fc_xmm | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | +; | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ; ---------------------------------------------------------------------------------- -; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | +; | 0x90 | 0x94 | 0x98 | 0x9c | 0x100 | 0x104 | 0x108 | 0x10c | ; ---------------------------------------------------------------------------------- -; | XMM6 | XMM7 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | +; | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ; ---------------------------------------------------------------------------------- -; | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | +; | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | 0x128 | 0x12c | ; ---------------------------------------------------------------------------------- -; | XMM8 | XMM9 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | +; | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ; ---------------------------------------------------------------------------------- -; | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | +; | 0x130 | 0x134 | 0x138 | 0x13c| 0x140 | 0x144 | 0x148 | 0x14c | ; ---------------------------------------------------------------------------------- -; | XMM10 | XMM11 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | +; | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ; ---------------------------------------------------------------------------------- -; | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | +; | 0x150 | 0x154 | 0x158 | 0x15c | 0x160 | 0x164 | 0x168 | 0x16c | ; ---------------------------------------------------------------------------------- -; | XMM12 | XMM13 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | +; | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | ; ---------------------------------------------------------------------------------- -; | 0x160 | 0x164 | 0x168 | 0x16c | 0x170 | 0x174 | 0x178 | 0x17c | +; | 0x170 | 0x174 | 0x178 | 0x17c | 0x180 | 0x184 | 0x188 | 0x18c | ; ---------------------------------------------------------------------------------- -; | XMM14 | XMM15 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- EXTERN _exit:PROC ; standard C library function -EXTERN align_stack:PROC ; stack alignment EXTERN seh_fcontext:PROC ; exception handler .code @@ -113,32 +112,44 @@ jump_fcontext PROC EXPORT FRAME:seh_fcontext stmxcsr [rcx+070h] ; save MMX control and status word fnstcw [rcx+074h] ; save x87 control word ; save XMM storage - movaps [rcx+080h], xmm6 - movaps [rcx+090h], xmm7 - movaps [rcx+0100h], xmm8 - movaps [rcx+0110h], xmm9 - movaps [rcx+0120h], xmm10 - movaps [rcx+0130h], xmm11 - movaps [rcx+0140h], xmm12 - movaps [rcx+0150h], xmm13 - movaps [rcx+0160h], xmm14 - movaps [rcx+0170h], xmm15 + ; save start address of SSE register block in R10 + lea r10, [rcx+090h] + ; shift address in R10 to lower 16 byte boundary + ; == pointer to SEE register block + and r10, -0fh + + movaps [r10], xmm6 + movaps [r10+010h], xmm7 + movaps [r10+020h], xmm8 + movaps [r10+030h], xmm9 + movaps [r10+040h], xmm10 + movaps [r10+050h], xmm11 + movaps [r10+060h], xmm12 + movaps [r10+070h], xmm13 + movaps [r10+080h], xmm14 + movaps [r10+090h], xmm15 ldmxcsr [rdx+070h] ; restore MMX control and status word fldcw [rdx+074h] ; restore x87 control word ; restore XMM storage - movaps xmm6, [rdx+080h] - movaps xmm7, [rdx+090h] - movaps xmm8, [rdx+0100h] - movaps xmm9, [rdx+0110h] - movaps xmm10, [rdx+0120h] - movaps xmm11, [rdx+0130h] - movaps xmm12, [rdx+0140h] - movaps xmm13, [rdx+0150h] - movaps xmm14, [rdx+0160h] - movaps xmm15, [rdx+0170h] -nxt: + ; save start address of SSE register block in R10 + lea r10, [rdx+090h] + ; shift address in R10 to lower 16 byte boundary + ; == pointer to SEE register block + and r10, -0fh + movaps xmm6, [r10] + movaps xmm7, [r10+010h] + movaps xmm8, [r10+020h] + movaps xmm9, [r10+030h] + movaps xmm10, [r10+040h] + movaps xmm11, [r10+050h] + movaps xmm12, [r10+060h] + movaps xmm13, [r10+070h] + movaps xmm14, [r10+080h] + movaps xmm15, [r10+090h] + +nxt: lea rax, [rsp+08h] ; exclude the return address mov [rcx+040h], rax ; save as stack pointer mov rax, [rsp] ; load return address diff --git a/src/asm/make_arm_aapcs_elf_gas.S b/src/asm/make_arm_aapcs_elf_gas.S index 3fff7c4..ea3c22d 100644 --- a/src/asm/make_arm_aapcs_elf_gas.S +++ b/src/asm/make_arm_aapcs_elf_gas.S @@ -50,26 +50,27 @@ .align 2 .type make_fcontext,%function make_fcontext: - stmfd sp!, {a1-a3,lr} @ save arguments of make_fcontext and return address on stack, SP % 8 == 0 - sub a1, #116 @ reserve space for fcontext_t at top of context stack - bl align_stack@PLT @ call align_stack, A1 contains address at 16 byte boundary after return - @ == pointer to fcontext_t and address of context stack + mov a4, a1 @ save address of context stack (base) A4 + sub a1, #116 @ reserve space for fcontext_t at top of context stack - ldmfd sp!, {a2-a4,lr} @ restore arguments of make_fcontext and return address from stack - str a2, [a1,#44] @ save address of context stack (base) in fcontext_t - str a3, [a1,#48] @ save context stack size in fcontext_t - str a4, [a1,#40] @ save address of context function in fcontext_t + @ shift address in A1 to lower 16 byte boundary + @ == pointer to fcontext_t and address of context stack + bic a1, a1, #15 - str a1, [a1,#32] @ save address in A1 as stack pointer for context function + str a4, [a1,#44] @ save address of context stack (base) in fcontext_t + str a2, [a1,#48] @ save context stack size in fcontext_t + str a3, [a1,#40] @ save address of context function in fcontext_t - adr a2, finish @ compute abs address of label finish - str a2, [a1,#36] @ save address of finish as return address for context function - @ entered after context function returns + str a1, [a1,#32] @ save address in A4 as stack pointer for context function + + adr a2, finish @ compute abs address of label finish + str a2, [a1,#36] @ save address of finish as return address for context function + @ entered after context function returns bx lr finish: - @ SP points to same address as SP on entry of context function - mov a1, #0 @ exit code is zero - bl _exit@PLT @ exit application + @ SP points to same addras SP on entry of context function + mov a1, #0 @ exit code is zero + bl _exit@PLT @ exit application .size make_fcontext,.-make_fcontext diff --git a/src/asm/make_i386_ms_pe_masm.asm b/src/asm/make_i386_ms_pe_masm.asm index 926f702..3e8decb 100644 --- a/src/asm/make_i386_ms_pe_masm.asm +++ b/src/asm/make_i386_ms_pe_masm.asm @@ -43,30 +43,26 @@ .386 .XMM .model flat, c -_exit PROTO, value:SDWORD -align_stack PROTO, vp:DWORD +_exit PROTO, value:SDWORD seh_fcontext PROTO, except:DWORD, frame:DWORD, context:DWORD, dispatch:DWORD .code make_fcontext PROC EXPORT - push ebp ; save previous frame pointer; get the stack 16 byte aligned - mov ebp, esp ; set EBP to ESP - sub esp, 010h ; allocate stack space - - mov eax, [ebp+08h] ; load 1. arg of make_fcontext, pointer to context stack (base) + mov eax, [esp+04h] ; load 1. arg of make_fcontext, pointer to context stack (base) lea eax, [eax-034h] ; reserve space for fcontext_t at top of context stack - mov [esp], eax ; address in EAX becomes 1.arg of align_stack - call align_stack ; call align_stack, EAX contains address at 16 byte boundary after return - ; == pointer to fcontext_t and address of context stack - mov ecx, [ebp+08h] ; load 1. arg of make_fcontext, pointer to context stack (base) + ; shift address in EAX to lower 16 byte boundary + ; == pointer to fcontext_t and address of context stack + and eax, -0fh + + mov ecx, [esp+04h] ; load 1. arg of make_fcontext, pointer to context stack (base) mov [eax+018h], ecx ; save address of context stack (base) in fcontext_t - mov edx, [ebp+0ch] ; load 2. arg of make_fcontext, context stack size + mov edx, [esp+08h] ; load 2. arg of make_fcontext, context stack size mov [eax+01ch], edx ; save context stack size in fcontext_t neg edx ; negate stack size for LEA instruction (== substraction) lea ecx, [ecx+edx] ; compute bottom address of context stack (limit) mov [eax+020h], ecx ; save address of context stack (limit) in fcontext_t - mov ecx, [ebp+010h] ; load 3. arg of make_fcontext, pointer to context function + mov ecx, [esp+0ch] ; load 3. arg of make_fcontext, pointer to context function mov [eax+014h], ecx ; save address of context function in fcontext_t stmxcsr [eax+02ch] ; save MMX control word @@ -86,9 +82,6 @@ make_fcontext PROC EXPORT mov [edx], ecx ; save address of finish as return address for context function ; entered after context function returns - add esp, 010h ; deallocate stack space - pop ebp - ret finish: diff --git a/src/asm/make_i386_sysv_elf_gas.S b/src/asm/make_i386_sysv_elf_gas.S index 98863ae..03d5597 100644 --- a/src/asm/make_i386_sysv_elf_gas.S +++ b/src/asm/make_i386_sysv_elf_gas.S @@ -36,27 +36,18 @@ .align 2 .type make_fcontext,@function make_fcontext: - pushl %ebp /* save previous frame pointer; get the stack 16 byte aligned */ - movl %esp, %ebp /* set EBP to ESP */ - subl $0x10, %esp /* allocate stack space */ - - movl %ebx, 0x4(%esp) /* save EBX */ - movl 0x8(%ebp), %eax /* load 1. arg of make_fcontext, pointer to context stack (base) */ + movl 0x4(%esp), %eax /* load 1. arg of make_fcontext, pointer to context stack (base) */ leal -0x28(%eax), %eax /* reserve space for fcontext_t at top of context stack */ - movl %eax, (%esp) /* address in EAX becomes 1. arg of align_stack */ - call 1f -1: popl %ebx /* address of label 1 */ - addl $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx /* compute address of GOT and store it in EBX */ - call align_stack@PLT /* call align_stack, EAX contains address at 16 byte boundary after return */ - /* == pointer to fcontext_t and address of context stack */ - movl 0x4(%esp), %ebx /* restore EBX */ + /* shift address in EAX to lower 16 byte boundary */ + /* == pointer to fcontext_t and address of context stack */ + andl $-0xf, %eax - movl 0x8(%ebp), %edx /* load 1. arg of make_fcontext, pointer to context stack (base) */ + movl 0x4(%esp), %edx /* load 1. arg of make_fcontext, pointer to context stack (base) */ movl %edx, 0x18(%eax) /* save address of context stack (base) in fcontext_t */ - movl 0xc(%ebp), %edx /* load 2. arg of make_fcontext, context stack size */ + movl 0x8(%esp), %edx /* load 2. arg of make_fcontext, context stack size */ movl %edx, 0x1c(%eax) /* save stack size in fcontext_t */ - movl 0x10(%ebp), %edx /* load 3. arg of make_fcontext, pointer to context function */ + movl 0xc(%esp), %edx /* load 3. arg of make_fcontext, pointer to context function */ movl %edx, 0x14(%eax) /* save address of context function in fcontext_t */ stmxcsr 0x20(%eax) /* save MMX control and status word */ @@ -71,9 +62,6 @@ make_fcontext: movl %ecx, (%edx) /* save address of finish as return address for context functions */ /* entered after context function returns */ - addl $0x10, %esp /* deallocate stack space */ - pop %ebp - ret finish: diff --git a/src/asm/make_i386_sysv_macho_gas.S b/src/asm/make_i386_sysv_macho_gas.S index 6ae0a7b..86c8356 100644 --- a/src/asm/make_i386_sysv_macho_gas.S +++ b/src/asm/make_i386_sysv_macho_gas.S @@ -35,21 +35,18 @@ .globl _make_fcontext .align 2 _make_fcontext: - pushl %ebp /* save previous frame pointer */ - movl %esp, %ebp /* set EBP to ESP */ - subl $0x8, %esp /* allocate stack space */ - - movl 0x8(%ebp), %eax /* load 1. arg of make_fcontext, pointer to context stack (base) */ + movl 0x4(%esp), %eax /* load 1. arg of make_fcontext, pointer to context stack (base) */ leal -0x28(%eax), %eax /* reserve space for fcontext_t at top of context stack */ - movl %eax, (%esp) /* address in EAX becomes 1. arg of align_stack */ - call _align_stack /* call align_stack, EAX contains address at 16 byte boundary after return */ - /* ==pointer to fcontext_t and address of context stack */ - movl 0x8(%ebp), %edx /* load 1. arg of make_fcontext, pointer to context stack (base) */ + /* shift address in EAX to lower 16 byte boundary */ + /* == pointer to fcontext_t and address of context stack */ + andl $-0xf, %eax + + movl 0x4(%esp), %edx /* load 1. arg of make_fcontext, pointer to context stack (base) */ movl %edx, 0x18(%eax) /* save address of stack pointer (base) in fcontext_t */ - movl 0xc(%ebp), %edx /* load 2. arg of make_fcontext, context stack size */ + movl 0x8(%esp), %edx /* load 2. arg of make_fcontext, context stack size */ movl %edx, 0x1c(%eax) /* save stack size in fcontext_t */ - movl 0x10(%ebp), %edx /* load 3. arg of make_fcontext, pointer to context function */ + movl 0xc(%esp), %edx /* load 3. arg of make_fcontext, pointer to context function */ movl %edx, 0x14(%eax) /* save address of context fcuntion in fcontext_t */ stmxcsr 0x20(%eax) /* save MMX control and status word */ @@ -60,13 +57,10 @@ _make_fcontext: call 1f 1: popl %ecx /* address of label 1 */ - addl $finish-1b, %ecx /* compute abs address of label finish */ + addl $finish-2b, %ecx /* compute abs address of label finish */ movl %ecx, (%edx) /* save address of finish as return address for context function */ /* entered after context function returns */ - addl $0x8, %esp /* deallocate stack space */ - popl %ebp - ret finish: diff --git a/src/asm/make_mips32_o32_elf_gas.S b/src/asm/make_mips32_o32_elf_gas.S index 3b8b12e..1f37394 100644 --- a/src/asm/make_mips32_o32_elf_gas.S +++ b/src/asm/make_mips32_o32_elf_gas.S @@ -49,22 +49,16 @@ make_fcontext: .cpload $t9 .set reorder #endif - addiu $sp, $sp, -48 # allocate stack space (contains shadow space for subroutines) - sw $ra, 44($sp) # save return address - sw $fp, 40($sp) # save frame pointer + move $v0, $a0 + addiu $v0, $v0, -104 # reserve space for fcontext_t at top of context stack - sw $a2, 48($sp) # save 3. arg of make_fcontnext, pointer to context function - sw $a1, 52($sp) # save 2. arg of make_fcontext, context stack size - sw $a0, 56($sp) # save 1. arg of make_fcontext, pointer to context stack (base) - addiu $a0, $a0, -104 # reserve space for fcontext_t at top of context stack - lw $t9, %call16(align_stack)($gp) # compute adddress of align_stack via global pointer - jalr $t9 # call align_stack, V0 contains address at 16 byte boundary after return - # == pointer to fcontext_t and address of context stack - lw $a0, 56($sp) # restore pointer to context stack (base) - lw $a1, 52($sp) # restore context stack size - lw $a2, 48($sp) # restore pointer to context function + # shift address in V0 to lower 16 byte boundary + # == pointer to fcontext_t and address of context stack + move $v1, $v0 + li $v0, -16 # 0xfffffffffffffff0 + and $v0, $v1, $v0 - sw $a0, 48($v0) # save address of context stack (base) in fcontext_t + sw $a0, 48($v0) # save address of context stack (base) in fcontext_t sw $a1, 52($v0) # save context stack size in fcontext_t sw $a2, 44($v0) # save address of context function in fcontext_t sw $gp, ($v0) # save global pointer in fcontext_t, S0 will contain address of global pointer @@ -76,10 +70,6 @@ make_fcontext: sw $t9, 40($v0) # save address of finish as return address for context function # entered after context function returns - lw $fp, 40($sp) # restore frame pointer - lw $ra, 44($sp) # restore return address - addiu $sp, $sp, 48 # deallocate stack space - jr $ra finish: diff --git a/src/asm/make_ppc32_sysv_elf_gas.S b/src/asm/make_ppc32_sysv_elf_gas.S index 7d2425c..40d66d3 100644 --- a/src/asm/make_ppc32_sysv_elf_gas.S +++ b/src/asm/make_ppc32_sysv_elf_gas.S @@ -29,37 +29,37 @@ * | CR | LR | PC | | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 23 | 24 | | * + * | 23 | 24 | 25 | | * * ------------------------------------------------------------- * - * | 92 | 96 | | * + * | 92 | 96 | 100 | | * * ------------------------------------------------------------- * - * | sp | size| | * + * | sp | size|| | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | * + * | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | * * ------------------------------------------------------------- * - * | 100 | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | * + * | 104 | 108 | 112 | 116 | 120 | 124 | 128 | 132 | 136 | 140 | * * ------------------------------------------------------------- * * | F14 | F15 | F16 | F17 | F18 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | * + * | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | * * ------------------------------------------------------------- * - * | 140 | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | * + * | 144 | 148 | 152 | 156 | 160 | 164 | 168 | 172 | 176 | 180 | * * ------------------------------------------------------------- * * | F19 | F20 | F21 | F22 | F23 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | * + * | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | * * ------------------------------------------------------------- * - * | 180 | 184 | 188 | 192 | 196 | 200 | 204 | 208 | 212 | 216 | * + * | 184 | 188 | 192 | 196 | 200 | 204 | 208 | 212 | 216 | 220 | * * ------------------------------------------------------------- * * | F24 | F25 | F26 | F27 | F28 | * * ------------------------------------------------------------- * * ------------------------------------------------------------- * - * | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | | * + * | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | | * * ------------------------------------------------------------- * - * | 220 | 224 | 228 | 232 | 236 | 240 | 244 | 248 | | * + * | 224 | 228 | 232 | 236 | 240 | 244 | 248 | 252 | | * * ------------------------------------------------------------- * * | F29 | F30 | F31 | fpscr | | * * ------------------------------------------------------------- * @@ -71,27 +71,21 @@ .align 2 .type make_fcontext,@function make_fcontext: - mflr %r0 # save return address into R0 - stw %r0, 4(%r1) # save return address on stack, set up stack frame - stwu %r1, -48(%r1) # allocate stack space, SP % 16 == 0 + mflr %r6 # save return address into R6 - stw %r5, 32(%r1) # save 3. arg of make_fcontext, pointer to context function - stw %r4, 28(%r1) # save 2. arg of make_fcontext, context stack size - stw %r3, 24(%r1) # save 1. arg of make_fcontext, pointer to context stack (base) + mr %r0, %r3 + subi %r3, %r3, 256 # reserve space for fcontext_t at top of context stack - subi %r3, %r3, 252 # reserve space for fcontext_t at top of context stack - bl align_stack@plt # call align_stack, R3 contains address at 16 byte boundary after return - # == pointer to fcontext_t and address of context stack - lwz %r4, 24(%r1) # restore pointer to context stack (base) - lwz %r5, 28(%r1) # restore context stack size - lwz %r6, 32(%r1) # restore pointer to context function + # call align_stack, R3 contains address at 16 byte boundary after return + # == pointer to fcontext_t and address of context stack + rlwinm %r3, %r3, 0, 0, 27 - stw %r4, 92(%r3) # save address of context stack (base) in fcontext_t - stw %r5, 96(%r3) # save context stack size in fcontext_t - stw %r6, 88(%r3) # save address of context function in fcontext_t + stw %r0, 92(%r3) # save address of context stack (base) in fcontext_t + stw %r4, 96(%r3) # save context stack size in fcontext_t + stw %r5, 88(%r3) # save address of context function in fcontext_t - subi %r0, %r3, 64 # reserve 64 bytes (linkage + parameter area), R0 % 16 == 0 - stw %r0, 76(%r3) # save address in R0 as stack pointer for context function + subi %r0, %r3, 64 # reserve 64 bytes (linkage + parameter area), R4 % 16 == 0 + stw %r0, 76(%r3) # save address in R3 as stack pointer for context function mflr %r0 # load LR bl 1f # jump to label 1 @@ -102,9 +96,7 @@ make_fcontext: stw %r4, 84(%r3) # save address of finish as return address for context function # entered after context function returns - addi %r1, %r1, 48 # deallocate stack space - lwz %r0, 4(%r1) # load return address from stack, destroy stack frame - mtlr %r0 # restore return address + mtlr %r6 # restore return address from R6 blr diff --git a/src/asm/make_ppc64_sysv_elf_gas.S b/src/asm/make_ppc64_sysv_elf_gas.S index 60fb455..df9bd37 100644 --- a/src/asm/make_ppc64_sysv_elf_gas.S +++ b/src/asm/make_ppc64_sysv_elf_gas.S @@ -92,24 +92,18 @@ make_fcontext: .type .make_fcontext,@function .globl .make_fcontext .make_fcontext: - mflr %r0 # save return address into R0 - std %r0, 8(%r1) # save return address on stack, set up stack frame - stdu %r1, -96(%r1) # allocate stack space, SP % 16 == 0 - - std %r5, 64(%r1) # save 3. arg of make_fcontext, pointer to context function - std %r4, 56(%r1) # save 2. arg of make_fcontext, context stack size - std %r3, 48(%r1) # save 1. arg of make_fcontext, pointer to context stack (base) + mflr %r6 # save return address into R6 + mr %r0, %r3 subi %r3, %r3, 352 # reserve space for fcontext_t at top of context stack - bl align_stack@plt # call align_stack, R3 contains address at 16 byte boundary after return - # == pointer to fcontext_t and address of context stack - ld %r4, 48(%r1) # restore pointer to context stack (base) - ld %r5, 56(%r1) # restore context stack size - ld %r6, 64(%r1) # restore pointer to context function - std %r4, 184(%r3) # save address of context stack (base) in fcontext_t - std %r5, 192(%r3) # save context stack size in fcontext_t - std %r6, 176(%r3) # save address of context function in fcontext_t + # call align_stack, R3 contains address at 16 byte boundary after return + # == pointer to fcontext_t and address of context stack + rlwinm %r3, %r3, 0, 0, 27 + + std %r0, 184(%r3) # save address of context stack (base) in fcontext_t + std %r4, 192(%r3) # save context stack size in fcontext_t + std %r5, 176(%r3) # save address of context function in fcontext_t subf %r0, %r3, 64 # 64 bytes on stack for parameter area (== 8 registers) std %r0, 152(%r3) # save the stack base @@ -123,9 +117,7 @@ make_fcontext: std %r4, 168(%r3) # save address of finish as return address for context function # entered after context function returns - addi %r1, %r1, 64 # deallocate stack space - lwz %r0, 8(%r1) # load return address from stack, destroy stack frame - mtlr %r0 # restore return address + mtlr %r6 # restore return address from R6 blr diff --git a/src/asm/make_x86_64_ms_pe_masm.asm b/src/asm/make_x86_64_ms_pe_masm.asm index 2c73df4..30e0a77 100644 --- a/src/asm/make_x86_64_ms_pe_masm.asm +++ b/src/asm/make_x86_64_ms_pe_masm.asm @@ -40,70 +40,59 @@ ; | fbr_strg | | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 28 | 29 | 30 | 31 | | +; | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ; ---------------------------------------------------------------------------------- -; | 0x70 | 0x74 | 0x78 | 0x7c | | +; | 0x70 | 0x74 | 0x78 | 0x7c | 0x80 | 0x84 | 0x88 | 0x8c | ; ---------------------------------------------------------------------------------- -; | fc_mxcsr|fc_x87_cw| | | +; | fc_mxcsr|fc_x87_cw| fc_xmm | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | +; | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | ; ---------------------------------------------------------------------------------- -; | 0x80 | 0x84 | 0x88 | 0x8c | 0x90 | 0x94 | 0x98 | 0x9c | +; | 0x90 | 0x94 | 0x98 | 0x9c | 0x100 | 0x104 | 0x108 | 0x10c | ; ---------------------------------------------------------------------------------- -; | XMM6 | XMM7 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | +; | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | ; ---------------------------------------------------------------------------------- -; | 0x100 | 0x104 | 0x108 | 0x10c | 0x110 | 0x114 | 0x118 | 0x11c | +; | 0x110 | 0x114 | 0x118 | 0x11c | 0x120 | 0x124 | 0x128 | 0x12c | ; ---------------------------------------------------------------------------------- -; | XMM8 | XMM9 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | +; | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ; ---------------------------------------------------------------------------------- -; | 0x120 | 0x124 | 0x128 | 0x12c | 0x130 | 0x134 | 0x138 | 0x13c | +; | 0x130 | 0x134 | 0x138 | 0x13c| 0x140 | 0x144 | 0x148 | 0x14c | ; ---------------------------------------------------------------------------------- -; | XMM10 | XMM11 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | +; | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ; ---------------------------------------------------------------------------------- -; | 0x140 | 0x144 | 0x148 | 0x14c | 0x150 | 0x154 | 0x158 | 0x15c | +; | 0x150 | 0x154 | 0x158 | 0x15c | 0x160 | 0x164 | 0x168 | 0x16c | ; ---------------------------------------------------------------------------------- -; | XMM12 | XMM13 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- ; ---------------------------------------------------------------------------------- -; | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | +; | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | ; ---------------------------------------------------------------------------------- -; | 0x160 | 0x164 | 0x168 | 0x16c | 0x170 | 0x174 | 0x178 | 0x17c | +; | 0x170 | 0x174 | 0x178 | 0x17c | 0x180 | 0x184 | 0x188 | 0x18c | ; ---------------------------------------------------------------------------------- -; | XMM14 | XMM15 | +; | SEE registers (XMM6-XMM15) | ; ---------------------------------------------------------------------------------- EXTERN _exit:PROC ; standard C library function -EXTERN align_stack:PROC ; stack alignment -EXTERN seh_fcontext:PROC ; exception handler .code make_fcontext PROC EXPORT FRAME ; generate function table entry in .pdata and unwind information in .endprolog ; .xdata for a function's structured exception handling unwind behavior - push rbp ; save previous frame pointer; get the stack 16 byte aligned - mov rbp, rsp ; set RBP to RSP - sub rsp, 040h ; allocate stack space (contains shadow space for subroutines) + lea rax, [rcx-0130h] ; reserve space for fcontext_t at top of context stack - mov [rbp-08h], r8 ; save 3. arg of make_fcontext, pointer to context function - mov [rbp-010h], rdx ; save 2. arg of make_fcontext, context stack size - mov [rbp-018h], rcx ; save 1. arg of make_fcontext, pointer to context stack (base) - lea rcx, [rcx-0180h] ; reserve space for fcontext_t at top of context stack - call align_stack ; align context stack, RAX contains address at 16 byte boundary - ; == pointer to fcontext_t and address of context stack - - mov r8, [rbp-08h] ; restore pointer to context function - mov rdx, [rbp-010h] ; restore context stack size - mov rcx, [rbp-018h] ; restore pointer to context stack (base) + ; shift address in RAX to lower 16 byte boundary + ; == pointer to fcontext_t and address of context stack + and rax, -0fh mov [rax+048h], r8 ; save address of context function in fcontext_t mov [rax+058h], rdx ; save context stack size in fcontext_t @@ -123,9 +112,6 @@ make_fcontext PROC EXPORT FRAME ; generate function table entry in .pdata and u mov [rdx], rcx ; save address of finish as return address for context function ; entered after context function returns - add rsp, 040h ; deallocate shadow space - pop rbp ; restore previous frame pointer - ret finish: diff --git a/src/asm/make_x86_64_sysv_elf_gas.S b/src/asm/make_x86_64_sysv_elf_gas.S index a08434a..e66d905 100644 --- a/src/asm/make_x86_64_sysv_elf_gas.S +++ b/src/asm/make_x86_64_sysv_elf_gas.S @@ -43,23 +43,15 @@ .type make_fcontext,@function .align 16 make_fcontext: - pushq %rbp /* save previous frame pointer; get the stack 16 byte aligned */ - movq %rsp, %rbp /* set RBP to RSP */ - subq $0x20, %rsp /* allocate stack space */ + leaq -0x58(%rdi), %rax /* reserve space for fcontext_t at top of context stack */ - movq %rdx, 0x10(%rsp) /* save 3. arg of make_fcontext, pointer to context function */ - movq %rsi, 0x8(%rsp) /* save 2. arg of make_fcontext, context stack size */ - movq %rdi, (%rsp) /* save 1. arg of make_fcontext, pointer to context stack (base) */ - leaq -0x58(%rdi), %rdi /* reserve space for fcontext_t at top of context stack */ - call align_stack@PLT /* align context stack, RAX contains address at 16 byte boundary afte return */ - /* == pointer to fcontext_t and address of context stack */ - movq (%rsp), %rdi /* restore pointer to context stack (base) */ - movq 0x8(%rsp), %rsi /* restore context stack size */ - movq 0x10(%rsp), %rdx /* restore pointer to context function */ + /* shift address in RAX to lower 16 byte boundary */ + /* == pointer to fcontext_t and address of context stack */ + andq $-0xf, %rax - movq %rdi, 0x40(%rax) /* save address of context stack pointer (base) in fcontext_t */ - movq %rsi, 0x48(%rax) /* save context stack size in fcontext_t */ - movq %rdx, 0x38(%rax) /* save address of context function in fcontext_t */ + movq %rdi, 0x40(%rax) /* save address of context stack pointer (base) in fcontext_t */ + movq %rsi, 0x48(%rax) /* save context stack size in fcontext_t */ + movq %rdx, 0x38(%rax) /* save address of context function in fcontext_t */ stmxcsr 0x50(%rax) /* save MMX control and status word */ fnstcw 0x54(%rax) /* save x87 control word */ @@ -71,9 +63,6 @@ make_fcontext: movq %rcx, (%rdx) /* save address of finish as return address for context function */ /* entered after context function returns */ - addq $0x20, %rsp /* deallocate shadow space */ - popq %rbp /* restore previous frame pointer */ - ret /* return pointer to fcontext_t placed on context stack */ finish: diff --git a/src/asm/make_x86_64_sysv_macho_gas.S b/src/asm/make_x86_64_sysv_macho_gas.S index 9301b18..90d8669 100644 --- a/src/asm/make_x86_64_sysv_macho_gas.S +++ b/src/asm/make_x86_64_sysv_macho_gas.S @@ -41,20 +41,11 @@ .text .globl _make_fcontext .align 8 -_make_fcontext: - pushq %rbp /* save previous frame pointer; get the stack 16 byte aligned */ - movq %rsp, %rbp /* set RBP to RSP */ - subq $0x20, %rsp /* allocate stack space */ + leaq -0x58(%rdi), %r8 /* reserve space for fcontext_t at top of context stack */ - movq %rdx, 0x10(%rsp) /* save 3. arg of make_fcontext, pointer to context function */ - movq %rsi, 0x8(%rsp) /* save 2. arg of make_fcontext, context stack size */ - movq %rdi, (%rsp) /* save 1. arg of make_fcontext, pointer to context stack (base) */ - leaq -0x58(%rdi), %rdi /* reserve space for fcontext_t at top of context stack */ - call _align_stack /* align context stack, RAX contains address at 16 byte boundary */ - /* == pointer to fcontext_t and address of context stack */ - movq (%rsp), %rdi /* restore pointer to context stack (base) */ - movq 0x8(%rsp), %rsi /* restore context stack size */ - movq 0x10(%rsp), %rdx /* restore pointer to context function */ + /* shift address in RAX to lower 16 byte boundary */ + /* == pointer to fcontext_t and address of context stack */ + andq $-0xf, %rax movq %rdi, 0x40(%rax) /* save address of stack pointer (base) in fcontext_t */ movq %rsi, 0x48(%rax) /* save stack size in fcontext_t */ @@ -70,9 +61,6 @@ _make_fcontext: movq %rcx, (%rdx) /* save address of finish as return address for context function */ /* entered after context function returns */ - addq $0x20, %rsp /* deallocate shadow space */ - popq %rbp /* restore previous frame pointer */ - ret /* return pointer to fcontext_t placed on context stack */ finish: diff --git a/src/fcontext.cpp b/src/fcontext.cpp deleted file mode 100644 index 90129ed..0000000 --- a/src/fcontext.cpp +++ /dev/null @@ -1,36 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_CONTEXT_SOURCE - -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace context { -namespace detail { - -extern "C" BOOST_CONTEXT_DECL -void * BOOST_CONTEXT_CALLDECL align_stack( void * vp) -{ - void * base = vp; - if ( 0 != ( ( ( uintptr_t) base) & 15) ) - base = ( char * ) ( ( ( ( uintptr_t) base) - 15) & ~0x0F); - return base; -} - -} - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif diff --git a/src/guarded_stack_allocator_posix.cpp b/src/guarded_stack_allocator_posix.cpp deleted file mode 100644 index 8f68294..0000000 --- a/src/guarded_stack_allocator_posix.cpp +++ /dev/null @@ -1,152 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_CONTEXT_SOURCE - -#include - -extern "C" { -#include -#include -#include -#include -#include -#include -#include -#include -} - -//#if _POSIX_C_SOURCE >= 200112L - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#if !defined (SIGSTKSZ) -# define SIGSTKSZ (8 * 1024) -#endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace { - -static rlimit stacksize_limit_() -{ - rlimit limit; - // conforming to POSIX.1-2001 - const int result = ::getrlimit( RLIMIT_STACK, & limit); - BOOST_ASSERT( 0 == result); - return limit; -} - -static rlimit stacksize_limit() -{ - static rlimit limit = stacksize_limit_(); - return limit; -} - -static std::size_t page_count( std::size_t stacksize) -{ - return static_cast< std::size_t >( - std::ceil( - static_cast< float >( stacksize) / boost::context::pagesize() ) ); -} - -} - -namespace boost { -namespace context { - -bool -guarded_stack_allocator::is_stack_unbound() -{ return RLIM_INFINITY == stacksize_limit().rlim_max; } - -std::size_t -guarded_stack_allocator::maximum_stacksize() -{ - BOOST_ASSERT( ! is_stack_unbound() ); - return static_cast< std::size_t >( stacksize_limit().rlim_max); -} - -std::size_t -guarded_stack_allocator::minimum_stacksize() -{ return SIGSTKSZ + sizeof( fcontext_t) + 15; } - -std::size_t -guarded_stack_allocator::default_stacksize() -{ - std::size_t size = 8 * minimum_stacksize(); - if ( is_stack_unbound() ) return size; - - BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() ); - return maximum_stacksize() == size - ? size - : std::min( size, maximum_stacksize() ); -} - -void * -guarded_stack_allocator::allocate( std::size_t size) const -{ - BOOST_ASSERT( minimum_stacksize() <= size); - BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) ); - - const std::size_t pages( page_count( size) + 1); // add one guard page - const std::size_t size_( pages * pagesize() ); - BOOST_ASSERT( 0 < size && 0 < size_); - - const int fd( ::open("/dev/zero", O_RDONLY) ); - BOOST_ASSERT( -1 != fd); - // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L) - void * limit = -# if defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) - ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -# else - ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); -# endif - ::close( fd); - if ( ! limit) throw std::bad_alloc(); - - std::memset( limit, size_, '\0'); - - // conforming to POSIX.1-2001 - const int result( ::mprotect( limit, pagesize(), PROT_NONE) ); - BOOST_ASSERT( 0 == result); - - return static_cast< char * >( limit) + size_; -} - -void -guarded_stack_allocator::deallocate( void * vp, std::size_t size) const -{ - BOOST_ASSERT( vp); - BOOST_ASSERT( minimum_stacksize() <= size); - BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) ); - - const std::size_t pages = page_count( size) + 1; - const std::size_t size_ = pages * pagesize(); - BOOST_ASSERT( 0 < size && 0 < size_); - void * limit = static_cast< char * >( vp) - size_; - // conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L) - ::munmap( limit, size_); -} - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -//#endif diff --git a/src/guarded_stack_allocator_windows.cpp b/src/guarded_stack_allocator_windows.cpp deleted file mode 100644 index c08af5f..0000000 --- a/src/guarded_stack_allocator_windows.cpp +++ /dev/null @@ -1,156 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_CONTEXT_SOURCE -#define NOMINMAX - -#include - -extern "C" { -#include -} - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -# if defined(BOOST_MSVC) -# pragma warning(push) -# pragma warning(disable:4244 4267) -# endif - -// x86_64 -// test x86_64 before i386 because icc might -// define __i686__ for x86_64 too -#if defined(__x86_64__) || defined(__x86_64) \ - || defined(__amd64__) || defined(__amd64) \ - || defined(_M_X64) || defined(_M_AMD64) - -// Windows seams not to provide a constant or function -// telling the minimal stacksize -# define MIN_STACKSIZE 8 * 1024 -#else -# define MIN_STACKSIZE 4 * 1024 -#endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace { - -static SYSTEM_INFO system_info_() -{ - SYSTEM_INFO si; - ::GetSystemInfo( & si); - return si; -} - -static SYSTEM_INFO system_info() -{ - static SYSTEM_INFO si = system_info_(); - return si; -} - -static std::size_t page_count( std::size_t stacksize) -{ - return static_cast< std::size_t >( - std::ceil( - static_cast< float >( stacksize) / boost::context::pagesize() ) ); -} - -} - -namespace boost { -namespace context { - -// Windows seams not to provide a limit for the stacksize -bool -guarded_stack_allocator::is_stack_unbound() -{ return true; } - -// because Windows seams not to provide a limit for maximum stacksize -// maximum_stacksize() can never be called (pre-condition ! is_stack_unbound() ) -std::size_t -guarded_stack_allocator::maximum_stacksize() -{ - BOOST_ASSERT( ! is_stack_unbound() ); - return 1 * 1024 * 1024 * 1024; // 1GB -} - -// because Windows seams not to provide a limit for minimum stacksize -std::size_t -guarded_stack_allocator::minimum_stacksize() -{ return MIN_STACKSIZE; } - -std::size_t -guarded_stack_allocator::default_stacksize() -{ - std::size_t size = 64 * 1024; // 64 kB - if ( is_stack_unbound() ) - return std::max( size, minimum_stacksize() ); - - BOOST_ASSERT( maximum_stacksize() >= minimum_stacksize() ); - return maximum_stacksize() == minimum_stacksize() - ? minimum_stacksize() - : std::min( size, maximum_stacksize() ); -} - -void * -guarded_stack_allocator::allocate( std::size_t size) const -{ - BOOST_ASSERT( minimum_stacksize() <= size); - BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) ); - - const std::size_t pages( page_count( size) + 1); // add one guard page - const std::size_t size_ = pages * pagesize(); - BOOST_ASSERT( 0 < size && 0 < size_); - - void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE); - if ( ! limit) throw std::bad_alloc(); - - std::memset( limit, size_, '\0'); - - DWORD old_options; - const BOOL result = ::VirtualProtect( - limit, pagesize(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options); - BOOST_ASSERT( FALSE != result); - - return static_cast< char * >( limit) + size_; -} - -void -guarded_stack_allocator::deallocate( void * vp, std::size_t size) const -{ - BOOST_ASSERT( vp); - BOOST_ASSERT( minimum_stacksize() <= size); - BOOST_ASSERT( is_stack_unbound() || ( maximum_stacksize() >= size) ); - - const std::size_t pages = page_count( size) + 1; - const std::size_t size_ = pages * pagesize(); - BOOST_ASSERT( 0 < size && 0 < size_); - void * limit = static_cast< char * >( vp) - size_; - ::VirtualFree( limit, 0, MEM_RELEASE); -} - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -# if defined(BOOST_MSVC) -# pragma warning(pop) -# endif diff --git a/src/utils_posix.cpp b/src/utils_posix.cpp deleted file mode 100644 index 7d16b9b..0000000 --- a/src/utils_posix.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_CONTEXT_SOURCE - -#include - -extern "C" { -#include -} - -//#if _POSIX_C_SOURCE >= 200112L - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace context { - -std::size_t pagesize() -{ - // conform to POSIX.1-2001 - static std::size_t size = ::sysconf( _SC_PAGESIZE); - return size; -} - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -//#endif diff --git a/src/utils_windows.cpp b/src/utils_windows.cpp deleted file mode 100644 index c50c105..0000000 --- a/src/utils_windows.cpp +++ /dev/null @@ -1,48 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_CONTEXT_SOURCE - -#include - -extern "C" { -#include -} - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace { - -static SYSTEM_INFO system_info_() -{ - SYSTEM_INFO si; - ::GetSystemInfo( & si); - return si; -} - -static SYSTEM_INFO system_info() -{ - static SYSTEM_INFO si = system_info_(); - return si; -} - -} - -namespace boost { -namespace context { - -std::size_t pagesize() -{ return static_cast< std::size_t >( system_info().dwPageSize); } - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif diff --git a/test/test_context.cpp b/test/test_context.cpp index b85d1cb..b09360f 100644 --- a/test/test_context.cpp +++ b/test/test_context.cpp @@ -17,8 +17,16 @@ #include +#include "../example/simple_stack_allocator.hpp" + namespace ctx = boost::context; +typedef ctx::simple_stack_allocator< + 8 * 1024 * 1024, // 8MB + 64 * 1024, // 64kB + 8 * 1024 // 8kB +> stack_allocator; + ctx::fcontext_t fcm; ctx::fcontext_t * fc = 0; int value1 = 0; @@ -76,43 +84,28 @@ void f8( intptr_t arg) ctx::jump_fcontext( fc, & fcm, 0); } -void test_stack() -{ - ctx::guarded_stack_allocator alloc; - - bool unbound = ctx::guarded_stack_allocator::is_stack_unbound(); - std::size_t min = ctx::guarded_stack_allocator::minimum_stacksize(); - std::size_t def = ctx::guarded_stack_allocator::default_stacksize(); - BOOST_CHECK( min <= def); - if ( ! unbound) - { - std::size_t max = ctx::guarded_stack_allocator::maximum_stacksize(); - BOOST_CHECK( max >= def); - } -} - void test_setup() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f1); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f1); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); } void test_start() { value1 = 0; - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f1); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f1); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); BOOST_CHECK_EQUAL( 0, value1); ctx::jump_fcontext( & fcm, fc, 0); @@ -123,13 +116,13 @@ void test_jump() { value1 = 0; - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f3); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f3); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); BOOST_CHECK_EQUAL( 0, value1); ctx::jump_fcontext( & fcm, fc, 0); @@ -140,13 +133,13 @@ void test_jump() void test_result() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f4); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f4); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); int result = ( int) ctx::jump_fcontext( & fcm, fc, 0); BOOST_CHECK_EQUAL( 7, result); @@ -154,14 +147,14 @@ void test_result() void test_arg() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; int i = 7; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f5); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f5); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); int result = ( int) ctx::jump_fcontext( & fcm, fc, i); BOOST_CHECK_EQUAL( i, result); @@ -169,14 +162,14 @@ void test_arg() void test_transfer() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; std::pair< int, int > data = std::make_pair( 3, 7); - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f6); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f6); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); int result = ( int) ctx::jump_fcontext( & fcm, fc, ( intptr_t) & data); BOOST_CHECK_EQUAL( 10, result); @@ -187,14 +180,14 @@ void test_transfer() void test_exception() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; const char * what = "hello world"; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::default_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::default_stacksize(), f7); + void * sp = alloc.allocate( stack_allocator::default_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::default_stacksize(), f7); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::default_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::default_stacksize(), fc->fc_stack.size); ctx::jump_fcontext( & fcm, fc, ( intptr_t) what); BOOST_CHECK_EQUAL( std::string( what), value2); @@ -202,14 +195,14 @@ void test_exception() void test_fp() { - ctx::guarded_stack_allocator alloc; + stack_allocator alloc; double d = 7.13; - void * sp = alloc.allocate( ctx::guarded_stack_allocator::minimum_stacksize() ); - fc = ctx::make_fcontext( sp, ctx::guarded_stack_allocator::minimum_stacksize(), f8); + void * sp = alloc.allocate( stack_allocator::minimum_stacksize() ); + fc = ctx::make_fcontext( sp, stack_allocator::minimum_stacksize(), f8); BOOST_CHECK( fc); BOOST_CHECK_EQUAL( sp, fc->fc_stack.sp); - BOOST_CHECK_EQUAL( ctx::guarded_stack_allocator::minimum_stacksize(), fc->fc_stack.size); + BOOST_CHECK_EQUAL( stack_allocator::minimum_stacksize(), fc->fc_stack.size); ctx::jump_fcontext( & fcm, fc, (intptr_t) & d); BOOST_CHECK_EQUAL( 10.58, value3); @@ -220,7 +213,6 @@ boost::unit_test::test_suite * init_unit_test_suite( int, char* []) boost::unit_test::test_suite * test = BOOST_TEST_SUITE("Boost.Context: context test suite"); - test->add( BOOST_TEST_CASE( & test_stack) ); test->add( BOOST_TEST_CASE( & test_setup) ); test->add( BOOST_TEST_CASE( & test_start) ); test->add( BOOST_TEST_CASE( & test_jump) );