Skip to content

Commit

Permalink
all: merge dev.garbage (d1238958d4ae) into default branch
Browse files Browse the repository at this point in the history
When we start work on Gerrit, ppc64 and garbage collection
work will continue in the master branch, not the dev branches.

(We may still use dev branches for other things later, but
these are ready to be merged, and doing it now, before moving
to Git means we don't have to have dev branches working
in the Gerrit workflow on day one.)

TBR=rlh
CC=golang-codereviews
https://golang.org/cl/183140043
  • Loading branch information
rsc committed Dec 6, 2014
2 parents 09d92b6 + db40624 commit 31457ce
Show file tree
Hide file tree
Showing 43 changed files with 1,890 additions and 554 deletions.
4 changes: 2 additions & 2 deletions lib/codereview/codereview.py
Original file line number Diff line number Diff line change
Expand Up @@ -2024,13 +2024,13 @@ def submit(ui, repo, *pats, **opts):
# push to remote; if it fails for any reason, roll back
try:
new_heads = len(hg_heads(ui, repo).split())
if old_heads != new_heads and not (old_heads == 0 and new_heads == 1):
if cl.desc.find("create new branch") < 0 and old_heads != new_heads and not (old_heads == 0 and new_heads == 1):
# Created new head, so we weren't up to date.
need_sync()

# Push changes to remote. If it works, we're committed. If not, roll back.
try:
if hg_push(ui, repo):
if hg_push(ui, repo, new_branch=cl.desc.find("create new branch")>=0):
raise hg_util.Abort("push error")
except hg_error.Abort, e:
if e.message.find("push creates new heads") >= 0:
Expand Down
31 changes: 28 additions & 3 deletions src/cmd/gc/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ char *runtimeimport =
"func @\"\".printslice (? any)\n"
"func @\"\".printnl ()\n"
"func @\"\".printsp ()\n"
"func @\"\".printlock ()\n"
"func @\"\".printunlock ()\n"
"func @\"\".concatstring2 (? string, ? string) (? string)\n"
"func @\"\".concatstring3 (? string, ? string, ? string) (? string)\n"
"func @\"\".concatstring4 (? string, ? string, ? string, ? string) (? string)\n"
Expand Down Expand Up @@ -86,10 +88,33 @@ char *runtimeimport =
"func @\"\".writebarrierstring (@\"\".dst·1 *any, @\"\".src·2 any)\n"
"func @\"\".writebarrierslice (@\"\".dst·1 *any, @\"\".src·2 any)\n"
"func @\"\".writebarrieriface (@\"\".dst·1 *any, @\"\".src·2 any)\n"
"func @\"\".writebarrierfat2 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat3 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat4 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat01 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat10 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat11 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat0111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1000 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1001 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1010 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1011 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1100 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1101 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1110 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat1111 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
"func @\"\".writebarrierfat (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n"
"func @\"\".writebarriercopy (@\"\".typ·2 *byte, @\"\".dst·3 any, @\"\".src·4 any) (? int)\n"
"func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n"
"func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
"func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n"
Expand Down
1 change: 1 addition & 0 deletions src/cmd/gc/go.h
Original file line number Diff line number Diff line change
Expand Up @@ -1473,6 +1473,7 @@ void walk(Node *fn);
void walkexpr(Node **np, NodeList **init);
void walkexprlist(NodeList *l, NodeList **init);
void walkexprlistsafe(NodeList *l, NodeList **init);
void walkexprlistcheap(NodeList *l, NodeList **init);
void walkstmt(Node **np);
void walkstmtlist(NodeList *l);
Node* conv(Node*, Type*);
Expand Down
33 changes: 30 additions & 3 deletions src/cmd/gc/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func printeface(any)
func printslice(any)
func printnl()
func printsp()
func printlock()
func printunlock()

func concatstring2(string, string) string
func concatstring3(string, string, string) string
Expand Down Expand Up @@ -115,10 +117,35 @@ func writebarrieriface(dst *any, src any)
// The unused *byte argument makes sure that src is 2-pointer-aligned,
// which is the maximum alignment on NaCl amd64p32
// (and possibly on 32-bit systems if we start 64-bit aligning uint64s).
func writebarrierfat2(dst *any, _ *byte, src any)
func writebarrierfat3(dst *any, _ *byte, src any)
func writebarrierfat4(dst *any, _ *byte, src any)
// The bitmap in the name tells which words being copied are pointers.
func writebarrierfat01(dst *any, _ *byte, src any)
func writebarrierfat10(dst *any, _ *byte, src any)
func writebarrierfat11(dst *any, _ *byte, src any)
func writebarrierfat001(dst *any, _ *byte, src any)
func writebarrierfat010(dst *any, _ *byte, src any)
func writebarrierfat011(dst *any, _ *byte, src any)
func writebarrierfat100(dst *any, _ *byte, src any)
func writebarrierfat101(dst *any, _ *byte, src any)
func writebarrierfat110(dst *any, _ *byte, src any)
func writebarrierfat111(dst *any, _ *byte, src any)
func writebarrierfat0001(dst *any, _ *byte, src any)
func writebarrierfat0010(dst *any, _ *byte, src any)
func writebarrierfat0011(dst *any, _ *byte, src any)
func writebarrierfat0100(dst *any, _ *byte, src any)
func writebarrierfat0101(dst *any, _ *byte, src any)
func writebarrierfat0110(dst *any, _ *byte, src any)
func writebarrierfat0111(dst *any, _ *byte, src any)
func writebarrierfat1000(dst *any, _ *byte, src any)
func writebarrierfat1001(dst *any, _ *byte, src any)
func writebarrierfat1010(dst *any, _ *byte, src any)
func writebarrierfat1011(dst *any, _ *byte, src any)
func writebarrierfat1100(dst *any, _ *byte, src any)
func writebarrierfat1101(dst *any, _ *byte, src any)
func writebarrierfat1110(dst *any, _ *byte, src any)
func writebarrierfat1111(dst *any, _ *byte, src any)

func writebarrierfat(typ *byte, dst *any, src *any)
func writebarriercopy(typ *byte, dst any, src any) int

func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
Expand Down
6 changes: 4 additions & 2 deletions src/cmd/gc/typecheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -2891,15 +2891,17 @@ typecheckas(Node *n)
case OSLICE3:
case OSLICESTR:
// For x = x[0:y], x can be updated in place, without touching pointer.
if(samesafeexpr(n->left, n->right->left) && (n->right->right->left == N || iszero(n->right->right->left)))
// TODO(rsc): Reenable once it is actually updated in place without touching the pointer.
if(0 && samesafeexpr(n->left, n->right->left) && (n->right->right->left == N || iszero(n->right->right->left)))
n->right->reslice = 1;
break;

case OAPPEND:
// For x = append(x, ...), x can be updated in place when there is capacity,
// without touching the pointer; otherwise the emitted code to growslice
// can take care of updating the pointer, and only in that case.
if(n->right->list != nil && samesafeexpr(n->left, n->right->list->n))
// TODO(rsc): Reenable once the emitted code does update the pointer.
if(0 && n->right->list != nil && samesafeexpr(n->left, n->right->list->n))
n->right->reslice = 1;
break;
}
Expand Down
63 changes: 55 additions & 8 deletions src/cmd/gc/walk.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <libc.h>
#include "go.h"
#include "../ld/textflag.h"
#include "../../runtime/mgc0.h"

static Node* walkprint(Node*, NodeList**);
static Node* writebarrierfn(char*, Type*, Type*);
Expand Down Expand Up @@ -362,6 +363,15 @@ walkexprlistsafe(NodeList *l, NodeList **init)
}
}

void
walkexprlistcheap(NodeList *l, NodeList **init)
{
for(; l; l=l->next) {
l->n = cheapexpr(l->n, init);
walkexpr(&l->n, init);
}
}

void
walkexpr(Node **np, NodeList **init)
{
Expand Down Expand Up @@ -1771,6 +1781,11 @@ walkprint(Node *nn, NodeList **init)
calls = nil;
notfirst = 0;

// Hoist all the argument evaluation up before the lock.
walkexprlistcheap(all, init);

calls = list(calls, mkcall("printlock", T, init));

for(l=all; l; l=l->next) {
if(notfirst) {
calls = list(calls, mkcall("printsp", T, init));
Expand Down Expand Up @@ -1851,6 +1866,9 @@ walkprint(Node *nn, NodeList **init)

if(op == OPRINTN)
calls = list(calls, mkcall("printnl", T, nil));

calls = list(calls, mkcall("printunlock", T, init));

typechecklist(calls, Etop);
walkexprlist(calls, init);

Expand Down Expand Up @@ -1987,6 +2005,9 @@ applywritebarrier(Node *n, NodeList **init)
{
Node *l, *r;
Type *t;
vlong x;
static Bvec *bv;
char name[32];

if(n->left && n->right && needwritebarrier(n->left, n->right)) {
t = n->left->type;
Expand All @@ -2004,14 +2025,35 @@ applywritebarrier(Node *n, NodeList **init)
} else if(isinter(t)) {
n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init,
l, n->right);
} else if(t->width == 2*widthptr) {
n = mkcall1(writebarrierfn("writebarrierfat2", t, n->right->type), T, init,
l, nodnil(), n->right);
} else if(t->width == 3*widthptr) {
n = mkcall1(writebarrierfn("writebarrierfat3", t, n->right->type), T, init,
l, nodnil(), n->right);
} else if(t->width == 4*widthptr) {
n = mkcall1(writebarrierfn("writebarrierfat4", t, n->right->type), T, init,
} else if(t->width <= 4*widthptr) {
x = 0;
if(bv == nil)
bv = bvalloc(BitsPerPointer*4);
bvresetall(bv);
twobitwalktype1(t, &x, bv);
// The bvgets are looking for BitsPointer in successive slots.
enum {
PtrBit = 1,
};
if(BitsPointer != (1<<PtrBit))
fatal("wrong PtrBit");
switch(t->width/widthptr) {
default:
fatal("found writebarrierfat for %d-byte object of type %T", (int)t->width, t);
case 2:
snprint(name, sizeof name, "writebarrierfat%d%d",
bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit));
break;
case 3:
snprint(name, sizeof name, "writebarrierfat%d%d%d",
bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit));
break;
case 4:
snprint(name, sizeof name, "writebarrierfat%d%d%d%d",
bvget(bv, PtrBit), bvget(bv, BitsPerPointer+PtrBit), bvget(bv, 2*BitsPerPointer+PtrBit), bvget(bv, 3*BitsPerPointer+PtrBit));
break;
}
n = mkcall1(writebarrierfn(name, t, n->right->type), T, init,
l, nodnil(), n->right);
} else {
r = n->right;
Expand Down Expand Up @@ -2873,6 +2915,11 @@ copyany(Node *n, NodeList **init, int runtimecall)
{
Node *nl, *nr, *nfrm, *nto, *nif, *nlen, *nwid, *fn;
NodeList *l;

if(haspointers(n->left->type->type)) {
fn = writebarrierfn("writebarriercopy", n->left->type, n->right->type);
return mkcall1(fn, n->type, init, typename(n->left->type->type), n->left, n->right);
}

if(runtimecall) {
if(n->right->type->etype == TSTRING)
Expand Down
20 changes: 20 additions & 0 deletions src/runtime/asm_386.s
Original file line number Diff line number Diff line change
Expand Up @@ -2285,3 +2285,23 @@ TEXT runtime·getg(SB),NOSPLIT,$0-4
MOVL AX, ret+0(FP)
RET

TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT0 (AX)
RET

TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT1 (AX)
RET


TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT2 (AX)
RET

TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHNTA (AX)
RET
20 changes: 20 additions & 0 deletions src/runtime/asm_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -2228,3 +2228,23 @@ TEXT runtime·getg(SB),NOSPLIT,$0-8
MOVQ g(CX), AX
MOVQ AX, ret+0(FP)
RET

TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
MOVQ addr+0(FP), AX
PREFETCHT0 (AX)
RET

TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
MOVQ addr+0(FP), AX
PREFETCHT1 (AX)
RET

TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
MOVQ addr+0(FP), AX
PREFETCHT2 (AX)
RET

TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
MOVQ addr+0(FP), AX
PREFETCHNTA (AX)
RET
21 changes: 21 additions & 0 deletions src/runtime/asm_amd64p32.s
Original file line number Diff line number Diff line change
Expand Up @@ -1079,3 +1079,24 @@ TEXT runtime·getg(SB),NOSPLIT,$0-4
MOVL g(CX), AX
MOVL AX, ret+0(FP)
RET

TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT0 (AX)
RET

TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT1 (AX)
RET


TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHT2 (AX)
RET

TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
MOVL addr+0(FP), AX
PREFETCHNTA (AX)
RET
12 changes: 12 additions & 0 deletions src/runtime/asm_arm.s
Original file line number Diff line number Diff line change
Expand Up @@ -1320,3 +1320,15 @@ TEXT runtime·goexit(SB),NOSPLIT,$-4-0
TEXT runtime·getg(SB),NOSPLIT,$-4-4
MOVW g, ret+0(FP)
RET

TEXT runtime·prefetcht0(SB),NOSPLIT,$0-4
RET

TEXT runtime·prefetcht1(SB),NOSPLIT,$0-4
RET

TEXT runtime·prefetcht2(SB),NOSPLIT,$0-4
RET

TEXT runtime·prefetchnta(SB),NOSPLIT,$0-4
RET
12 changes: 12 additions & 0 deletions src/runtime/asm_ppc64x.s
Original file line number Diff line number Diff line change
Expand Up @@ -977,3 +977,15 @@ TEXT runtime·goexit(SB),NOSPLIT,$-8-0
TEXT runtime·getg(SB),NOSPLIT,$-8-8
MOVD g, ret+0(FP)
RETURN

TEXT runtime·prefetcht0(SB),NOSPLIT,$0-8
RETURN

TEXT runtime·prefetcht1(SB),NOSPLIT,$0-8
RETURN

TEXT runtime·prefetcht2(SB),NOSPLIT,$0-8
RETURN

TEXT runtime·prefetchnta(SB),NOSPLIT,$0-8
RETURN
2 changes: 1 addition & 1 deletion src/runtime/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var Exitsyscall = exitsyscall
var LockedOSThread = lockedOSThread

type LFNode struct {
Next *LFNode
Next uint64
Pushcnt uintptr
}

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/heapdump.go
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ func dumpobjs() {
if n > uintptr(len(freemark)) {
gothrow("freemark array doesn't have enough entries")
}
for l := s.freelist; l != nil; l = l.next {
freemark[(uintptr(unsafe.Pointer(l))-p)/size] = true
for l := s.freelist; l.ptr() != nil; l = l.ptr().next {
freemark[(uintptr(l)-p)/size] = true
}
for j := uintptr(0); j < n; j, p = j+1, p+size {
if freemark[j] {
Expand Down
10 changes: 3 additions & 7 deletions src/runtime/lfstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func lfstackpush(head *uint64, node *lfnode) {
}
for {
old := atomicload64(head)
node.next, _ = lfstackUnpack(old)
node.next = old
if cas64(head, old, new) {
break
}
Expand All @@ -32,12 +32,8 @@ func lfstackpop(head *uint64) unsafe.Pointer {
return nil
}
node, _ := lfstackUnpack(old)
node2 := (*lfnode)(atomicloadp(unsafe.Pointer(&node.next)))
new := uint64(0)
if node2 != nil {
new = lfstackPack(node2, node2.pushcnt)
}
if cas64(head, old, new) {
next := atomicload64(&node.next)
if cas64(head, old, next) {
return unsafe.Pointer(node)
}
}
Expand Down
Loading

0 comments on commit 31457ce

Please sign in to comment.