From 708296036c9753b9d08cba905a398f11095101c9 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 16 Oct 2002 04:39:59 +0000 Subject: Optimize for kernels which are known to have the vfork syscall. Don't confuse the CPUs branch prediction unit by jumping to the return address. --- sysdeps/unix/sysv/linux/i386/vfork.S | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'sysdeps/unix/sysv/linux/i386/vfork.S') diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S index 6f7477e89d..59657e49c0 100644 --- a/sysdeps/unix/sysv/linux/i386/vfork.S +++ b/sysdeps/unix/sysv/linux/i386/vfork.S @@ -1,4 +1,4 @@ -/* Copyright (C) 1999 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Schwab . @@ -20,6 +20,7 @@ #include #define _ERRNO_H 1 #include +#include /* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is @@ -36,22 +37,32 @@ ENTRY (__vfork) /* Stuff the syscall number in EAX and enter into the kernel. */ movl $SYS_ify (vfork), %eax int $0x80 + + /* Jump to the return PC. Don't jump directly since this + disturbs the branch target cache. Instead push the return + address back on the stack. */ + pushl %ecx + cmpl $-4095, %eax - jae .Lerror /* Branch forward if it failed. */ + /* Branch forward if it failed. */ +# ifdef __ASSUME_VFORK_SYSCALL + jae SYSCALL_ERROR_LABEL +.Lpseudo_end: +# else + jae .Lerror +# endif - /* Jump to the return PC. */ - jmp *%ecx + ret +# ifndef __ASSUME_VFORK_SYSCALL .Lerror: - /* Push back the return PC. */ - pushl %ecx - /* Check if vfork syscall is known at all. */ cmpl $-ENOSYS, %eax jne SYSCALL_ERROR_LABEL - +# endif #endif +#ifndef __ASSUME_VFORK_SYSCALL /* If we don't have vfork, fork is close enough. */ movl $SYS_ify (fork), %eax @@ -60,7 +71,7 @@ ENTRY (__vfork) jae SYSCALL_ERROR_LABEL .Lpseudo_end: ret - +#endif PSEUDO_END (__vfork) weak_alias (__vfork, vfork) -- cgit 1.4.1