mirror of
https://github.com/golang/go
synced 2024-11-25 21:28:03 -07:00
runtime: pass setmg function to cgo_init
This keeps the logic about how to set the thread-local variables m and g in code compiled and linked by the gc toolchain, an important property for upcoming cgo changes. It's also just a nice cleanup: one less place to update when these details change. R=golang-dev, r CC=golang-dev https://golang.org/cl/7560048
This commit is contained in:
parent
cb807e7b4a
commit
6a70f9d073
@ -37,6 +37,8 @@ nocpuinfo:
|
|||||||
MOVL _cgo_init(SB), AX
|
MOVL _cgo_init(SB), AX
|
||||||
TESTL AX, AX
|
TESTL AX, AX
|
||||||
JZ needtls
|
JZ needtls
|
||||||
|
MOVL $setmg_gcc<>(SB), BX
|
||||||
|
MOVL BX, 4(SP)
|
||||||
MOVL BP, 0(SP)
|
MOVL BP, 0(SP)
|
||||||
CALL AX
|
CALL AX
|
||||||
// skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
|
// skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
|
||||||
@ -643,6 +645,15 @@ settls:
|
|||||||
MOVL BX, g(CX)
|
MOVL BX, g(CX)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// void setmg_gcc(M*, G*); set m and g. for use by gcc
|
||||||
|
TEXT setmg_gcc<>(SB), 7, $0
|
||||||
|
get_tls(AX)
|
||||||
|
MOVL mm+0(FP), DX
|
||||||
|
MOVL DX, m(AX)
|
||||||
|
MOVL gg+4(FP), DX
|
||||||
|
MOVL DX,g (AX)
|
||||||
|
RET
|
||||||
|
|
||||||
// check that SP is in range [g->stackbase, g->stackguard)
|
// check that SP is in range [g->stackbase, g->stackguard)
|
||||||
TEXT runtime·stackcheck(SB), 7, $0
|
TEXT runtime·stackcheck(SB), 7, $0
|
||||||
get_tls(CX)
|
get_tls(CX)
|
||||||
|
@ -37,6 +37,7 @@ nocpuinfo:
|
|||||||
JZ needtls
|
JZ needtls
|
||||||
// g0 already in DI
|
// g0 already in DI
|
||||||
MOVQ DI, CX // Win64 uses CX for first parameter
|
MOVQ DI, CX // Win64 uses CX for first parameter
|
||||||
|
MOVQ $setmg_gcc<>(SB), SI
|
||||||
CALL AX
|
CALL AX
|
||||||
CMPL runtime·iswindows(SB), $0
|
CMPL runtime·iswindows(SB), $0
|
||||||
JEQ ok
|
JEQ ok
|
||||||
@ -682,6 +683,13 @@ settls:
|
|||||||
MOVQ BX, g(CX)
|
MOVQ BX, g(CX)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
|
// void setmg_gcc(M*, G*); set m and g called from gcc.
|
||||||
|
TEXT setmg_gcc<>(SB),7,$0
|
||||||
|
get_tls(AX)
|
||||||
|
MOVQ DI, m(AX)
|
||||||
|
MOVQ SI, g(AX)
|
||||||
|
RET
|
||||||
|
|
||||||
// check that SP is in range [g->stackbase, g->stackguard)
|
// check that SP is in range [g->stackbase, g->stackguard)
|
||||||
TEXT runtime·stackcheck(SB), 7, $0
|
TEXT runtime·stackcheck(SB), 7, $0
|
||||||
get_tls(CX)
|
get_tls(CX)
|
||||||
|
@ -10,13 +10,15 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -66,15 +68,9 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On FreeBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %gs:0. Our dynamic 8.out's reserve 8 bytes
|
|
||||||
* for the two words g and m at %gs:-8 and %gs:-4.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movl %0, %%gs:-8\n" // MOVL g, -8(GS)
|
|
||||||
"movl %1, %%gs:-4\n" // MOVL m, -4(GS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
|
|
||||||
crosscall_386(ts.fn);
|
crosscall_386(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -10,20 +10,21 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_cgo_sys_thread_start(ThreadStart *ts)
|
_cgo_sys_thread_start(ThreadStart *ts)
|
||||||
{
|
{
|
||||||
@ -67,15 +68,10 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On FreeBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %fs:0. Our dynamic 6.out's reserve 16 bytes
|
|
||||||
* for the two words g and m at %fs:-16 and %fs:-8.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movq %0, %%fs:-16\n" // MOVL g, -16(FS)
|
|
||||||
"movq %1, %%fs:-8\n" // MOVL m, -8(FS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
crosscall_amd64(ts.fn);
|
crosscall_amd64(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,15 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void *threadentry(void*);
|
static void *threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -69,18 +71,9 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On Linux/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %gs:0. Our dynamic 8.out's reserve 8 bytes
|
|
||||||
* for the two words g and m at %gs:-8 and %gs:-4.
|
|
||||||
* Xen requires us to access those words indirect from %gs:0
|
|
||||||
* which points at itself.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movl %%gs:0, %%eax\n" // MOVL 0(GS), tmp
|
|
||||||
"movl %0, -8(%%eax)\n" // MOVL g, -8(GS)
|
|
||||||
"movl %1, -4(%%eax)\n" // MOVL m, -4(GS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m) : "%eax"
|
|
||||||
);
|
|
||||||
|
|
||||||
crosscall_386(ts.fn);
|
crosscall_386(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -8,13 +8,15 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G* g)
|
x_cgo_init(G* g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -64,15 +66,10 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On Linux/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %fs:0. Our dynamic 6.out's reserve 16 bytes
|
|
||||||
* for the two words g and m at %fs:-16 and %fs:-8.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movq %0, %%fs:-16\n" // MOVL g, -16(FS)
|
|
||||||
"movq %1, %%fs:-8\n" // MOVL m, -8(FS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
crosscall_amd64(ts.fn);
|
crosscall_amd64(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -9,13 +9,15 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -65,15 +67,9 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On NetBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %gs:0. Our dynamic 8.out's reserve 8 bytes
|
|
||||||
* for the two words g and m at %gs:-8 and %gs:-4.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movl %0, %%gs:-8\n" // MOVL g, -8(GS)
|
|
||||||
"movl %1, %%gs:-4\n" // MOVL m, -4(GS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
|
|
||||||
crosscall_386(ts.fn);
|
crosscall_386(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -9,13 +9,15 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -66,15 +68,10 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On NetBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %fs:0. Our dynamic 6.out's reserve 16 bytes
|
|
||||||
* for the two words g and m at %fs:-16 and %fs:-8.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movq %0, %%fs:-16\n" // MOVL g, -16(FS)
|
|
||||||
"movq %1, %%fs:-8\n" // MOVL m, -8(FS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
crosscall_amd64(ts.fn);
|
crosscall_amd64(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
// TCB_SIZE is sizeof(struct thread_control_block),
|
// TCB_SIZE is sizeof(struct thread_control_block),
|
||||||
// as defined in /usr/src/lib/librthread/tcb.h
|
// as defined in /usr/src/lib/librthread/tcb.h
|
||||||
@ -82,12 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -154,15 +156,9 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On OpenBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %gs:0. Our dynamic 8.out's reserve 8 bytes
|
|
||||||
* for the two words g and m at %gs:-8 and %gs:-4.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movl %0, %%gs:-8\n" // MOVL g, -8(GS)
|
|
||||||
"movl %1, %%gs:-4\n" // MOVL m, -4(GS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
|
|
||||||
crosscall_386(ts.fn);
|
crosscall_386(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "libcgo.h"
|
#include "libcgo.h"
|
||||||
|
|
||||||
static void* threadentry(void*);
|
static void* threadentry(void*);
|
||||||
|
static void (*setmg_gcc)(void*, void*);
|
||||||
|
|
||||||
// TCB_SIZE is sizeof(struct thread_control_block),
|
// TCB_SIZE is sizeof(struct thread_control_block),
|
||||||
// as defined in /usr/src/lib/librthread/tcb.h
|
// as defined in /usr/src/lib/librthread/tcb.h
|
||||||
@ -82,12 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
x_cgo_init(G *g)
|
x_cgo_init(G *g, void (*setmg)(void*, void*))
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
size_t size;
|
size_t size;
|
||||||
void *handle;
|
void *handle;
|
||||||
|
|
||||||
|
setmg_gcc = setmg;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_getstacksize(&attr, &size);
|
pthread_attr_getstacksize(&attr, &size);
|
||||||
g->stackguard = (uintptr)&attr - size + 4096;
|
g->stackguard = (uintptr)&attr - size + 4096;
|
||||||
@ -155,15 +157,10 @@ threadentry(void *v)
|
|||||||
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set specific keys. On OpenBSD/ELF, the thread local storage
|
* Set specific keys.
|
||||||
* is just before %fs:0. Our dynamic 6.out's reserve 16 bytes
|
|
||||||
* for the two words g and m at %fs:-16 and %fs:-8.
|
|
||||||
*/
|
*/
|
||||||
asm volatile (
|
setmg_gcc((void*)ts.m, (void*)ts.g);
|
||||||
"movq %0, %%fs:-16\n" // MOVL g, -16(FS)
|
|
||||||
"movq %1, %%fs:-8\n" // MOVL m, -8(FS)
|
|
||||||
:: "r"(ts.g), "r"(ts.m)
|
|
||||||
);
|
|
||||||
crosscall_amd64(ts.fn);
|
crosscall_amd64(ts.fn);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user