1 #include "xi-Message.h"
7 static const char* CIMsgClassAnsi =
10 " static int __idx;\n"
11 " void* operator new(size_t, void*p) { return p; }\n"
12 " void* operator new(size_t);\n"
13 " void* operator new(size_t, int*, const int);\n"
14 " void* operator new(size_t, int*, const int, const GroupDepNum);\n"
15 " void* operator new(size_t, int*);\n"
16 "#if CMK_MULTIPLE_DELETE\n"
17 " void operator delete(void*p, void*){dealloc(p);}\n"
18 " void operator delete(void*p){dealloc(p);}\n"
19 " void operator delete(void*p, int*, const int){dealloc(p);}\n"
20 " void operator delete(void*p, int*, const int, const GroupDepNum){dealloc(p);}\n"
21 " void operator delete(void*p, int*){dealloc(p);}\n"
23 " void operator delete(void*p, size_t){dealloc(p);}\n"
24 " static void* alloc(int,size_t, int*, int, GroupDepNum);\n"
25 " static void dealloc(void *p);\n";
27 Message::Message(int l, NamedType* t, MsgVarList* mv) : type(t), mvlist(mv) {
32 const char* Message::proxyPrefix(void) { return Prefix::Message; }
34 void Message::genAllocDecl(XStr& str) {
38 if (templat) templat->genVars(mtype);
39 str << CIMsgClassAnsi;
40 str << " CMessage_" << mtype << "();\n";
41 str << " static void *pack(" << mtype << " *p);\n";
42 str << " static " << mtype << "* unpack(void* p);\n";
45 str << " void *operator new(size_t";
46 for (i = 0; i < num; i++) str << ", int";
49 str << " void *operator new(size_t, ";
50 for (i = 0; i < num; i++) str << "int, ";
51 str << "const int);\n";
52 str << " void *operator new(size_t, ";
55 str << "const int, const GroupDepNum);\n";
56 str << "#if CMK_MULTIPLE_DELETE\n";
58 str << " void operator delete(void *p";
59 for (i = 0; i < num; i++) str << ", int";
60 str << "){dealloc(p);}\n";
62 str << " void operator delete(void *p, ";
63 for (i = 0; i < num; i++) str << "int, ";
64 str << "const int){dealloc(p);}\n";
65 str << " void operator delete(void *p, ";
66 for (i = 0; i < num; i++) str << "int, ";
67 str << "const int, const GroupDepNum){dealloc(p);}\n";
71 const char GroupDepNumStruct[] =
72 "#ifndef GROUPDEPNUM_DECLARED\n"
73 "# define GROUPDEPNUM_DECLARED\n"
74 "struct GroupDepNum\n"
77 " explicit GroupDepNum(int g = 0) : groupDepNum{g} { }\n"
78 " operator int() const { return groupDepNum; }\n"
82 void Message::genDecls(XStr& str) {
84 ptype << proxyPrefix() << type;
85 if (type->isTemplated()) return;
86 str << GroupDepNumStruct;
90 if (templat) templat->genSpec(str);
94 if (templat) templat->genSpec(str);
95 str << "class " << ptype;
96 if (external || type->isTemplated()) {
100 str << ":public CkMessage";
104 if (!(external || type->isTemplated())) {
105 // generate register function
106 str << " static void __register(const char *s, size_t size, CkPackFnPtr pack, "
107 "CkUnpackFnPtr unpack) {\n";
108 str << " __idx = CkRegisterMsg(s, pack, unpack, dealloc, size);\n";
113 if (strncmp(type->getBaseName(), "MarshallMsg_", 12) == 0) {
117 str << "class " << type << " : public " << ptype << " {\n";
120 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
122 if (mv->isConditional() || mv->isArray()) {
126 str << " " << mv->type << " *" << mv->name << ";\n";
133 void Message::genDefs(XStr& str) {
134 int i, count, num = numVars();
135 int numArray = numArrays();
138 XStr ptype, mtype, tspec;
139 ptype << proxyPrefix() << type;
140 if (templat) templat->genVars(ptype);
142 if (templat) templat->genVars(mtype);
144 templat->genSpec(tspec);
152 templateGuardBegin(templat, str);
153 if (!(external || type->isTemplated())) {
155 str << tspec << "void *" << ptype << "::operator new(size_t s){\n";
156 str << " return " << mtype << "::alloc(__idx, s, 0, 0, GroupDepNum{});\n}\n";
157 // new (size_t, int*)
158 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz){\n";
159 str << " return " << mtype << "::alloc(__idx, s, sz, 0, GroupDepNum{});\n}\n";
160 // new (size_t, int*, priobits)
161 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
162 str << "const int pb){\n";
163 str << " return " << mtype << "::alloc(__idx, s, sz, pb, GroupDepNum{});\n}\n";
164 // new (size_t, int *, priobits, groupDepNum)
165 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
166 str << "const int pb, const GroupDepNum groupDepNum){\n";
167 str << " return " << mtype << "::alloc(__idx, s, sz, pb, groupDepNum);\n}\n";
168 // new (size_t, int, int, ..., int)
170 str << tspec << "void *" << ptype << "::operator new(size_t s";
171 for (i = 0; i < numArray; i++) str << ", int sz" << i;
173 str << " int sizes[" << numArray << "];\n";
174 for (i = 0; i < numArray; i++) str << " sizes[" << i << "] = sz" << i << ";\n";
175 str << " return " << mtype << "::alloc(__idx, s, sizes, 0, GroupDepNum{});\n";
178 // new (size_t, int, int, ..., int, priobits)
179 // degenerates to new(size_t, priobits) if no varsize
180 std::vector<MsgVar*> arrayVars;
181 str << tspec << "void *" << ptype << "::operator new(size_t s, ";
182 for (i = 0; i < numArray; i++) str << "int sz" << i << ", ";
183 str << "const int p) {\n";
185 str << " int sizes[" << numArray << "];\n";
186 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
189 str << " sizes[" << count << "] = sz" << count << ";\n";
191 arrayVars.push_back(mv);
195 str << " return " << mtype << "::alloc(__idx, s, " << (numArray > 0 ? "sizes" : "0")
196 << ", p, GroupDepNum{});\n";
198 // new (size_t, int, int, ..., int, priobits, groupDepNum)
199 // degenerates to new(size_t, priobits, groupDepNum) if no varsize
201 str << tspec << "void *"<< ptype << "::operator new(size_t s, ";
202 for(i=0;i<numArray;i++)
203 str << "int sz" << i << ", ";
204 str << "const int p, const GroupDepNum groupDepNum) {\n";
206 str << " int sizes[" << numArray << "];\n";
207 for(i=0, count=0, ml=mvlist ;i<num; i++, ml=ml->next) {
210 str << " sizes[" << count << "] = sz" << count << ";\n";
212 arrayVars.push_back(mv);
216 str << " return " << mtype << "::alloc(__idx, s, " << (numArray>0?"sizes":"0") << ", p, groupDepNum);\n";
219 // alloc(int, size_t, int*, priobits, groupDepNum)
220 str << tspec << "void* " << ptype;
221 str << "::alloc(int msgnum, size_t sz, int *sizes, int pb, GroupDepNum groupDepNum) {\n";
222 str << " CkpvAccess(_offsets)[0] = ALIGN_DEFAULT(sz);\n";
223 for (count = 0; count < numArray; count++) {
224 mv = arrayVars[count];
225 str << " if(sizes==0)\n";
226 str << " CkpvAccess(_offsets)[" << count + 1 << "] = CkpvAccess(_offsets)[0];\n";
228 str << " CkpvAccess(_offsets)[" << count + 1 << "] = CkpvAccess(_offsets)["
230 str << "ALIGN_DEFAULT(sizeof(" << mv->type << ")*sizes[" << count << "]);\n";
232 str << " return CkAllocMsg(msgnum, CkpvAccess(_offsets)[" << numArray << "], pb, groupDepNum);\n";
235 str << tspec << ptype << "::" << proxyPrefix() << type << "() {\n";
236 str << mtype << " *newmsg = (" << mtype << " *)this;\n";
237 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
240 str << " newmsg->" << mv->name << " = (" << mv->type << " *) ";
241 str << "((char *)newmsg + CkpvAccess(_offsets)[" << count << "]);\n";
247 int numCond = numConditional();
248 str << tspec << "void " << ptype << "::dealloc(void *p) {\n";
250 str << " " << mtype << " *msg = (" << mtype << "*) p;\n";
251 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
253 if (mv->isConditional()) {
254 if (mv->type->isPointer())
255 XLAT_ERROR_NOCOL("conditional variable cannot be a pointer", line);
256 str << " CkConditional *cond_" << mv->name
257 << " = static_cast<CkConditional*>(msg->" << mv->name << ");\n";
258 str << " if (cond_" << mv->name << "!=NULL) cond_" << mv->name
259 << "->deallocate();\n";
263 str << " CkFreeMsg(p);\n";
266 str << tspec << "void* " << ptype << "::pack(" << mtype << " *msg) {\n";
267 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
270 str << " msg->" << mv->name << " = (" << mv->type << " *) ";
271 str << "((char *)msg->" << mv->name << " - (char *)msg);\n";
275 str << " int impl_off[" << numCond + 1 << "];\n";
276 str << " impl_off[0] = UsrToEnv(msg)->getUsersize();\n";
277 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
279 if (mv->isConditional()) {
280 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
281 mv->type->print(str);
282 str << " " << mv->name << " */\n";
283 str << " PUP::sizer implP;\n";
284 str << " implP|*msg->" << mv->name << ";\n";
285 str << " impl_off[" << count + 1 << "] = impl_off[" << count
286 << "] + implP.size();\n";
287 str << " } else {\n";
288 str << " impl_off[" << count + 1 << "] = impl_off[" << count << "];\n";
293 str << " " << mtype << " *newmsg = (" << mtype << "*) CkAllocMsg(__idx, impl_off["
294 << numCond << "], UsrToEnv(msg)->getPriobits());\n";
295 str << " envelope *newenv = UsrToEnv(newmsg);\n";
296 str << " UInt newSize = newenv->getTotalsize();\n";
297 str << " CmiMemcpy(newenv, UsrToEnv(msg), impl_off[0]+sizeof(envelope));\n";
298 str << " newenv->setTotalsize(newSize);\n";
299 str << " if (UsrToEnv(msg)->getPriobits() > 0) CmiMemcpy(newenv->getPrioPtr(), "
300 "UsrToEnv(msg)->getPrioPtr(), newenv->getPrioBytes());\n";
301 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
303 if (mv->isConditional()) {
304 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
305 mv->type->print(str);
306 str << " " << mv->name << " */\n";
307 str << " newmsg->" << mv->name << " = (";
308 mv->type->print(str);
309 str << "*)(((char*)newmsg)+impl_off[" << count << "]);\n";
310 str << " PUP::toMem implP((void *)newmsg->" << mv->name << ");\n";
311 str << " implP|*msg->" << mv->name << ";\n";
312 str << " newmsg->" << mv->name << " = (" << mv->type
313 << "*) ((char *)newmsg->" << mv->name << " - (char *)newmsg);\n";
318 str << " CkFreeMsg(msg);\n";
319 str << " msg = newmsg;\n";
321 str << " return (void *) msg;\n}\n";
323 str << tspec << mtype << "* " << ptype << "::unpack(void* buf) {\n";
324 str << " " << mtype << " *msg = (" << mtype << " *) buf;\n";
325 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
328 str << " msg->" << mv->name << " = (" << mv->type << " *) ";
329 str << "((size_t)msg->" << mv->name << " + (char *)msg);\n";
333 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
335 if (mv->isConditional()) {
336 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
337 mv->type->print(str);
338 str << " " << mv->name << " */\n";
339 str << " PUP::fromMem implP((char*)msg + (size_t)msg->" << mv->name
341 str << " msg->" << mv->name << " = new " << mv->type << ";\n";
342 str << " implP|*msg->" << mv->name << ";\n";
348 str << " return msg;\n}\n";
351 if (!external && !type->isTemplated()) {
352 str << "int " << ptype << "::__idx=0;\n";
355 str << tspec << "int " << ptype << "::__idx=0;\n";
357 templateGuardEnd(str);
360 void Message::genReg(XStr& str) {
364 if (!templat && !external) {
365 XStr ptype, mtype, tspec;
366 ptype << proxyPrefix() << type;
367 str << ptype << "::__register(\"" << type << "\", sizeof(" << type << "),";
368 str << "(CkPackFnPtr) " << type << "::pack,";
369 str << "(CkUnpackFnPtr) " << type << "::unpack);\n";
373 void Message::print(XStr& str) {
374 if (external) str << "extern ";
375 if (templat) templat->genSpec(str);
382 void Message::printVars(XStr& str) {
390 int Message::numArrays(void) {
391 if (mvlist == 0) return 0;
393 MsgVarList* mv = mvlist;
394 for (int i = 0; i < mvlist->len(); ++i, mv = mv->next)
395 if (mv->msg_var->isArray()) count++;
399 int Message::numConditional(void) {
400 if (mvlist == 0) return 0;
402 MsgVarList* mv = mvlist;
403 for (int i = 0; i < mvlist->len(); ++i, mv = mv->next)
404 if (mv->msg_var->isConditional()) count++;
408 int Message::numVars(void) { return ((mvlist == 0) ? 0 : mvlist->len()); }
410 MsgVar::MsgVar(Type* t, const char* n, int c, int a)
411 : type(t), name(n), cond(c), array(a) {}
413 Type* MsgVar::getType() { return type; }
415 const char* MsgVar::getName() { return name; }
417 int MsgVar::isConditional() { return cond; }
419 int MsgVar::isArray() { return array; }
421 void MsgVar::print(XStr& str) {
422 str << (isConditional() ? "conditional " : "");
424 str << " " << name << (isArray() ? "[]" : "") << ";";
427 MsgVarList::MsgVarList(MsgVar* mv, MsgVarList* n) : msg_var(mv), next(n) {}
429 void MsgVarList::print(XStr& str) {
432 if (next) next->print(str);
435 int MsgVarList::len(void) { return (next == 0) ? 1 : (next->len() + 1); }