Commit c8a47c48 by Ian Lance Taylor

runtime: avoid write barriers when calling deferred function

    
    Calling a deferred function currently requires changing from a uintptr
    to the function code to a Go function value. That is done by setting
    the value of a func local variable using unsafe.Pointer. The local
    variable will always be on the stack. Adjust the code that sets the
    local variable to avoid generating a write barrier.
    
    A write barrier is never needed here. Also, for deferreturn, we must
    avoid write barriers entirely when called from a cgo function; that
    requires more than just this, but this is a start.
    
    The test for this is runtime tests that use the go tool; these are not
    currently run, but they will be in the future.
    
    Reviewed-on: https://go-review.googlesource.com/46455

From-SVN: r249559
parent b92e4dff
a459f1fdfe0bd365bf2def730e1529052c6487fd 73b14da15ec731837ce2a45db658142bfbf5fe22
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -194,7 +194,7 @@ func deferreturn(frame *bool) { ...@@ -194,7 +194,7 @@ func deferreturn(frame *bool) {
// The gc compiler does this using assembler // The gc compiler does this using assembler
// code in jmpdefer. // code in jmpdefer.
var fn func(unsafe.Pointer) var fn func(unsafe.Pointer)
*(**uintptr)(unsafe.Pointer(&fn)) = &pfn *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
fn(d.arg) fn(d.arg)
} }
...@@ -259,7 +259,7 @@ func checkdefer(frame *bool) { ...@@ -259,7 +259,7 @@ func checkdefer(frame *bool) {
gp._defer = d.link gp._defer = d.link
var fn func(unsafe.Pointer) var fn func(unsafe.Pointer)
*(**uintptr)(unsafe.Pointer(&fn)) = &pfn *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
fn(d.arg) fn(d.arg)
freedefer(d) freedefer(d)
...@@ -345,7 +345,7 @@ func Goexit() { ...@@ -345,7 +345,7 @@ func Goexit() {
if pfn != 0 { if pfn != 0 {
var fn func(unsafe.Pointer) var fn func(unsafe.Pointer)
*(**uintptr)(unsafe.Pointer(&fn)) = &pfn *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
fn(d.arg) fn(d.arg)
} }
...@@ -446,7 +446,7 @@ func gopanic(e interface{}) { ...@@ -446,7 +446,7 @@ func gopanic(e interface{}) {
if pfn != 0 { if pfn != 0 {
var fn func(unsafe.Pointer) var fn func(unsafe.Pointer)
*(**uintptr)(unsafe.Pointer(&fn)) = &pfn *(*uintptr)(unsafe.Pointer(&fn)) = uintptr(unsafe.Pointer(&pfn))
fn(d.arg) fn(d.arg)
if p.recovered { if p.recovered {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment