~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/runtime/race_amd64.s

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-11-18 15:12:26 UTC
  • mfrom: (14.2.12 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20141118151226-zug7vn93mn3dtiz3
Tags: 2:1.3.2-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - Support co-installability with gccgo-go tool:
    - d/rules,golang-go.install: Rename bin/go -> bin/golang-go
    - d/golang-go.{postinst,prerm}: Install/remove /usr/bin/go using
      alternatives.
  - d/copyright: Amendments for full compiliance with copyright format.
  - d/control: Demote golang-go.tools to Suggests to support Ubuntu MIR.
  - dropped patches (now upstream):
    - d/p/issue27650045_40001_50001.diff
    - d/p/issue28050043_60001_70001.diff
    - d/p/issue54790044_100001_110001.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
// +build race
6
6
 
 
7
#include "zasm_GOOS_GOARCH.h"
 
8
#include "funcdata.h"
7
9
#include "../../cmd/ld/textflag.h"
8
10
 
 
11
// The following thunks allow calling the gcc-compiled race runtime directly
 
12
// from Go code without going all the way through cgo.
 
13
// First, it's much faster (up to 50% speedup for real Go programs).
 
14
// Second, it eliminates race-related special cases from cgocall and scheduler.
 
15
// Third, in long-term it will allow to remove cyclic runtime/race dependency on cmd/go.
 
16
 
 
17
// A brief recap of the amd64 calling convention.
 
18
// Arguments are passed in DI, SI, DX, CX, R8, R9, the rest is on stack.
 
19
// Callee-saved registers are: BX, BP, R12-R15.
 
20
// SP must be 16-byte aligned.
 
21
// On Windows:
 
22
// Arguments are passed in CX, DX, R8, R9, the rest is on stack.
 
23
// Callee-saved registers are: BX, BP, DI, SI, R12-R15.
 
24
// SP must be 16-byte aligned. Windows also requires "stack-backing" for the 4 register arguments:
 
25
// http://msdn.microsoft.com/en-us/library/ms235286.aspx
 
26
// We do not do this, because it seems to be intended for vararg/unprototyped functions.
 
27
// Gcc-compiled race runtime does not try to use that space.
 
28
 
 
29
#ifdef GOOS_windows
 
30
#define RARG0 CX
 
31
#define RARG1 DX
 
32
#define RARG2 R8
 
33
#define RARG3 R9
 
34
#else
 
35
#define RARG0 DI
 
36
#define RARG1 SI
 
37
#define RARG2 DX
 
38
#define RARG3 CX
 
39
#endif
 
40
 
 
41
// func runtime·raceread(addr uintptr)
 
42
// Called from instrumented code.
 
43
TEXT    runtime·raceread(SB), NOSPLIT, $0-8
 
44
        MOVQ    addr+0(FP), RARG1
 
45
        MOVQ    (SP), RARG2
 
46
        // void __tsan_read(ThreadState *thr, void *addr, void *pc);
 
47
        MOVQ    $__tsan_read(SB), AX
 
48
        JMP     racecalladdr<>(SB)
 
49
 
 
50
// func runtime·RaceRead(addr uintptr)
 
51
TEXT    runtime·RaceRead(SB), NOSPLIT, $0-8
 
52
        // This needs to be a tail call, because raceread reads caller pc.
 
53
        JMP     runtime·raceread(SB)
 
54
 
 
55
// void runtime·racereadpc(void *addr, void *callpc, void *pc)
 
56
TEXT    runtime·racereadpc(SB), NOSPLIT, $0-24
 
57
        MOVQ    addr+0(FP), RARG1
 
58
        MOVQ    callpc+8(FP), RARG2
 
59
        MOVQ    pc+16(FP), RARG3
 
60
        // void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
 
61
        MOVQ    $__tsan_read_pc(SB), AX
 
62
        JMP     racecalladdr<>(SB)
 
63
 
 
64
// func runtime·racewrite(addr uintptr)
 
65
// Called from instrumented code.
 
66
TEXT    runtime·racewrite(SB), NOSPLIT, $0-8
 
67
        MOVQ    addr+0(FP), RARG1
 
68
        MOVQ    (SP), RARG2
 
69
        // void __tsan_write(ThreadState *thr, void *addr, void *pc);
 
70
        MOVQ    $__tsan_write(SB), AX
 
71
        JMP     racecalladdr<>(SB)
 
72
 
 
73
// func runtime·RaceWrite(addr uintptr)
 
74
TEXT    runtime·RaceWrite(SB), NOSPLIT, $0-8
 
75
        // This needs to be a tail call, because racewrite reads caller pc.
 
76
        JMP     runtime·racewrite(SB)
 
77
 
 
78
// void runtime·racewritepc(void *addr, void *callpc, void *pc)
 
79
TEXT    runtime·racewritepc(SB), NOSPLIT, $0-24
 
80
        MOVQ    addr+0(FP), RARG1
 
81
        MOVQ    callpc+8(FP), RARG2
 
82
        MOVQ    cp+16(FP), RARG3
 
83
        // void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
 
84
        MOVQ    $__tsan_write_pc(SB), AX
 
85
        JMP     racecalladdr<>(SB)
 
86
 
 
87
// func runtime·racereadrange(addr, size uintptr)
 
88
// Called from instrumented code.
 
89
TEXT    runtime·racereadrange(SB), NOSPLIT, $0-16
 
90
        MOVQ    addr+0(FP), RARG1
 
91
        MOVQ    size+8(FP), RARG2
 
92
        MOVQ    (SP), RARG3
 
93
        // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
 
94
        MOVQ    $__tsan_read_range(SB), AX
 
95
        JMP     racecalladdr<>(SB)
 
96
 
 
97
// func runtime·RaceReadRange(addr, size uintptr)
 
98
TEXT    runtime·RaceReadRange(SB), NOSPLIT, $0-16
 
99
        // This needs to be a tail call, because racereadrange reads caller pc.
 
100
        JMP     runtime·racereadrange(SB)
 
101
 
 
102
// void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc)
 
103
TEXT    runtime·racereadrangepc1(SB), NOSPLIT, $0-24
 
104
        MOVQ    addr+0(FP), RARG1
 
105
        MOVQ    size+8(FP), RARG2
 
106
        MOVQ    pc+16(FP), RARG3
 
107
        // void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
 
108
        MOVQ    $__tsan_read_range(SB), AX
 
109
        JMP     racecalladdr<>(SB)
 
110
 
 
111
// func runtime·racewriterange(addr, size uintptr)
 
112
// Called from instrumented code.
 
113
TEXT    runtime·racewriterange(SB), NOSPLIT, $0-16
 
114
        MOVQ    addr+0(FP), RARG1
 
115
        MOVQ    size+8(FP), RARG2
 
116
        MOVQ    (SP), RARG3
 
117
        // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
 
118
        MOVQ    $__tsan_write_range(SB), AX
 
119
        JMP     racecalladdr<>(SB)
 
120
 
 
121
// func runtime·RaceWriteRange(addr, size uintptr)
 
122
TEXT    runtime·RaceWriteRange(SB), NOSPLIT, $0-16
 
123
        // This needs to be a tail call, because racewriterange reads caller pc.
 
124
        JMP     runtime·racewriterange(SB)
 
125
 
 
126
// void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc)
 
127
TEXT    runtime·racewriterangepc1(SB), NOSPLIT, $0-24
 
128
        MOVQ    addr+0(FP), RARG1
 
129
        MOVQ    size+8(FP), RARG2
 
130
        MOVQ    pc+16(FP), RARG3
 
131
        // void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
 
132
        MOVQ    $__tsan_write_range(SB), AX
 
133
        JMP     racecalladdr<>(SB)
 
134
 
 
135
// If addr (RARG1) is out of range, do nothing.
 
136
// Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
 
137
TEXT    racecalladdr<>(SB), NOSPLIT, $0-0
 
138
        get_tls(R12)
 
139
        MOVQ    g(R12), R14
 
140
        MOVQ    g_racectx(R14), RARG0   // goroutine context
 
141
        // Check that addr is within [arenastart, arenaend) or within [noptrdata, enoptrbss).
 
142
        CMPQ    RARG1, runtime·racearenastart(SB)
 
143
        JB      racecalladdr_data
 
144
        CMPQ    RARG1, runtime·racearenaend(SB)
 
145
        JB      racecalladdr_call
 
146
racecalladdr_data:
 
147
        CMPQ    RARG1, $noptrdata(SB)
 
148
        JB      racecalladdr_ret
 
149
        CMPQ    RARG1, $enoptrbss(SB)
 
150
        JAE     racecalladdr_ret
 
151
racecalladdr_call:
 
152
        MOVQ    AX, AX          // w/o this 6a miscompiles this function
 
153
        JMP     racecall<>(SB)
 
154
racecalladdr_ret:
 
155
        RET
 
156
 
9
157
// func runtime·racefuncenter(pc uintptr)
10
 
TEXT    runtime·racefuncenter(SB), NOSPLIT, $16-8
11
 
        MOVQ    DX, saved-8(SP) // save function entry context (for closures)
12
 
        MOVQ    pc+0(FP), DX
13
 
        MOVQ    DX, arg-16(SP)
14
 
        CALL    runtime·racefuncenter1(SB)
15
 
        MOVQ    saved-8(SP), DX
 
158
// Called from instrumented code.
 
159
TEXT    runtime·racefuncenter(SB), NOSPLIT, $0-8
 
160
        MOVQ    DX, R15         // save function entry context (for closures)
 
161
        get_tls(R12)
 
162
        MOVQ    g(R12), R14
 
163
        MOVQ    g_racectx(R14), RARG0   // goroutine context
 
164
        MOVQ    callpc+0(FP), RARG1
 
165
        // void __tsan_func_enter(ThreadState *thr, void *pc);
 
166
        MOVQ    $__tsan_func_enter(SB), AX
 
167
        CALL    racecall<>(SB)
 
168
        MOVQ    R15, DX // restore function entry context
 
169
        RET
 
170
 
 
171
// func runtime·racefuncexit()
 
172
// Called from instrumented code.
 
173
TEXT    runtime·racefuncexit(SB), NOSPLIT, $0-0
 
174
        get_tls(R12)
 
175
        MOVQ    g(R12), R14
 
176
        MOVQ    g_racectx(R14), RARG0   // goroutine context
 
177
        // void __tsan_func_exit(ThreadState *thr);
 
178
        MOVQ    $__tsan_func_exit(SB), AX
 
179
        JMP     racecall<>(SB)
 
180
 
 
181
// void runtime·racecall(void(*f)(...), ...)
 
182
// Calls C function f from race runtime and passes up to 4 arguments to it.
 
183
// The arguments are never heap-object-preserving pointers, so we pretend there are no arguments.
 
184
TEXT    runtime·racecall(SB), NOSPLIT, $0-0
 
185
        MOVQ    fn+0(FP), AX
 
186
        MOVQ    arg0+8(FP), RARG0
 
187
        MOVQ    arg1+16(FP), RARG1
 
188
        MOVQ    arg2+24(FP), RARG2
 
189
        MOVQ    arg3+32(FP), RARG3
 
190
        JMP     racecall<>(SB)
 
191
 
 
192
// Switches SP to g0 stack and calls (AX). Arguments already set.
 
193
TEXT    racecall<>(SB), NOSPLIT, $0-0
 
194
        get_tls(R12)
 
195
        MOVQ    m(R12), R13
 
196
        MOVQ    g(R12), R14
 
197
        // Switch to g0 stack.
 
198
        MOVQ    SP, R12         // callee-saved, preserved across the CALL
 
199
        MOVQ    m_g0(R13), R10
 
200
        CMPQ    R10, R14
 
201
        JE      racecall_cont   // already on g0
 
202
        MOVQ    (g_sched+gobuf_sp)(R10), SP
 
203
racecall_cont:
 
204
        ANDQ    $~15, SP        // alignment for gcc ABI
 
205
        CALL    AX
 
206
        MOVQ    R12, SP
 
207
        RET
 
208
 
 
209
// C->Go callback thunk that allows to call runtime·racesymbolize from C code.
 
210
// Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g.
 
211
// The overall effect of Go->C->Go call chain is similar to that of mcall.
 
212
TEXT    runtime·racesymbolizethunk(SB), NOSPLIT, $56-8
 
213
        // Save callee-saved registers (Go code won't respect that).
 
214
        // This is superset of darwin/linux/windows registers.
 
215
        PUSHQ   BX
 
216
        PUSHQ   BP
 
217
        PUSHQ   DI
 
218
        PUSHQ   SI
 
219
        PUSHQ   R12
 
220
        PUSHQ   R13
 
221
        PUSHQ   R14
 
222
        PUSHQ   R15
 
223
        // Set g = g0.
 
224
        get_tls(R12)
 
225
        MOVQ    m(R12), R13
 
226
        MOVQ    m_g0(R13), R14
 
227
        MOVQ    R14, g(R12)     // g = m->g0
 
228
        MOVQ    RARG0, 0(SP)    // func arg
 
229
        CALL    runtime·racesymbolize(SB)
 
230
        // All registers are smashed after Go code, reload.
 
231
        get_tls(R12)
 
232
        MOVQ    m(R12), R13
 
233
        MOVQ    m_curg(R13), R14
 
234
        MOVQ    R14, g(R12)     // g = m->curg
 
235
        // Restore callee-saved registers.
 
236
        POPQ    R15
 
237
        POPQ    R14
 
238
        POPQ    R13
 
239
        POPQ    R12
 
240
        POPQ    SI
 
241
        POPQ    DI
 
242
        POPQ    BP
 
243
        POPQ    BX
16
244
        RET