Go patch committed: Use gcWriteBarrier for pointer-shaped struct/array

Message ID CAOyqgcUT_tUJA_X8nozHkkBdXndvr_SM9OLeGNcfgDJZYQ3uUQ@mail.gmail.com
State New
Headers show
Series
  • Go patch committed: Use gcWriteBarrier for pointer-shaped struct/array
Related show

Commit Message

Ian Lance Taylor June 10, 2019, 8:35 p.m.
This patch by Cherry Zhang changes the Go frontend to use
gcWriteBarrier for pointer-shaped struct/array values.  If a
struct/array is pointer-shaped (i.e. having a single field that is
pointer-shaped), we can use gcWriteBarrier instead of typedmemmove for
the write barrier.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 272127)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-a32739aadf0c7a65fcd5d5b6d0a0d206bff24a4f
+3f7dcb98df3ce1d4e02d0072fd21e70dc08351db
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/wb.cc
===================================================================
--- gcc/go/gofrontend/wb.cc	(revision 272127)
+++ gcc/go/gofrontend/wb.cc	(working copy)
@@ -955,14 +955,21 @@  Gogo::assign_with_write_barrier(Function
       // fallthrough
 
     case Type::TYPE_STRUCT:
-      {
-        // TODO: split assignments for small struct/array?
-	rhs = Expression::make_unary(OPERATOR_AND, rhs, loc);
-	rhs->unary_expression()->set_does_not_escape();
-	call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
-				  Expression::make_type_descriptor(type, loc),
-				  lhs, rhs);
-      }
+      if (type->is_direct_iface_type())
+        {
+          rhs = Expression::unpack_direct_iface(rhs, loc);
+          rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc);
+          call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs);
+        }
+      else
+        {
+          // TODO: split assignments for small struct/array?
+          rhs = Expression::make_unary(OPERATOR_AND, rhs, loc);
+          rhs->unary_expression()->set_does_not_escape();
+          call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
+                                    Expression::make_type_descriptor(type, loc),
+                                    lhs, rhs);
+        }
       break;
     }