LEFT | RIGHT |
(no file at all) | |
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 | 9 |
10 enum | 10 enum |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 // gp->status is usually Grunning, but it could be Gsyscall if a stack s
plit | 204 // gp->status is usually Grunning, but it could be Gsyscall if a stack s
plit |
205 // happens during a function call inside entersyscall. | 205 // happens during a function call inside entersyscall. |
206 gp = m->curg; | 206 gp = m->curg; |
207 oldstatus = gp->status; | 207 oldstatus = gp->status; |
208 | 208 |
209 framesize = m->moreframesize; | 209 framesize = m->moreframesize; |
210 argsize = m->moreargsize; | 210 argsize = m->moreargsize; |
211 gp->status = Gwaiting; | 211 gp->status = Gwaiting; |
212 gp->waitreason = "stack split"; | 212 gp->waitreason = "stack split"; |
213 reflectcall = framesize==1; | 213 reflectcall = framesize==1; |
214 | 214 » if(reflectcall) |
| 215 » » framesize = 0; |
| 216 |
| 217 » // For reflectcall the context already points to beginning of reflect·ca
ll. |
215 if(!reflectcall) | 218 if(!reflectcall) |
216 runtime·rewindmorestack(&gp->sched); | 219 runtime·rewindmorestack(&gp->sched); |
217 | 220 |
218 sp = gp->sched.sp; | 221 sp = gp->sched.sp; |
219 if(thechar == '6' || thechar == '8') { | 222 if(thechar == '6' || thechar == '8') { |
220 // The call to morestack cost a word. | 223 // The call to morestack cost a word. |
221 sp -= sizeof(uintptr); | 224 sp -= sizeof(uintptr); |
222 } | 225 } |
223 if(StackDebug || sp < gp->stackguard - StackGuard) { | 226 if(StackDebug || sp < gp->stackguard - StackGuard) { |
224 runtime·printf("runtime: newstack framesize=%p argsize=%p sp=%p
stack=[%p, %p]\n" | 227 runtime·printf("runtime: newstack framesize=%p argsize=%p sp=%p
stack=[%p, %p]\n" |
225 "\tmorebuf={pc:%p sp:%p lr:%p}\n" | 228 "\tmorebuf={pc:%p sp:%p lr:%p}\n" |
226 "\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n", | 229 "\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n", |
227 (uintptr)framesize, (uintptr)argsize, sp, gp->stackguard
- StackGuard, gp->stackbase, | 230 (uintptr)framesize, (uintptr)argsize, sp, gp->stackguard
- StackGuard, gp->stackbase, |
228 m->morebuf.pc, m->morebuf.sp, m->morebuf.lr, | 231 m->morebuf.pc, m->morebuf.sp, m->morebuf.lr, |
229 gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt
); | 232 gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt
); |
230 } | 233 } |
231 if(sp < gp->stackguard - StackGuard) { | 234 if(sp < gp->stackguard - StackGuard) { |
232 runtime·printf("runtime: split stack overflow: %p < %p\n", sp, g
p->stackguard - StackGuard); | 235 runtime·printf("runtime: split stack overflow: %p < %p\n", sp, g
p->stackguard - StackGuard); |
233 runtime·throw("runtime: split stack overflow"); | 236 runtime·throw("runtime: split stack overflow"); |
234 } | 237 } |
235 | 238 |
236 if(argsize % sizeof(uintptr) != 0) { | 239 if(argsize % sizeof(uintptr) != 0) { |
237 runtime·printf("runtime: stack split with misaligned argsize %d\
n", argsize); | 240 runtime·printf("runtime: stack split with misaligned argsize %d\
n", argsize); |
238 runtime·throw("runtime: stack split argsize"); | 241 runtime·throw("runtime: stack split argsize"); |
239 } | 242 } |
240 | 243 |
241 » reflectcall = framesize==1; | 244 » if(gp->stackguard0 == StackPreempt) { |
242 » if(reflectcall) | 245 » » if(gp == m->g0) |
243 » » framesize = 0; | 246 » » » runtime·throw("runtime: preempt g0"); |
| 247 » » if(oldstatus == Grunning && (m->p == nil || m->p->status != Prun
ning)) |
| 248 » » » runtime·throw("runtime: g is running but p is not"); |
| 249 » » // Be conservative about where we preempt. |
| 250 » » // We are interested in preempting user Go code, not runtime cod
e. |
| 251 » » if(oldstatus != Grunning || m->locks || m->mallocing || m->gcing
) { |
| 252 » » » // Let the goroutine keep running for now. |
| 253 » » » // TODO(dvyukov): remember but delay the preemption. |
| 254 » » » gp->stackguard0 = gp->stackguard; |
| 255 » » » gp->status = oldstatus; |
| 256 » » » runtime·gogo(&gp->sched);» // never return |
| 257 » » } |
| 258 » » // Act like goroutine called runtime.Gosched. |
| 259 » » gp->status = oldstatus; |
| 260 » » runtime·gosched0(gp);» // never return |
| 261 » } |
244 | 262 |
245 if(reflectcall && m->morebuf.sp - sizeof(Stktop) - argsize - 32 > gp->st
ackguard) { | 263 if(reflectcall && m->morebuf.sp - sizeof(Stktop) - argsize - 32 > gp->st
ackguard) { |
246 // special case: called from reflect.call (framesize==1) | 264 // special case: called from reflect.call (framesize==1) |
247 // to call code with an arbitrary argument size, | 265 // to call code with an arbitrary argument size, |
248 // and we have enough space on the current stack. | 266 // and we have enough space on the current stack. |
249 // the new Stktop* is necessary to unwind, but | 267 // the new Stktop* is necessary to unwind, but |
250 // we don't need to create a new segment. | 268 // we don't need to create a new segment. |
251 top = (Stktop*)(m->morebuf.sp - sizeof(*top)); | 269 top = (Stktop*)(m->morebuf.sp - sizeof(*top)); |
252 stk = (byte*)gp->stackguard - StackGuard; | 270 stk = (byte*)gp->stackguard - StackGuard; |
253 free = 0; | 271 free = 0; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 *(int32*)345 = 123; // never return | 337 *(int32*)345 = 123; // never return |
320 } | 338 } |
321 | 339 |
322 // adjust Gobuf as if it executed a call to fn | 340 // adjust Gobuf as if it executed a call to fn |
323 // and then did an immediate gosave. | 341 // and then did an immediate gosave. |
324 void | 342 void |
325 runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv) | 343 runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv) |
326 { | 344 { |
327 runtime·gostartcall(gobuf, fv->fn, fv); | 345 runtime·gostartcall(gobuf, fv->fn, fv); |
328 } | 346 } |
LEFT | RIGHT |