if s.IsBlank() {
return
}
- if compiling_runtime && s.Name == "getg" {
- // runtime.getg() is not a real function and so does
- // not get a funcsym.
+ if compiling_runtime && (s.Name == "getg" || s.Name == "getclosureptr") {
+ // runtime.getg() and getclosureptr are not real functions and so do not
+ // get funcsyms.
return
}
if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
return nil
},
all...)
+ add("runtime", "getclosureptr",
+ func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+ return s.newValue0(ssa.OpGetClosurePtr, s.f.Config.Types.Uintptr)
+ },
+ all...)
/******** runtime/internal/sys ********/
addF("runtime/internal/sys", "Ctz32",
return memhash(p, h, 16)
}
-// memhash_varlen is defined in assembly because it needs access
-// to the closure. It appears here to provide an argument
-// signature for the assembly routine.
-func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr
+//go:nosplit
+func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr {
+ ptr := getclosureptr()
+ size := *(*uintptr)(unsafe.Pointer(ptr + unsafe.Sizeof(h)))
+ return memhash(p, h, size)
+}
var algarray = [alg_max]typeAlg{
alg_NOEQ: {nil, nil},
TEXT runtime·emptyfunc(SB),0,$0-0
RET
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVL p+0(FP), AX
- MOVL h+4(FP), BX
- MOVL 4(DX), CX
- MOVL AX, 0(SP)
- MOVL BX, 4(SP)
- MOVL CX, 8(SP)
- CALL runtime·memhash(SB)
- MOVL 12(SP), AX
- MOVL AX, ret+8(FP)
- RET
-
// hash function using AES hardware instructions
TEXT runtime·aeshash(SB),NOSPLIT,$0-16
MOVL p+0(FP), AX // ptr to data
MOVQ AX, ret+0(FP)
RET
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$32-24
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVQ p+0(FP), AX
- MOVQ h+8(FP), BX
- MOVQ 8(DX), CX
- MOVQ AX, 0(SP)
- MOVQ BX, 8(SP)
- MOVQ CX, 16(SP)
- CALL runtime·memhash(SB)
- MOVQ 24(SP), AX
- MOVQ AX, ret+16(FP)
- RET
-
// hash function using AES hardware instructions
TEXT runtime·aeshash(SB),NOSPLIT,$0-32
MOVQ p+0(FP), AX // ptr to data
MOVQ AX, ret+0(FP)
RET
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$24-12
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVL p+0(FP), AX
- MOVL h+4(FP), BX
- MOVL 4(DX), CX
- MOVL AX, 0(SP)
- MOVL BX, 4(SP)
- MOVL CX, 8(SP)
- CALL runtime·memhash(SB)
- MOVL 16(SP), AX
- MOVL AX, ret+8(FP)
- RET
-
// hash function using AES hardware instructions
// For now, our one amd64p32 system (NaCl) does not
// support using AES instructions, so have not bothered to
MOVW $0, R0
MOVW (R0), R1
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVW p+0(FP), R0
- MOVW h+4(FP), R1
- MOVW 4(R7), R2
- MOVW R0, 4(R13)
- MOVW R1, 8(R13)
- MOVW R2, 12(R13)
- BL runtime·memhash(SB)
- MOVW 16(R13), R0
- MOVW R0, ret+8(FP)
- RET
-
// memequal(p, q unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$-4-13
MOVW a+0(FP), R1
B (ZR)
UNDEF
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVD p+0(FP), R3
- MOVD h+8(FP), R4
- MOVD 8(R26), R5
- MOVD R3, 8(RSP)
- MOVD R4, 16(RSP)
- MOVD R5, 24(RSP)
- BL runtime·memhash(SB)
- MOVD 32(RSP), R3
- MOVD R3, ret+16(FP)
- RET
-
// memequal(p, q unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$-8-25
MOVD a+0(FP), R1
MOVW (R0), R0
UNDEF
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVV p+0(FP), R1
- MOVV h+8(FP), R2
- MOVV 8(REGCTXT), R3
- MOVV R1, 8(R29)
- MOVV R2, 16(R29)
- MOVV R3, 24(R29)
- JAL runtime·memhash(SB)
- MOVV 32(R29), R1
- MOVV R1, ret+16(FP)
- RET
-
// AES hashing not implemented for mips64
TEXT runtime·aeshash(SB),NOSPLIT,$-8-0
MOVW (R0), R1
TEXT runtime·abort(SB),NOSPLIT,$0-0
UNDEF
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$16-12
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVW p+0(FP), R1
- MOVW h+4(FP), R2
- MOVW 4(REGCTXT), R3
- MOVW R1, 4(R29)
- MOVW R2, 8(R29)
- MOVW R3, 12(R29)
- JAL runtime·memhash(SB)
- MOVW 16(R29), R1
- MOVW R1, ret+8(FP)
- RET
-
// Not implemented.
TEXT runtime·aeshash(SB),NOSPLIT,$0
UNDEF
MOVD R3, ret+0(FP)
RET
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVD p+0(FP), R3
- MOVD h+8(FP), R4
- MOVD 8(R11), R5
- MOVD R3, FIXED_FRAME+0(R1)
- MOVD R4, FIXED_FRAME+8(R1)
- MOVD R5, FIXED_FRAME+16(R1)
- BL runtime·memhash(SB)
- MOVD FIXED_FRAME+24(R1), R3
- MOVD R3, ret+16(FP)
- RET
-
// AES hashing not implemented for ppc64
TEXT runtime·aeshash(SB),NOSPLIT|NOFRAME,$0-0
MOVW (R0), R1
MOVD R3, ret+0(FP)
RET
-// memhash_varlen(p unsafe.Pointer, h seed) uintptr
-// redirects to memhash(p, h, size) using the size
-// stored in the closure.
-TEXT runtime·memhash_varlen(SB),NOSPLIT,$40-24
- GO_ARGS
- NO_LOCAL_POINTERS
- MOVD p+0(FP), R3
- MOVD h+8(FP), R4
- MOVD 8(R12), R5
- MOVD R3, 8(R15)
- MOVD R4, 16(R15)
- MOVD R5, 24(R15)
- BL runtime·memhash(SB)
- MOVD 32(R15), R3
- MOVD R3, ret+16(FP)
- RET
-
// AES hashing not implemented for s390x
TEXT runtime·aeshash(SB),NOSPLIT|NOFRAME,$0-0
MOVW (R0), R15
return uintptr(argp) - sys.MinFrameSize
}
+// getg returns the pointer to the current closure.
+// getclosureptr can only be used in an assignment statement
+// at the entry of a function. Moreover, go:nosplit directive
+// must be specified at the declaration of caller function,
+// so that the function prolog does not clobber the closure register.
+// for example:
+//
+// //go:nosplit
+// func f(arg1, arg2, arg3 int) {
+// dx := getclosureptr()
+// }
+//
+// The compiler rewrites calls to this function into instructions that fetch the
+// pointer from a well-known register (DX on x86 architecture, etc.) directly.
+func getclosureptr() uintptr
+
//go:noescape
func asmcgocall(fn, arg unsafe.Pointer) int32