comparison ProcrContext.h @ 156:b86c54dfb19f

smaller Hists for malloc, free and plugin
author Merten Sach <msach@mailbox.tu-berlin.de>
date Thu, 06 Oct 2011 15:55:42 +0200
parents a49f02980151 521c75d64cef
children c1784868dcea
comparison
equal deleted inserted replaced
6:d761310d5427 5:eac5c550b72f
4 * 4 *
5 * Author: seanhalle@yahoo.com 5 * Author: seanhalle@yahoo.com
6 * 6 *
7 */ 7 */
8 8
9 #ifndef _SwitchAnimators_H 9 #ifndef _ProcrContext_H
10 #define _SwitchAnimators_H 10 #define _ProcrContext_H
11 #define __USE_GNU 11 #define _GNU_SOURCE
12 12
13 /*Isolating code for switching between animators within these macros -- at 13 void saveCoreLoopReturnAddr(void **returnAddress);
14 * some point will make switches to compile for 32 bit or for 64 bit, which
15 * having these isolated will make cleaner
16 *
17 *This also makes it easier to change architectures, at some point
18 *And it cleans the code up, having the ugly assembly out of the way
19 */
20 14
21 /*Originally, let GCC handle input and output variables, which 15 void switchToVP(VirtProcr *nextProcr);
22 * worked fine with -O0, but with -O3, it eliminated what it
23 * thought was un-used stores -- to fix this, am now hard-coding
24 * the offsets of the fields of VirtProcr and VMSMasterEnv data
25 * structs into the assembly for switching between VPs.
26 *To see what the offsets are, copy the following code to
27 * someplace, set compile to -O0 so it doesn't optimize, and
28 * set a break-point on the first line. In DDD or Eclipse, look
29 * at the disassembly to see what it compiled for the offsets.
30 *
31 void *foo;
32 foo = currPr->stackPtr; \
33 foo = currPr->framePtr; \
34 foo = currPr->nextInstrPt; \
35 foo = currPr->coreLoopStackPtr;
36 foo = currPr->coreLoopFramePtr;
37 foo = _VMSMasterEnv->coreLoopStartPt;
38 foo = _VMSMasterEnv->coreLoopEndPt;
39 foo = _VMSMasterEnv->masterLock;
40 16
41 * VirtProcr offsets: 17 void switchToCoreLoop(VirtProcr *nextProcr);
42 * 0xc stackPtr
43 * 0x10 framePtr
44 * 0x14 nextInstrPt
45 * 0x1c coreLoopFramePtr
46 * 0x20 coreLoopStackPtr
47 *
48 * _VMSMasterEnv offsets:
49 * 0x24 coreLoopStartPt
50 * 0x28 coreLoopEndPt
51 * 0x30 masterLock
52 *
53 *For reference on the switch-VP assembly, the %%eax, %%ebx, %%ecx are
54 * general purpose registers -- the "clobber" at the end tells GCC that the
55 * values in the listed registers are overwritten inside the assembly, so
56 * that GCC doesn't rely on keeping values in registers across the assembly.
57 *The "input" tells GCC to generate the assembly form of the variable name.
58 *The "%0" and "%1" mean the first and second items in the "input" list at
59 * the bottom, respectively. So, where %0 appears, GCC looks at the bottom,
60 * gets the first item it sees, generates the assembly for accessing that
61 * variable, and replaces %0 with that.
62 *
63 *%%ebp is the frame-ptr register and %%esp is the stack-ptr register
64 */
65 18
66 //=========================== MasterVP to CoreLoop ========================== 19 void masterSwitchToCoreLoop(VirtProcr *nextProcr);
67 //
68 //Save stack ptr and frame, restore CoreLoop's stack and frame,
69 // and clear the MasterLock
70 //GCC's -O3 messes with this -- go through generated -- protect somehow
71 //
72 #define masterSwitchToCoreLoop( masterPr ) \
73 void *stackPtrAddr, *framePtrAddr; \
74 volatile void *masterLockAddr; \
75 void *jmpPt, *coreLoopFramePtr, *coreLoopStackPtr; \
76 \
77 masterLockAddr = &(_VMSMasterEnv->masterLock); \
78 \
79 jmpPt = _VMSMasterEnv->coreLoopStartPt; \
80 coreLoopStackPtr = masterPr->coreLoopStackPtr; \
81 coreLoopFramePtr = masterPr->coreLoopFramePtr; \
82 \
83 asm volatile("mov %0, %%ecx; \
84 mov %1, %%ebx; \
85 mov %%ebx, %%eax; \
86 add $0x10, %%eax; \
87 movl %%esp, (%%eax); \
88 mov %%ebx, %%eax; \
89 add $0x14, %%eax; \
90 movl %%ebp, (%%eax); \
91 movl %2, %%eax; \
92 movl %3, %%esp; \
93 movl %4, %%ebp; \
94 movl $0x0, (%%ecx); \
95 jmp %%eax" \
96 /* outputs */ : "=g"(masterLockAddr) \
97 /* inputs */ : "g"(masterPr), "g" (jmpPt), "g" (coreLoopStackPtr), \
98 "g" (coreLoopFramePtr) \
99 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
100 );
101 20
102 // asm volatile("movl %0, %%eax; \ 21 void startVirtProcrFn();
103 movl %%esp, (%%eax); \
104 movl %1, %%eax; \
105 movl %%ebp, (%%eax); \
106 movl %2, %%ebx; \
107 movl %3, %%eax; \
108 movl %4, %%esp; \
109 movl %5, %%ebp; \
110 movl $0x0, (%%ebx); \
111 jmp %%eax;" \
112 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr), \
113 "=g"(masterLockAddr) \
114 /* inputs */ : "g" (jmpPt), "g"(coreLoopStackPtr), "g"(coreLoopFramePtr)\
115 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
116 );//can probably make clobber list empty -- but safe for now
117 22
23 void *asmTerminateCoreLoop(VirtProcr *currPr);
118 24
119 //=========================== SlaveVP to CoreLoop =========================== 25 #define flushRegisters() \
120 // 26 asm volatile ("":::"%rbx", "%r12", "%r13","%r14","%r15")
121 27
122 #define SwitchToCoreLoop( animatingPr ) \ 28 inline VirtProcr *
123 void *jmpPt, *coreLoopStackPtr; \ 29 create_procr_helper( VirtProcr *newPr, VirtProcrFnPtr fnPtr,
124 void *coreLoopFramePtr; \ 30 void *initialData, void *stackLocs );
125 \
126 jmpPt = _VMSMasterEnv->coreLoopStartPt; \
127 coreLoopStackPtr = animatingPr->coreLoopStackPtr; \
128 coreLoopFramePtr = animatingPr->coreLoopFramePtr; \
129 \
130 asm volatile("mov %0,%%ebx; \
131 mov %%ebx, %%eax; \
132 add $0x10, %%eax; \
133 movl %%esp, (%%eax); \
134 mov %%ebx, %%eax; \
135 add $0x14, %%eax; \
136 movl %%ebp, (%%eax); \
137 movl %1, %%eax; \
138 movl %2, %%esp; \
139 movl %3, %%ebp; \
140 jmp %%eax" \
141 /* outputs */ : \
142 /* inputs */ : "g"(animatingPr), "g" (jmpPt), "g" (coreLoopStackPtr), \
143 "g" (coreLoopFramePtr) \
144 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
145 );
146 31
147 /*Save the virt procr's stack and frame ptrs*/ \ 32 #endif /* _ProcrContext_H */
148 // asm volatile("movl %0, %%eax; \
149 movl %%esp, (%%eax); \
150 movl %1, %%eax; \
151 movl %%ebp, (%%eax) "\
152 /* outputs */ : "=g" (stackPtrAddr), "=g" (framePtrAddr) \
153 /* inputs */ : \
154 /* clobber */ : "%eax" \
155 ); \
156 \
157 /*restore coreloop's frame ptr, then jump back to "start" of core loop*/\
158 /*Note, GCC compiles to assembly that saves esp and ebp in the stack*/ \
159 /* frame -- so have to explicitly do assembly that saves to memory*/ \
160 asm volatile("movl %0, %%eax; \
161 movl %1, %%esp; \
162 movl %2, %%ebp; \
163 jmp %%eax " \
164 /* outputs */ : \
165 /* inputs */ : "m" (jmpPt), "m"(coreLoopStackPtr), "m"(coreLoopFramePtr)\
166 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi","%esi" \
167 );
168 //list everything as clobbered to force GCC to save all
169 // live vars that are in regs on stack before this
170 // assembly, so that stack pointer is correct, before jmp
171 33
172
173
174 //============================== CoreLoop to VP =============================
175 //
176 //Save the core loop's stack and frame pointers into virt procr struct
177 // then switch to stack ptr and frame ptr of virt procr & jmp to it
178 //This was a pain to get right because GCC converts the "(jmpPt)" to
179 // frame-relative mem-op -- so generated machine code first changed the
180 // frame pointer, then tried to jump to an addr stored on stack, which
181 // it accessed as an offset from frame-ptr! (wrong frame-ptr now)
182 //Explicitly loading into eax before changing frame-ptr fixed it
183 //Also, it turns "(currPr->coreLoopFramePtr)" into a temporary on the
184 // stack, so "movl %%ebp, %0" saves to the temp, NOT the data-struc!
185
186
187 //switch to virt procr's stack and frame ptr then jump to virt procr fn
188 /* VirtProcr offsets:
189 * 0xc stackPtr
190 * 0x10 framePtr
191 * 0x14 nextInstrPt
192 * 0x1c coreLoopFramePtr
193 * 0x20 coreLoopStackPtr
194 *
195 * _VMSMasterEnv offsets:
196 * 0x24 coreLoopStartPt
197 * 0x28 coreLoopEndPt
198 * 0x30 masterLock
199 */
200 #define SwitchToVP( currPr ) \
201 asm volatile("movl %0, %%ebx; \
202 movl %%esp, 0x20(%%ebx); \
203 movl %%ebp, 0x1c(%%ebx); \
204 movl 0x14(%%ebx), %%eax; \
205 movl 0x0c(%%ebx), %%esp; \
206 movl 0x10(%%ebx), %%ebp; \
207 jmp *%%eax" \
208 /* outputs */ : \
209 /* inputs */ : "g"(currPr) \
210 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
211 );
212
213 // void *stackPtr, *framePtr, *jmpPt; \
214 \
215 stackPtr = currPr->stackPtr; \
216 framePtr = currPr->framePtr; \
217 jmpPt = currPr->nextInstrPt; \
218 \
219 asm volatile("mov %0,%%ebx; \
220 mov %%ebx, %%eax; \
221 add $0x1c, %%eax; \
222 movl %%esp, (%%eax); \
223 mov %%ebx, %%eax; \
224 add $0x20, %%eax; \
225 movl %%ebp, (%%eax); \
226 movl %1, %%eax; \
227 movl %2, %%esp; \
228 movl %3, %%ebp; \
229 jmp %%eax" \
230 /* outputs */ : \
231 /* inputs */ : "g"(currPr), "g" (jmpPt), "g" (stackPtr), "g" (framePtr) \
232 /* clobber */ : "memory", "%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi" \
233 );
234
235
236 #endif /* _SwitchAnimators_H */
237