Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VMS_impls > VMS__MC_shared_impl
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 |
