aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/cgo/gcc_riscv64.S108
-rw-r--r--src/runtime/cgo/gcc_sigaction.c10
-rw-r--r--src/runtime/crash_cgo_test.go1
-rw-r--r--src/runtime/map.go21
-rw-r--r--src/runtime/mpagealloc.go2
-rw-r--r--src/runtime/proc.go2
-rw-r--r--src/runtime/runtime-gdb.py9
-rw-r--r--src/runtime/time.go30
-rw-r--r--src/runtime/time_linux_amd64.s37
9 files changed, 131 insertions, 89 deletions
diff --git a/src/runtime/cgo/gcc_riscv64.S b/src/runtime/cgo/gcc_riscv64.S
index f429dc64ee..fdc77496d9 100644
--- a/src/runtime/cgo/gcc_riscv64.S
+++ b/src/runtime/cgo/gcc_riscv64.S
@@ -8,36 +8,38 @@
* Calling into the gc tool chain, where all registers are caller save.
* Called from standard RISCV ELF psABI, where x8-x9, x18-x27, f8-f9 and
* f18-f27 are callee-save, so they must be saved explicitly, along with
- * x1 (LR).
+ * x1 (LR), x3 (GP) and x4 (TP).
*/
.globl crosscall1
crosscall1:
- sd x1, -200(sp)
- addi sp, sp, -200
- sd x8, 8(sp)
- sd x9, 16(sp)
- sd x18, 24(sp)
- sd x19, 32(sp)
- sd x20, 40(sp)
- sd x21, 48(sp)
- sd x22, 56(sp)
- sd x23, 64(sp)
- sd x24, 72(sp)
- sd x25, 80(sp)
- sd x26, 88(sp)
- sd x27, 96(sp)
- fsd f8, 104(sp)
- fsd f9, 112(sp)
- fsd f18, 120(sp)
- fsd f19, 128(sp)
- fsd f20, 136(sp)
- fsd f21, 144(sp)
- fsd f22, 152(sp)
- fsd f23, 160(sp)
- fsd f24, 168(sp)
- fsd f25, 176(sp)
- fsd f26, 184(sp)
- fsd f27, 192(sp)
+ sd x1, -216(sp)
+ addi sp, sp, -216
+ sd x3, 8(sp)
+ sd x4, 16(sp)
+ sd x8, 24(sp)
+ sd x9, 32(sp)
+ sd x18, 40(sp)
+ sd x19, 48(sp)
+ sd x20, 56(sp)
+ sd x21, 64(sp)
+ sd x22, 72(sp)
+ sd x23, 80(sp)
+ sd x24, 88(sp)
+ sd x25, 96(sp)
+ sd x26, 104(sp)
+ sd x27, 112(sp)
+ fsd f8, 120(sp)
+ fsd f9, 128(sp)
+ fsd f18, 136(sp)
+ fsd f19, 144(sp)
+ fsd f20, 152(sp)
+ fsd f21, 160(sp)
+ fsd f22, 168(sp)
+ fsd f23, 176(sp)
+ fsd f24, 184(sp)
+ fsd f25, 192(sp)
+ fsd f26, 200(sp)
+ fsd f27, 208(sp)
// a0 = *fn, a1 = *setg_gcc, a2 = *g
mv s1, a0
@@ -47,31 +49,33 @@ crosscall1:
jalr ra, s1 // call fn
ld x1, 0(sp)
- ld x8, 8(sp)
- ld x9, 16(sp)
- ld x18, 24(sp)
- ld x19, 32(sp)
- ld x20, 40(sp)
- ld x21, 48(sp)
- ld x22, 56(sp)
- ld x23, 64(sp)
- ld x24, 72(sp)
- ld x25, 80(sp)
- ld x26, 88(sp)
- ld x27, 96(sp)
- fld f8, 104(sp)
- fld f9, 112(sp)
- fld f18, 120(sp)
- fld f19, 128(sp)
- fld f20, 136(sp)
- fld f21, 144(sp)
- fld f22, 152(sp)
- fld f23, 160(sp)
- fld f24, 168(sp)
- fld f25, 176(sp)
- fld f26, 184(sp)
- fld f27, 192(sp)
- addi sp, sp, 200
+ ld x3, 8(sp)
+ ld x4, 16(sp)
+ ld x8, 24(sp)
+ ld x9, 32(sp)
+ ld x18, 40(sp)
+ ld x19, 48(sp)
+ ld x20, 56(sp)
+ ld x21, 64(sp)
+ ld x22, 72(sp)
+ ld x23, 80(sp)
+ ld x24, 88(sp)
+ ld x25, 96(sp)
+ ld x26, 104(sp)
+ ld x27, 112(sp)
+ fld f8, 120(sp)
+ fld f9, 128(sp)
+ fld f18, 136(sp)
+ fld f19, 144(sp)
+ fld f20, 152(sp)
+ fld f21, 160(sp)
+ fld f22, 168(sp)
+ fld f23, 176(sp)
+ fld f24, 184(sp)
+ fld f25, 192(sp)
+ fld f26, 200(sp)
+ fld f27, 208(sp)
+ addi sp, sp, 216
jr ra
diff --git a/src/runtime/cgo/gcc_sigaction.c b/src/runtime/cgo/gcc_sigaction.c
index dd283151f1..fcf1e50740 100644
--- a/src/runtime/cgo/gcc_sigaction.c
+++ b/src/runtime/cgo/gcc_sigaction.c
@@ -49,13 +49,13 @@ x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *ol
sigemptyset(&act.sa_mask);
for (i = 0; i < 8 * sizeof(goact->mask); i++) {
if (goact->mask & ((uint64_t)(1)<<i)) {
- sigaddset(&act.sa_mask, i+1);
+ sigaddset(&act.sa_mask, (int)(i+1));
}
}
- act.sa_flags = goact->flags & ~SA_RESTORER;
+ act.sa_flags = (int)(goact->flags & ~(uint64_t)SA_RESTORER);
}
- ret = sigaction(signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
+ ret = sigaction((int)signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
if (ret == -1) {
// runtime.rt_sigaction expects _cgo_sigaction to return errno on error.
_cgo_tsan_release();
@@ -70,11 +70,11 @@ x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *ol
}
oldgoact->mask = 0;
for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
- if (sigismember(&oldact.sa_mask, i+1) == 1) {
+ if (sigismember(&oldact.sa_mask, (int)(i+1)) == 1) {
oldgoact->mask |= (uint64_t)(1)<<i;
}
}
- oldgoact->flags = oldact.sa_flags;
+ oldgoact->flags = (uint64_t)oldact.sa_flags;
}
_cgo_tsan_release();
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 5729942cee..ce7bed920f 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -591,6 +591,7 @@ func TestSegv(t *testing.T) {
}
for _, test := range []string{"Segv", "SegvInCgo"} {
+ test := test
t.Run(test, func(t *testing.T) {
t.Parallel()
got := runTestProg(t, "testprogcgo", test)
diff --git a/src/runtime/map.go b/src/runtime/map.go
index 59b803d629..985c297cd4 100644
--- a/src/runtime/map.go
+++ b/src/runtime/map.go
@@ -1324,17 +1324,38 @@ func reflect_mapaccess(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
return elem
}
+//go:linkname reflect_mapaccess_faststr reflect.mapaccess_faststr
+func reflect_mapaccess_faststr(t *maptype, h *hmap, key string) unsafe.Pointer {
+ elem, ok := mapaccess2_faststr(t, h, key)
+ if !ok {
+ // reflect wants nil for a missing element
+ elem = nil
+ }
+ return elem
+}
+
//go:linkname reflect_mapassign reflect.mapassign
func reflect_mapassign(t *maptype, h *hmap, key unsafe.Pointer, elem unsafe.Pointer) {
p := mapassign(t, h, key)
typedmemmove(t.elem, p, elem)
}
+//go:linkname reflect_mapassign_faststr reflect.mapassign_faststr
+func reflect_mapassign_faststr(t *maptype, h *hmap, key string, elem unsafe.Pointer) {
+ p := mapassign_faststr(t, h, key)
+ typedmemmove(t.elem, p, elem)
+}
+
//go:linkname reflect_mapdelete reflect.mapdelete
func reflect_mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
mapdelete(t, h, key)
}
+//go:linkname reflect_mapdelete_faststr reflect.mapdelete_faststr
+func reflect_mapdelete_faststr(t *maptype, h *hmap, key string) {
+ mapdelete_faststr(t, h, key)
+}
+
//go:linkname reflect_mapiterinit reflect.mapiterinit
func reflect_mapiterinit(t *maptype, h *hmap, it *hiter) {
mapiterinit(t, h, it)
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go
index 071f1fc274..862882cd82 100644
--- a/src/runtime/mpagealloc.go
+++ b/src/runtime/mpagealloc.go
@@ -155,7 +155,7 @@ func addrsToSummaryRange(level int, base, limit uintptr) (lo int, hi int) {
// upper-bound. Note that the exclusive upper bound may be within a
// summary at this level, meaning if we just do the obvious computation
// hi will end up being an inclusive upper bound. Unfortunately, just
- // adding 1 to that is too broad since we might be on the very edge of
+ // adding 1 to that is too broad since we might be on the very edge
// of a summary's max page count boundary for this level
// (1 << levelLogPages[level]). So, make limit an inclusive upper bound
// then shift, then add 1, so we get an exclusive upper bound at the end.
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 197441dfa7..605e133000 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -623,7 +623,7 @@ func cpuinit() {
// Support cpu feature variables are used in code generated by the compiler
// to guard execution of instructions that can not be assumed to be always supported.
switch GOARCH {
- case "386", "AMD64":
+ case "386", "amd64":
x86HasPOPCNT = cpu.X86.HasPOPCNT
x86HasSSE41 = cpu.X86.HasSSE41
x86HasFMA = cpu.X86.HasFMA
diff --git a/src/runtime/runtime-gdb.py b/src/runtime/runtime-gdb.py
index 8d96dfb609..5bb605cc37 100644
--- a/src/runtime/runtime-gdb.py
+++ b/src/runtime/runtime-gdb.py
@@ -219,6 +219,9 @@ class ChanTypePrinter:
yield ('[{0}]'.format(i), (ptr + j).dereference())
+def paramtypematch(t, pattern):
+ return t.code == gdb.TYPE_CODE_TYPEDEF and str(t).startswith(".param") and pattern.match(str(t.target()))
+
#
# Register all the *Printer classes above.
#
@@ -228,6 +231,8 @@ def makematcher(klass):
try:
if klass.pattern.match(str(val.type)):
return klass(val)
+ elif paramtypematch(val.type, klass.pattern):
+ return klass(val.cast(val.type.target()))
except Exception:
pass
return matcher
@@ -387,7 +392,7 @@ class GoLenFunc(gdb.Function):
def invoke(self, obj):
typename = str(obj.type)
for klass, fld in self.how:
- if klass.pattern.match(typename):
+ if klass.pattern.match(typename) or paramtypematch(obj.type, klass.pattern):
return obj[fld]
@@ -402,7 +407,7 @@ class GoCapFunc(gdb.Function):
def invoke(self, obj):
typename = str(obj.type)
for klass, fld in self.how:
- if klass.pattern.match(typename):
+ if klass.pattern.match(typename) or paramtypematch(obj.type, klass.pattern):
return obj[fld]
diff --git a/src/runtime/time.go b/src/runtime/time.go
index ad267c3365..46e9a8c2ab 100644
--- a/src/runtime/time.go
+++ b/src/runtime/time.go
@@ -367,9 +367,9 @@ func deltimer(t *timer) bool {
// dodeltimer removes timer i from the current P's heap.
// We are locked on the P when this is called.
-// It reports whether it saw no problems due to races.
+// It returns the smallest changed index in pp.timers.
// The caller must have locked the timers for pp.
-func dodeltimer(pp *p, i int) {
+func dodeltimer(pp *p, i int) int {
if t := pp.timers[i]; t.pp.ptr() != pp {
throw("dodeltimer: wrong P")
} else {
@@ -381,16 +381,18 @@ func dodeltimer(pp *p, i int) {
}
pp.timers[last] = nil
pp.timers = pp.timers[:last]
+ smallestChanged := i
if i != last {
// Moving to i may have moved the last timer to a new parent,
// so sift up to preserve the heap guarantee.
- siftupTimer(pp.timers, i)
+ smallestChanged = siftupTimer(pp.timers, i)
siftdownTimer(pp.timers, i)
}
if i == 0 {
updateTimer0When(pp)
}
atomic.Xadd(&pp.numTimers, -1)
+ return smallestChanged
}
// dodeltimer0 removes timer 0 from the current P's heap.
@@ -675,13 +677,14 @@ func adjusttimers(pp *p, now int64) {
switch s := atomic.Load(&t.status); s {
case timerDeleted:
if atomic.Cas(&t.status, s, timerRemoving) {
- dodeltimer(pp, i)
+ changed := dodeltimer(pp, i)
if !atomic.Cas(&t.status, timerRemoving, timerRemoved) {
badTimer()
}
atomic.Xadd(&pp.deletedTimers, -1)
- // Look at this heap position again.
- i--
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
}
case timerModifiedEarlier, timerModifiedLater:
if atomic.Cas(&t.status, s, timerMoving) {
@@ -691,10 +694,11 @@ func adjusttimers(pp *p, now int64) {
// We don't add it back yet because the
// heap manipulation could cause our
// loop to skip some other timer.
- dodeltimer(pp, i)
+ changed := dodeltimer(pp, i)
moved = append(moved, t)
- // Look at this heap position again.
- i--
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
}
case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
badTimer()
@@ -1044,7 +1048,10 @@ func timeSleepUntil() (int64, *p) {
// "panic holding locks" message. Instead, we panic while not
// holding a lock.
-func siftupTimer(t []*timer, i int) {
+// siftupTimer puts the timer at position i in the right place
+// in the heap by moving it up toward the top of the heap.
+// It returns the smallest changed index.
+func siftupTimer(t []*timer, i int) int {
if i >= len(t) {
badTimer()
}
@@ -1064,8 +1071,11 @@ func siftupTimer(t []*timer, i int) {
if tmp != t[i] {
t[i] = tmp
}
+ return i
}
+// siftdownTimer puts the timer at position i in the right place
+// in the heap by moving it down toward the bottom of the heap.
func siftdownTimer(t []*timer, i int) {
n := len(t)
if i >= n {
diff --git a/src/runtime/time_linux_amd64.s b/src/runtime/time_linux_amd64.s
index c88e92bd0c..67cfdd8fdf 100644
--- a/src/runtime/time_linux_amd64.s
+++ b/src/runtime/time_linux_amd64.s
@@ -12,14 +12,11 @@
#define SYS_clock_gettime 228
// func time.now() (sec int64, nsec int32, mono int64)
-TEXT time·now(SB),NOSPLIT,$16-24
+TEXT time·now<ABIInternal>(SB),NOSPLIT,$16-24
MOVQ SP, R12 // Save old SP; R12 unchanged by C code.
MOVQ g_m(R14), BX // BX unchanged by C code.
- // Store CLOCK_REALTIME results directly to return space.
- LEAQ sec+0(FP), SI
-
// Set vdsoPC and vdsoSP for SIGPROF traceback.
// Save the old values on stack and restore them on exit,
// so this function is reentrant.
@@ -28,9 +25,10 @@ TEXT time·now(SB),NOSPLIT,$16-24
MOVQ CX, 0(SP)
MOVQ DX, 8(SP)
- MOVQ -8(SI), CX // Sets CX to function return address.
+ LEAQ sec+0(FP), DX
+ MOVQ -8(DX), CX // Sets CX to function return address.
MOVQ CX, m_vdsoPC(BX)
- MOVQ SI, m_vdsoSP(BX)
+ MOVQ DX, m_vdsoSP(BX)
CMPQ R14, m_curg(BX) // Only switch if on curg.
JNE noswitch
@@ -39,10 +37,11 @@ TEXT time·now(SB),NOSPLIT,$16-24
MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
noswitch:
- SUBQ $16, SP // Space for monotonic time results
+ SUBQ $32, SP // Space for two time results
ANDQ $~15, SP // Align for C code
MOVL $0, DI // CLOCK_REALTIME
+ LEAQ 16(SP), SI
MOVQ runtime·vdsoClockgettimeSym(SB), AX
CMPQ AX, $0
JEQ fallback
@@ -54,25 +53,27 @@ noswitch:
CALL AX
ret:
- MOVQ 0(SP), AX // sec
- MOVQ 8(SP), DX // nsec
+ MOVQ 16(SP), AX // realtime sec
+ MOVQ 24(SP), DI // realtime nsec (moved to BX below)
+ MOVQ 0(SP), CX // monotonic sec
+ IMULQ $1000000000, CX
+ MOVQ 8(SP), DX // monotonic nsec
MOVQ R12, SP // Restore real SP
+
// Restore vdsoPC, vdsoSP
// We don't worry about being signaled between the two stores.
// If we are not in a signal handler, we'll restore vdsoSP to 0,
// and no one will care about vdsoPC. If we are in a signal handler,
// we cannot receive another signal.
- MOVQ 8(SP), CX
- MOVQ CX, m_vdsoSP(BX)
- MOVQ 0(SP), CX
- MOVQ CX, m_vdsoPC(BX)
+ MOVQ 8(SP), SI
+ MOVQ SI, m_vdsoSP(BX)
+ MOVQ 0(SP), SI
+ MOVQ SI, m_vdsoPC(BX)
- // sec is in AX, nsec in DX
- // return nsec in AX
- IMULQ $1000000000, AX
- ADDQ DX, AX
- MOVQ AX, mono+16(FP)
+ // set result registers; AX is already correct
+ MOVQ DI, BX
+ ADDQ DX, CX
RET
fallback: