Skip to content
  • KJ Tsanaktsidis's avatar
    80771444
    Pass down "stack start" variables from closer to the top of the stack · 80771444
    KJ Tsanaktsidis authored
    This commit changes how stack extents are calculated for both the main
    thread and other threads. Ruby uses the address of a local variable as
    part of the calculation for machine stack extents:
    
    * pthreads uses it as a lower-bound on the start of the stack, because
      glibc (and maybe other libcs) can store its own data on the stack
      before calling into user code on thread creation.
    * win32 uses it as an argument to VirtualQuery, which gets the extent of
      the memory mapping which contains the variable
    
    However, the local being used for this is actually too low (too close to
    the leaf function call) in both the main thread case and the new thread
    case.
    
    In the main thread case, we have the `INIT_STACK` macro, which is used
    for pthreads to set the `native_main_thread->stack_start` value. This
    value is correctly captured at the very top level of the program (in
    main.c). However, this is _not_ what's used to set the execution context
    machine stack (`th->ec->machine_stack.stack_start`); that gets set as
    part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
    address of a local variable allocated _inside_ `Init_BareVM`. This is
    too low; we need to use a local allocated closer to the top of the
    program.
    
    In the new thread case, the lolcal is allocated inside
    `native_thread_init_stack`, which is, again, too low.
    
    In both cases, this means that we might have VALUEs lying outside the
    bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
    correctly by the GC machinery.
    
    To fix this,
    
    * In the main thread case: We already have `INIT_STACK` at the right
      level, so just pass that local var to `ruby_thread_init_stack`.
    * In the new thread case: Allocate the local one level above the call to
      `native_thread_init_stack` in `call_thread_start_func2`.
    
    [Bug #20001]
    
    fix
    80771444
    Pass down "stack start" variables from closer to the top of the stack
    KJ Tsanaktsidis authored
    This commit changes how stack extents are calculated for both the main
    thread and other threads. Ruby uses the address of a local variable as
    part of the calculation for machine stack extents:
    
    * pthreads uses it as a lower-bound on the start of the stack, because
      glibc (and maybe other libcs) can store its own data on the stack
      before calling into user code on thread creation.
    * win32 uses it as an argument to VirtualQuery, which gets the extent of
      the memory mapping which contains the variable
    
    However, the local being used for this is actually too low (too close to
    the leaf function call) in both the main thread case and the new thread
    case.
    
    In the main thread case, we have the `INIT_STACK` macro, which is used
    for pthreads to set the `native_main_thread->stack_start` value. This
    value is correctly captured at the very top level of the program (in
    main.c). However, this is _not_ what's used to set the execution context
    machine stack (`th->ec->machine_stack.stack_start`); that gets set as
    part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
    address of a local variable allocated _inside_ `Init_BareVM`. This is
    too low; we need to use a local allocated closer to the top of the
    program.
    
    In the new thread case, the lolcal is allocated inside
    `native_thread_init_stack`, which is, again, too low.
    
    In both cases, this means that we might have VALUEs lying outside the
    bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
    correctly by the GC machinery.
    
    To fix this,
    
    * In the main thread case: We already have `INIT_STACK` at the right
      level, so just pass that local var to `ruby_thread_init_stack`.
    * In the new thread case: Allocate the local one level above the call to
      `native_thread_init_stack` in `call_thread_start_func2`.
    
    [Bug #20001]
    
    fix
Loading