On 6 Jul 2017, at 06:57, Graham Cox <graham....@bigpond.com> 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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to