Re: Increasing stack size of NSDocument's open file thread
Re: Increasing stack size of NSDocument's open file thread
- Subject: Re: Increasing stack size of NSDocument's open file thread
- From: Alastair Houghton <email@hidden>
- Date: Thu, 6 Jul 2017 14:04:32 +0100
On 6 Jul 2017, at 06:57, Graham Cox <email@hidden> wrote:
>
> I’m wondering if there’s a way to increase the stack size of the thread that
> opens my NSDocument in the background.
There’s no way an API could exist that did that - in general it’d have to copy
the entire existing stack to a new location, then update a load of pointers
that it has no obvious way to find (otherwise the moment you return, everything
will go wildly wrong).
*However*, within a function that you control, you *can* do the following:
1. Allocate a block of read-write non-executable memory (using e.g. mmap()).
2. Set the stack pointer to point at the end of that block.
3. Push the old stack pointer value.
4. Do whatever work you need to do that requires a larger stack.
5. Pop the old stack pointer value into the stack pointer.
6. Release the memory.
Now, writing such a function in C, C++ or Objective-C is, well, going to rely
on undefined behaviour, and the compiler could break your code at any time.
The safest way to do this is to write a call-with-new-stack function in
assembly language, something like (for x86-64)
; WRITTEN IN MAIL OTOH - NOT GUARANTEED TO BE CORRECT!
;
; Arguments: rdi - argument for function
; rsi - function to call
; rdx - new stack pointer
;
_call_with_new_stack:
movq %rsp, %r8 ; Remember the old stack pointer
movq %rdx, %rsp ; Install the new stack pointer
pushq %r8 ; Push the old stack pointer to the new stack
jsr (%rsi) ; Jump to the function (argument is already in rdi)
popq %rsp ; Pop the old stack pointer value
ret ; Return
Which in C you’d declare as
uintptr_t call_with_new_stack(uintptr_t arg, uintptr_t (*fn)(uintptr_t arg),
void *new_stack_top);
then you can call any function you wish with a new stack pointer. Calling
functions that way *should* be safe for any compiler I can think of; there’s no
way it could make assumptions about the behaviour of the function
call_with_new_stack().
Note also that on x86-64, the stack must be aligned on a 16-byte boundary. I’m
not sure OTOH what the default stack alignment is for ARM; if this needs to be
portable you’ll have to look that up, and you’ll need to write an ARM
equivalent of the above routine also.
> (The reason is that sometimes my documents can get very recursive during
> dearchiving - occasionally extremely large ones can hit the stack limit.
> Rather than redesign the scheme to be flatter, simply increasing the stack
> limit would probably get me out of this on the rare occasion it bites. After
> dearchiving, the object graph is flat, so the stack limit increase only needs
> to be temporary during dearchiving on the background thread).
Removing recursion might actually be a better idea. It’ll certainly be
*cleaner* and won’t be processor specific at all.
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden