Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix i386 Fiber.swapcontext #10293

Merged
merged 1 commit into from
Jan 25, 2021
Merged

Fix i386 Fiber.swapcontext #10293

merged 1 commit into from
Jan 25, 2021

Conversation

bcardiff
Copy link
Member

Regression introduced by #9829

Before #9829 the asm emitted by Fiber.swapcontext was:

"*Fiber::swapcontext<Pointer(Fiber::Context), Pointer(Fiber::Context)>:Nil":
	.cfi_startproc
	movl	8(%esp), %eax
	movl	4(%esp), %ecx
	#APP

	pushl	%edi	# push 1st argument (because of initial resume)
	pushl	%ebx	# push callee-saved registers on the stack
	pushl	%ebp
	pushl	%esi
	movl	%esp, (%ecx)	# current_context.stack_top = %esp
	movl	$1, 4(%ecx)	# current_context.resumable = 1

	movl	$0, 4(%eax)	# new_context.resumable = 0
	movl	(%eax), %esp	# %esp = new_context.stack_top
	popl	%esi	# pop callee-saved registers from the stack
	popl	%ebp
	popl	%ebx
	popl	%edi	# pop first argument (for initial resume)

	#NO_APP
	retl

i386 is the only target that has this prelude in the swapcontext. It seems I didn't notice it before but test-ecosystem in 32 bits platforms was complaining.

@bcardiff bcardiff added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:runtime platform labels Jan 25, 2021
@bcardiff bcardiff added this to the 0.36.0 milestone Jan 25, 2021
Copy link
Member

@asterite asterite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@straight-shoota
Copy link
Member

straight-shoota commented Jan 25, 2021

Where did those movl instructions come from before #9829? They've not been in i386.cr:

def self.swapcontext(current_context, new_context) : Nil
asm("
pushl %edi // push 1st argument (because of initial resume)
pushl %ebx // push callee-saved registers on the stack
pushl %ebp

Is this related to switching from LLVMConstInlineAsm to LLVMGetInlineAsm? If so, does this patch work for LLVM < 7.0?

@bcardiff
Copy link
Member Author

It's because on i386 the arguments are passed entirely on the stack.

The inline asm before #9829 was getting the arguments as registers thanks to the :: "r"(current_context), "r"(new_context). In the rest of the swapcontext implementation having the argument values in registers is directly.

This PR simulates what the :: "r"(current_context), "r"(new_context) was doing on i386 accurately. The LLVM < 7.0 branch has arguments so we are fine, although argument in inline asm in naked functions are not actually supported and it was part of the fix to support llvm 11.0.

@bcardiff bcardiff merged commit 4625c46 into master Jan 25, 2021
@bcardiff bcardiff deleted the fix/fiber-swapcontext-i386 branch January 25, 2021 20:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. platform topic:stdlib:runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants