LEFT | RIGHT |
1 // Copyright 2013 The Go Authors. All rights reserved. | 1 // Copyright 2013 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 #include "runtime.h" |
6 #include "arch_GOARCH.h" | 6 #include "arch_GOARCH.h" |
7 #include "malloc.h" | 7 #include "malloc.h" |
8 #include "stack.h" | 8 #include "stack.h" |
9 #include "funcdata.h" | 9 #include "funcdata.h" |
10 #include "typekind.h" | 10 #include "typekind.h" |
11 #include "type.h" | 11 #include "type.h" |
12 #include "race.h" | 12 #include "race.h" |
13 #include "mgc0.h" | 13 #include "mgc0.h" |
14 #include "textflag.h" | 14 #include "textflag.h" |
15 | 15 |
16 enum | 16 enum |
17 { | 17 { |
18 // StackDebug == 0: no logging | 18 // StackDebug == 0: no logging |
19 // == 1: logging of per-stack operations | 19 // == 1: logging of per-stack operations |
20 // == 2: logging of per-frame operations | 20 // == 2: logging of per-frame operations |
21 // == 3: logging of per-word updates | 21 // == 3: logging of per-word updates |
22 // == 4: logging of per-word reads | 22 // == 4: logging of per-word reads |
23 StackDebug = 0, | 23 StackDebug = 0, |
24 StackFromSystem = 0, // allocate stacks from system memory instead of
the heap | 24 StackFromSystem = 0, // allocate stacks from system memory instead of
the heap |
25 StackFaultOnFree = 0, // old stacks are mapped noaccess to detect use
after free | 25 StackFaultOnFree = 0, // old stacks are mapped noaccess to detect use
after free |
26 » StackPoisonCopy = 1,» // fill stack that should not be accessed with g
arbage, to detect bad dereferences during copy | 26 » StackPoisonCopy = 0,» // fill stack that should not be accessed with g
arbage, to detect bad dereferences during copy |
27 | 27 |
28 StackCache = 1, | 28 StackCache = 1, |
29 }; | 29 }; |
30 | 30 |
31 // Global pool of spans that have free stacks. | 31 // Global pool of spans that have free stacks. |
32 // Stacks are assigned an order according to size. | 32 // Stacks are assigned an order according to size. |
33 // order = log_2(size/FixedStack) | 33 // order = log_2(size/FixedStack) |
34 // There is a free list for each order. | 34 // There is a free list for each order. |
35 static MSpan stackpool[NumStackOrders]; | 35 static MSpan stackpool[NumStackOrders]; |
36 static Mutex stackpoolmu; | 36 static Mutex stackpoolmu; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 // | return address | | 345 // | return address | |
346 // +------------------+ <- frame->sp | 346 // +------------------+ <- frame->sp |
347 | 347 |
348 void runtime·main(void); | 348 void runtime·main(void); |
349 void runtime·switchtoM(void(*)(void)); | 349 void runtime·switchtoM(void(*)(void)); |
350 | 350 |
351 typedef struct AdjustInfo AdjustInfo; | 351 typedef struct AdjustInfo AdjustInfo; |
352 struct AdjustInfo { | 352 struct AdjustInfo { |
353 Stack old; | 353 Stack old; |
354 uintptr delta; // ptr distance from old to new stack (newbase - oldbase
) | 354 uintptr delta; // ptr distance from old to new stack (newbase - oldbase
) |
355 G *g; | |
356 }; | 355 }; |
357 | 356 |
358 // Adjustpointer checks whether *vpp is in the old stack described by adjinfo. | 357 // Adjustpointer checks whether *vpp is in the old stack described by adjinfo. |
359 // If so, it rewrites *vpp to point into the new stack. | 358 // If so, it rewrites *vpp to point into the new stack. |
360 static void | 359 static void |
361 adjustpointer(AdjustInfo *adjinfo, void *vpp) | 360 adjustpointer(AdjustInfo *adjinfo, void *vpp) |
362 { | 361 { |
363 byte **pp, *p; | 362 byte **pp, *p; |
364 ········ | 363 ········ |
365 pp = vpp; | 364 pp = vpp; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 while(p < ep) | 590 while(p < ep) |
592 *p++ = 0xfd; | 591 *p++ = 0xfd; |
593 } | 592 } |
594 | 593 |
595 if(StackDebug >= 1) | 594 if(StackDebug >= 1) |
596 runtime·printf("copystack gp=%p [%p %p %p]/%d -> [%p %p %p]/%d\n
", gp, old.lo, old.hi-used, old.hi, (int32)(old.hi-old.lo), new.lo, new.hi-used,
new.hi, (int32)newsize); | 595 runtime·printf("copystack gp=%p [%p %p %p]/%d -> [%p %p %p]/%d\n
", gp, old.lo, old.hi-used, old.hi, (int32)(old.hi-old.lo), new.lo, new.hi-used,
new.hi, (int32)newsize); |
597 ········ | 596 ········ |
598 // adjust pointers in the to-be-copied frames | 597 // adjust pointers in the to-be-copied frames |
599 adjinfo.old = old; | 598 adjinfo.old = old; |
600 adjinfo.delta = new.hi - old.hi; | 599 adjinfo.delta = new.hi - old.hi; |
601 adjinfo.g = gp; | |
602 cb = adjustframe; | 600 cb = adjustframe; |
603 runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff
, &cb, &adjinfo, false); | 601 runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff
, &cb, &adjinfo, false); |
604 ········ | 602 ········ |
605 // adjust other miscellaneous things that have pointers into stacks. | 603 // adjust other miscellaneous things that have pointers into stacks. |
606 adjustctxt(gp, &adjinfo); | 604 adjustctxt(gp, &adjinfo); |
607 adjustdefers(gp, &adjinfo); | 605 adjustdefers(gp, &adjinfo); |
608 adjustpanics(gp, &adjinfo); | 606 adjustpanics(gp, &adjinfo); |
609 adjustsudogs(gp, &adjinfo); | 607 adjustsudogs(gp, &adjinfo); |
610 ········ | 608 ········ |
611 // copy the stack to the new location | 609 // copy the stack to the new location |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 ········ | 821 ········ |
824 fn = badc; | 822 fn = badc; |
825 runtime·onM(&fn); | 823 runtime·onM(&fn); |
826 } | 824 } |
827 | 825 |
828 static void | 826 static void |
829 badc(void) | 827 badc(void) |
830 { | 828 { |
831 runtime·throw("attempt to execute C code on Go stack"); | 829 runtime·throw("attempt to execute C code on Go stack"); |
832 } | 830 } |
LEFT | RIGHT |