Author: hyperion
Date: Sun Dec 14 13:49:05 2008
New Revision: 38081
URL: 
http://svn.reactos.org/svn/reactos?rev=38081&view=rev
Log:
modified   include/reactos/libs/pseh/pseh2.h
modified   lib/pseh/framebased-gcchack.c
   Disassemble trampolines in the library, instead of the macros. Results in better,
smaller code. As a side effect, PSEH no longer requires a trampoline for nested functions
- which results in even better, even smaller code in many common cases where the nested
functions don't use any variables from the containing function
   Simulate a no-op setjmp so that GCC correctly handles variables in registers, instead
of surprise-corrupting random variables in random conditions
   Save EBP every time a _SEH2_TRY/_SEH2_EXCEPT is entered, instead of only the first
time: correctly handles code compiled with -fomit-frame-pointers
   Don't generate a nested function for a _SEH2_EXCEPT() filter expression if the
value is a compile-time constant: convert the value to (void *)0, (void *)1 or (void *)-1,
and set that as the filter, instead (like Visual C++ does, incidentally)
   If a _SEH2_EXCEPT() filter expression is a compile-time constant evaluating to
EXCEPTION_CONTINUE_EXECUTION or EXCEPTION_CONTINUE_SEARCH, allow GCC to optimize out the
body of the _SEH2_EXCEPT (because it'd be unreachable). This should really result in a
compile-time warning, but #pragma message is unsupported in GCC 4.1.3
   Let _SEH2_EXCEPT() accept a comma expression as filter expression (e.g.
_SEH2_EXCEPT(MessageBox(...), EXCEPTION_EXECUTE_HANDLER) instead of
_SEH2_EXCEPT((MessageBox(...), EXCEPTION_EXECUTE_HANDLER)))
   Small optimizations in PSEH library
   Clean up GCC hacks
   Remove currently unused PSEH 3 hacks
Modified:
    trunk/reactos/include/reactos/libs/pseh/pseh2.h
    trunk/reactos/lib/pseh/framebased-gcchack.c
Modified: trunk/reactos/include/reactos/libs/pseh/pseh2.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/…
==============================================================================
--- trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] Sun Dec 14 13:49:05 2008
@@ -55,7 +55,6 @@
 typedef struct __SEH2TryLevel
 {
        volatile struct __SEH2TryLevel * ST_Next;
-       void * ST_FramePointer;
        void * ST_Filter;
        void * ST_Body;
 }
@@ -120,28 +119,36 @@
 #define __SEH_PRETEND_SIDE_EFFECT (void)0
 /* Forces GCC to consider the specified label reachable */
-#define __SEH_USE_LABEL(L_) __asm__ __volatile__("# %0\n" : : "i"
(&&L_))
+#define __SEH_USE_LABEL(L_) if(__SEH_VOLATILE_FALSE) goto L_;
 /* Makes GCC pretend the specified label is reachable, to silence warnings */
 #define __SEH_PRETEND_USE_LABEL(L_) (void)(&&L_)
-/* Forces GCC to emit the specified nested function as a function */
-#define __SEH_USE_NESTED_FUNCTION(F_) (void)(&F_) /* __attribute__((noinline)) seems
to do the trick */
-
 /* Soft memory barrier */
 #define __SEH_BARRIER __asm__ __volatile__("#":::"memory")
 /* GCC doesn't know that this equals zero */
-#define __SEH_ZERO ({ int zero = 0; __asm__ __volatile__("#" : "+g"
(zero)); zero; })
-
-#define __SEH_FALSE __builtin_expect(__SEH_ZERO, 0)
-#define __SEH_TRUE  __builtin_expect(!__SEH_ZERO, 1)
+#define __SEH_VOLATILE_ZERO ({ int zero = 0; __asm__ __volatile__("#" :
"+g" (zero)); zero; })
+
+/* GCC believes this is setjmp */
+#define __SEH_PRETEND_SETJMP() (_SEH2PretendSetjmp(), __SEH_VOLATILE_FALSE)
+
+#define __SEH_VOLATILE_FALSE __builtin_expect(__SEH_VOLATILE_ZERO, 0)
+#define __SEH_VOLATILE_TRUE  __builtin_expect(!__SEH_VOLATILE_ZERO, 1)
+
+#define ___SEH_STRINGIFY(X_) # X_
+#define __SEH_STRINGIFY(X_) ___SEH_STRINGIFY(X_)
+
+static
+__inline__
+__attribute__((returns_twice))
+__attribute__((always_inline))
+void _SEH2PretendSetjmp(void)
+{
+}
 #define __SEH_FORCE_NEST \
        __asm__ __volatile__("#%0" : : "r" (&_SEHFrame))
-
-#define __SEH_NESTED_PROLOG \
-       __SEH_FORCE_NEST;
 #define __SEH_DECLARE_EXCEPT_PFN(NAME_) int (__cdecl * NAME_)(void *)
 #define __SEH_DECLARE_EXCEPT(NAME_) int __cdecl NAME_(void *)
@@ -155,21 +162,19 @@
 #define __SEH_RETURN_FINALLY() return
 #define __SEH_BEGIN_TRY \
+       if(!__SEH_PRETEND_SETJMP()) \
        { \
-               __label__ _SEHBeginTry; \
                __label__ _SEHEndTry; \
-        \
-               __SEH_USE_LABEL(_SEHBeginTry); \
-               __SEH_USE_LABEL(_SEHEndTry); \
-        \
-               _SEHBeginTry: __SEH_SIDE_EFFECT; \
+ \
+               __SEH_PRETEND_USE_LABEL(_SEHEndTry); \
+ \
                { \
                        __SEH_BARRIER;
 #define __SEH_END_TRY \
                        __SEH_BARRIER; \
                } \
-               _SEHEndTry: __SEH_SIDE_EFFECT; \
+               _SEHEndTry:; \
        }
 #define __SEH_SET_TRYLEVEL(TRYLEVEL_) \
@@ -188,11 +193,6 @@
 #define __SEH_BEGIN_SCOPE \
        for(;;) \
        { \
-               __label__ _SEHBeginScope; \
-               __label__ _SEHEndScope; \
- \
-               _SEHBeginScope: __SEH_SIDE_EFFECT; \
- \
                const int _SEHTopTryLevel = (_SEH2ScopeKind != 0); \
                _SEH2Frame_t * const _SEHCurFrameP = _SEH2FrameP; \
                volatile _SEH2TryLevel_t * const _SEHPrevTryLevelP = _SEH2TryLevelP; \
@@ -200,9 +200,6 @@
         (void)_SEHTopTryLevel; \
         (void)_SEHCurFrameP; \
         (void)_SEHPrevTryLevelP; \
- \
-               __SEH_USE_LABEL(_SEHBeginScope); \
-               __SEH_USE_LABEL(_SEHEndScope); \
  \
                { \
                        __label__ _SEHBeforeTry; \
@@ -227,15 +224,10 @@
                        __SEH_ENTER_TRYLEVEL(); \
  \
                        if(_SEHTopTryLevel) \
-                       { \
-                               __SEH_BARRIER; __asm__ __volatile__("mov %%ebp,
%0\n#%1" : "=m" (_SEHFrame.SF_FramePointer) : "r"
(__builtin_frame_address(0))); __SEH_BARRIER; \
                                _SEH2EnterFrame(&_SEHFrame); \
-                       } \
 #define __SEH_END_SCOPE \
                } \
- \
-               _SEHEndScope: __SEH_SIDE_EFFECT; \
  \
                break; \
        }
@@ -244,14 +236,13 @@
        __label__ _SEHBeginExcept; \
        __label__ _SEHEndExcept; \
  \
-       auto __SEH_DECLARE_EXCEPT(_SEHExcept); \
        auto __SEH_DECLARE_FINALLY(_SEHFinally);
 #define _SEH2_TRY \
        __SEH_BEGIN_SCOPE \
        { \
                __SEH_SCOPE_LOCALS; \
-\
+ \
                __SEH_BEGIN_TRY \
                {
@@ -265,11 +256,8 @@
                __SEH_PRETEND_USE_LABEL(_SEHBeginExcept); \
                __SEH_PRETEND_USE_LABEL(_SEHEndExcept); \
  \
-               __SEH_USE_NESTED_FUNCTION(_SEHFinally); \
- \
-               _SEHTryLevel.ST_FramePointer = _SEHClosureFromTrampoline((_SEHTrampoline_t
*)&_SEHFinally); \
                _SEHTryLevel.ST_Filter = 0; \
-               _SEHTryLevel.ST_Body = _SEHFunctionFromTrampoline((_SEHTrampoline_t
*)&_SEHFinally); \
+               _SEHTryLevel.ST_Body = &_SEHFinally; \
  \
                goto _SEHDoTry; \
                _SEHAfterTry:; \
@@ -284,10 +272,9 @@
                _SEHFinally(); \
                goto _SEHEndExcept; \
  \
-               _SEHBeginExcept: __SEH_PRETEND_SIDE_EFFECT; \
-               __attribute__((unused)) __SEH_DEFINE_EXCEPT(_SEHExcept) {
__SEH_RETURN_EXCEPT(0); } \
- \
-               __attribute__((noinline)) __attribute__((used))
__SEH_DEFINE_FINALLY(_SEHFinally) \
+               _SEHBeginExcept:; \
+ \
+               __attribute__((noinline)) __SEH_DEFINE_FINALLY(_SEHFinally) \
                { \
                        __SEH_END_SCOPE_CHAIN; \
  \
@@ -295,39 +282,64 @@
                        (void)_SEH2FrameP; \
                        (void)_SEH2TryLevelP; \
  \
-                       __SEH_NESTED_PROLOG; \
- \
                        for(;; ({ __SEH_RETURN_FINALLY(); })) \
                        {
-#define _SEH2_EXCEPT(E_) \
+#define _SEH2_EXCEPT(...) \
                } \
                __SEH_END_TRY; \
  \
                goto _SEHAfterTry; \
  \
                _SEHBeforeTry:; \
-\
-               __SEH_USE_LABEL(_SEHBeginExcept); \
-               __SEH_USE_LABEL(_SEHEndExcept); \
-\
-               __SEH_USE_NESTED_FUNCTION(_SEHExcept); \
- \
-               _SEHTryLevel.ST_FramePointer = _SEHClosureFromTrampoline((_SEHTrampoline_t
*)&_SEHExcept); \
-               _SEHTryLevel.ST_Filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t
*)&_SEHExcept); \
-               _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \
-               __SEH_BARRIER; __asm__ __volatile__("mov %%esp, %0" :
"=m" (_SEH2FrameP->SF_StackPointer)); __SEH_BARRIER; \
-\
+ \
+               if(__builtin_constant_p((__VA_ARGS__))) \
+               { \
+                       if((__VA_ARGS__) > 0) \
+                       { \
+                               _SEHTryLevel.ST_Filter = (void *)1; \
+                               _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \
+                               __SEH_USE_LABEL(_SEHBeginExcept); \
+                       } \
+                       else if((__VA_ARGS__) < 0) \
+                       { \
+                               _SEHTryLevel.ST_Filter = (void *)-1; \
+                               _SEHTryLevel.ST_Body = NULL; \
+                       } \
+                       else \
+                       { \
+                               _SEHTryLevel.ST_Filter = (void *)0; \
+                               _SEHTryLevel.ST_Body = NULL; \
+                       } \
+               } \
+               else \
+               { \
+                       __SEH_DEFINE_EXCEPT(_SEHExcept) \
+                       { \
+                               __SEH_RETURN_EXCEPT((__VA_ARGS__)); \
+                       } \
+ \
+                       _SEHTryLevel.ST_Filter = &_SEHExcept; \
+                       _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \
+                       __SEH_USE_LABEL(_SEHBeginExcept); \
+               } \
+ \
+               __SEH_BARRIER; \
+ \
+               __asm__ __volatile__ \
+               ( \
+                       "mov %%ebp, %0\n" \
+                       "mov %%esp, %1" : \
+                       "=m" (_SEH2FrameP->SF_FramePointer), \
+                       "=m" (_SEH2FrameP->SF_StackPointer) \
+               ); \
+ \
+               __SEH_BARRIER; \
+ \
                goto _SEHDoTry; \
-\
-               __attribute__((noinline)) __attribute__((used))
__SEH_DEFINE_EXCEPT(_SEHExcept) \
-               { \
-                       __SEH_NESTED_PROLOG; \
-                       __SEH_RETURN_EXCEPT(E_); \
-               } \
-\
+ \
                __attribute__((unused)) __SEH_DEFINE_FINALLY(_SEHFinally) {
__SEH_RETURN_FINALLY(); } \
-\
+ \
                _SEHAfterTry:; \
                if(_SEHTopTryLevel) \
                        _SEH2LeaveFrame(); \
@@ -336,12 +348,9 @@
                        __SEH_LEAVE_TRYLEVEL(); \
                } \
  \
-               if(__SEH_FALSE) \
-                       goto _SEHBeginExcept; \
-               else \
-                       goto _SEHEndExcept; \
-\
-               _SEHBeginExcept: __SEH_SIDE_EFFECT; \
+               goto _SEHEndExcept; \
+ \
+               _SEHBeginExcept:; \
                { \
                        { \
                                _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ?
&_SEHFrame : _SEHCurFrameP; \
@@ -352,7 +361,8 @@
                                __SEH_BARRIER; \
                        } \
                } \
-               _SEHEndExcept: __SEH_SIDE_EFFECT; \
+ \
+               _SEHEndExcept:; \
        } \
        __SEH_END_SCOPE;
@@ -379,7 +389,7 @@
 #define _SEH2_TRY __try
 #define _SEH2_FINALLY __finally
-#define _SEH2_EXCEPT(E_) __except((E_))
+#define _SEH2_EXCEPT(...) __except(__VA_ARGS__)
 #define _SEH2_END
 #define _SEH2_GetExceptionInformation() (GetExceptionInformation())
Modified: trunk/reactos/lib/pseh/framebased-gcchack.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/framebased-gcchac…
==============================================================================
--- trunk/reactos/lib/pseh/framebased-gcchack.c [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/framebased-gcchack.c [iso-8859-1] Sun Dec 14 13:49:05 2008
@@ -53,7 +53,25 @@
 FORCEINLINE
 int _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel,
EXCEPTION_POINTERS * ep)
 {
-       return __SEH2Except(trylevel->ST_Filter, trylevel->ST_FramePointer, ep);
+       void * filter = trylevel->ST_Filter;
+       void * context = NULL;
+
+       if(filter == (void *)0)
+               return 0;
+
+       if(filter == (void *)1)
+               return 1;
+
+       if(filter == (void *)-1)
+               return -1;
+
+       if(_SEHIsTrampoline((_SEHTrampoline_t *)filter))
+       {
+               context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)filter);
+               filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter);
+       }
+
+       return __SEH2Except(filter, context, ep);
 }
 static
@@ -62,7 +80,16 @@
 #endif
 void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
 {
-       __SEH2Finally(trylevel->ST_Body, trylevel->ST_FramePointer);
+       void * body = trylevel->ST_Body;
+       void * context = NULL;
+
+       if(_SEHIsTrampoline((_SEHTrampoline_t *)body))
+       {
+               context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)body);
+               body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body);
+       }
+
+       __SEH2Finally(body, context);
 }
 extern
@@ -91,10 +118,7 @@
        __SEH2EnterFrame(&nestedframe);
        for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel !=
dsttrylevel; trylevel = trylevel->ST_Next)
-       {
-               if(!trylevel->ST_Filter)
-                       _SEH2Finally(frame, trylevel);
-       }
+               _SEH2Finally(frame, trylevel);
        frame->SF_TopTryLevel = dsttrylevel;
@@ -132,25 +156,21 @@
        {
                int ret = 0;
                volatile _SEH2TryLevel_t * trylevel;
+               EXCEPTION_POINTERS ep;
+
+               ep.ExceptionRecord = ExceptionRecord;
+               ep.ContextRecord = ContextRecord;
                frame->SF_Code = ExceptionRecord->ExceptionCode;
                for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel =
trylevel->ST_Next)
                {
-                       if(trylevel->ST_Filter)
-                       {
-                               EXCEPTION_POINTERS ep;
-
-                               ep.ExceptionRecord = ExceptionRecord;
-                               ep.ContextRecord = ContextRecord;
-
-                               ret = _SEH2Except(frame, trylevel, &ep);
-
-                               if(ret < 0)
-                                       return ExceptionContinueExecution;
-                               else if(ret > 0)
-                                       _SEH2Handle(frame, trylevel);
-                       }
+                       ret = _SEH2Except(frame, trylevel, &ep);
+
+                       if(ret < 0)
+                               return ExceptionContinueExecution;
+                       else if(ret > 0)
+                               _SEH2Handle(frame, trylevel);
                }
        }