Skip to content

Commit

Permalink
cmd/gc: add //go:nowritebarrier to diagnose unintended write barriers
Browse files Browse the repository at this point in the history
//go:nowritebarrier can only be used in package runtime.
It does not disable write barriers; it is an assertion, checked
by the compiler, that the following function needs no write
barriers.

Change-Id: Id7978b779b66dc1feea39ee6bda9fd4d80280b7c
Reviewed-on: https://go-review.googlesource.com/1224
Reviewed-by: Rick Hudson <[email protected]>
  • Loading branch information
rsc committed Dec 12, 2014
1 parent 2fa657c commit 557a61d
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 138 deletions.
2 changes: 2 additions & 0 deletions src/cmd/gc/go.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ struct Node
uchar noescape; // func arguments do not escape
uchar nosplit; // func should not execute on separate stack
uchar builtin; // built-in name, like len or close
uchar nowritebarrier; // emit compiler error instead of write barrier
uchar walkdef;
uchar typecheck;
uchar local;
Expand Down Expand Up @@ -987,6 +988,7 @@ EXTERN int flag_race;
EXTERN int flag_largemodel;
EXTERN int noescape;
EXTERN int nosplit;
EXTERN int nowritebarrier;
EXTERN int debuglive;
EXTERN Link* ctxt;

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/gc/go.y
Original file line number Diff line number Diff line change
Expand Up @@ -1319,6 +1319,7 @@ xfndcl:
$$->endlineno = lineno;
$$->noescape = noescape;
$$->nosplit = nosplit;
$$->nowritebarrier = nowritebarrier;
funcbody($$);
}

Expand Down Expand Up @@ -1502,6 +1503,7 @@ xdcl_list:
nointerface = 0;
noescape = 0;
nosplit = 0;
nowritebarrier = 0;
}

vardcl_list:
Expand Down
6 changes: 6 additions & 0 deletions src/cmd/gc/lex.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,12 @@ getlinepragma(void)
nosplit = 1;
goto out;
}
if(strcmp(lexbuf, "go:nowritebarrier") == 0) {
if(!compiling_runtime)
yyerror("//go:nowritebarrier only allowed in runtime");
nowritebarrier = 1;
goto out;
}

out:
return c;
Expand Down
2 changes: 2 additions & 0 deletions src/cmd/gc/walk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2010,6 +2010,8 @@ applywritebarrier(Node *n, NodeList **init)
char name[32];

if(n->left && n->right && needwritebarrier(n->left, n->right)) {
if(curfn && curfn->nowritebarrier)
yyerror("write barrier prohibited");
t = n->left->type;
l = nod(OADDR, n->left, N);
l->etype = 1; // addr does not escape
Expand Down
Loading

0 comments on commit 557a61d

Please sign in to comment.