[ros-diffs] [hyperion] 38081: 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

hyperion at svn.reactos.org hyperion at svn.reactos.org
Sun Dec 14 20:49:06 CET 2008


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/pseh2.h?rev=38081&r1=38080&r2=38081&view=diff
==============================================================================
--- 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-gcchack.c?rev=38081&r1=38080&r2=38081&view=diff
==============================================================================
--- 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);
 		}
 	}
 



More information about the Ros-diffs mailing list