void connectTransfer(void) // 환승역을 연결 { // 환승역 끼리 연결해야 한다는 사실 // 중복된 이름을 찾아 그 둘을 연결. mysubway *chain = map; mysubway *chain2 = map; while (chain->next != NULL) { chain2 = chain->next; while (chain2 != NULL) { if (strcmp(chain->name, chain2->name) == 0) { if (strcmp(chain->kind, chain2->kind) != 0) { addTrans(chain, chain2, 1); // printf("%s %s %s %s\n", chain->name, chain->kind, chain2->name, chain2->kind); } } chain2 = chain2->next; } chain = chain->next; } }
void addTrans(mysubway *chain, mysubway *chain2, int doReverse) { mysubway *fresh1, *fresh2; fresh1 = (mysubway *)malloc(sizeof(mysubway)); fresh2 = (mysubway *)malloc(sizeof(mysubway)); strcpy(fresh1->identity, chain->identity); strcpy(fresh2->identity, chain2->identity); strcpy(fresh1->kind, chain->kind); strcpy(fresh2->kind, chain2->kind); strcpy(fresh1->name, chain->name); strcpy(fresh2->name, chain2->name); fresh1->prev = fresh2->prev = NULL; fresh1->next = fresh2->next = NULL; fresh1->connect = fresh2->connect = NULL; fresh1->weight = fresh2->weight = 5; if (chain == NULL) { chain = fresh2; } else { mysubway *temp = chain; while (temp->connect != NULL) { temp = temp->connect; } temp->connect = fresh2; // printf("%s %s %s %s\n", chain->name, chain->kind, fresh2->name, fresh2->kind); } if (doReverse == 1) { addTrans(chain2, chain, 0); } }
//------------------------------------------------------------------------------------------------------------------------------- // 中间语言翻译 void translate(LinkQueue head,TransQueue &tr) { int Num=100; Tr_stack sq; sq.base=sq.top=NULL; word *ptr=head->front; while(ptr) { if(ptr->Class=="KEYWORD")//保留字 { if(ptr->Name=="while"||ptr->Name=="if") { Tr_push(sq,ptr->Name); } ptr=ptr->next; continue; } else if(ptr->Class=="IDEN")//iden 标识符 { string str1=ptr->Name; ptr=ptr->next; string ex=ptr->Name; int mark=Tr_judge(ex);//判断标识符下一字符为运算符或大小于跳转 if(mark==1) { ptr=ptr->next; string str2=ptr->Name; trans_ptr temp=new trans;//判断条件为真跳转语句 temp->num=Num++; temp->name.exp1="j"; temp->name.exp1.append(ex); temp->name.exp2=str1; temp->name.exp3=str2; char *c=new char; itoa(Num+1,c,10); string svai(c); temp->name.exp4=svai; temp->next=NULL; temp->pre=NULL; addTrans(tr,temp);//讲四元式结点加入到四元式链表中 trans_ptr next=new trans;//判断条件为假跳转语句 next->num=Num++; next->name.exp1="j"; next->name.exp2="_"; next->name.exp3="_"; next->name.exp4=sq.top->keyword; next->next=NULL; next->pre=NULL; addTrans(tr,next); } else if(mark==2) { ptr=ptr->next; if(ptr->next->Name==";")//表达式为赋值语句 { trans_ptr temp=new trans; temp->num=Num++; temp->name.exp1=ex; temp->name.exp2=ptr->Name; temp->name.exp3="_"; temp->name.exp4=str1; temp->next=NULL; temp->pre=NULL; addTrans(tr,temp); continue; } //运算语句 Tr_stack s1,s2; s1.base=s1.top=NULL; s2.base=s2.top=NULL; while(ptr->Name!=";")//讲运算符和标识符分别入栈 { if(ptr->Class=="IDEN") { Tr_push(s1,ptr->Name); } else { Tr_push(s2,ptr->Name); } ptr=ptr->next; } while(s2.top)//运算符栈为空 则运算结束 { string vai1=Tr_pop(s2); string vai2=Tr_pop(s1); string vai3=Tr_pop(s1); trans_ptr temp=new trans; temp->num=Num++; temp->name.exp1=vai1; temp->name.exp2=vai3; temp->name.exp3=vai2; temp->name.exp4="t"; temp->pre=NULL; temp->next=NULL; addTrans(tr,temp); } trans_ptr temp=new trans;//运算结果赋值 temp->num=Num++; temp->name.exp1=ex; temp->name.exp2="t"; temp->name.exp3="_"; temp->name.exp4=str1; temp->pre=NULL; temp->next=NULL; addTrans(tr,temp); } ptr=ptr->next; continue; } else if(ptr->Name=="}")//遇到作用域结束,即if或while结束 回填条件为假跳转地址 { if(!sq.top) { ptr=ptr->next; continue; } string str=Tr_pop(sq); trans_ptr temp=tr.rear; while(temp->name.exp4!=str)//想上找条件为假语句位置 { temp=temp->pre; } if(str=="if")//if语句 只回填当前位置到 条件为假语句 { char *c=new char; itoa(Num,c,10); string s(c); temp->name.exp4=s; } else //while还包括 添加一条跳回判断条件的语句 { char *ch=new char; trans_ptr ret=new trans; ret->num=Num++; ret->name.exp1="j"; ret->name.exp2=ret->name.exp3="_"; itoa(temp->pre->num,ch,10); string ss(ch); ret->name.exp4=ss; itoa(Num,ch,10); string ss1(ch); temp->name.exp4=ss1; ret->next=NULL; ret->pre=NULL; addTrans(tr,ret); } } ptr=ptr->next; } }
void OfflineTransData::loadTCData(string dumpDir) { string fileName = dumpDir + tcDataFileName; char buf[BUFLEN+1]; char funcName[BUFLEN+1]; gzFile file = gzopen(fileName.c_str(), "r"); if (!file) { error("Error opening file " + fileName); } // read header info READ("repo_schema = %s", repoSchema); READ("ahot.base = %p", &ahotBase); READ("ahot.frontier = %p", &ahotFrontier); READ("a.base = %p", &aBase); READ("a.frontier = %p", &aFrontier); READ("aprof.base = %p", &aprofBase); READ("aprof.frontier = %p", &aprofFrontier); READ("acold.base = %p", &coldBase); READ("acold.frontier = %p", &coldFrontier); READ("afrozen.base = %p", &frozenBase); READ("afrozen.frontier = %p", &frozenFrontier); READ_EMPTY(); READ("total_translations = %u", &nTranslations); READ_EMPTY(); // Read translations for (uint32_t tid = 0; tid < nTranslations; tid++) { TransRec tRec; MD5Str md5Str; uint32_t kind; FuncId funcId; int32_t resumed; uint64_t profCount; size_t numBCMappings = 0; size_t numBlocks = 0; size_t numGuards = 0; READ("Translation %u {", &tRec.id); READ(" src.md5 = %s", md5Str); tRec.md5 = MD5(md5Str); READ(" src.funcId = %u", &funcId); READ(" src.funcName = %s", funcName); tRec.funcName = funcName; READ(" src.resumed = %d", &resumed); READ(" src.bcStart = %d", &tRec.bcStart); READ(" src.blocks = %lu", &numBlocks); for (size_t i = 0; i < numBlocks; ++i) { MD5Str md5Tmp; Offset start = kInvalidOffset; Offset past = kInvalidOffset; if (gzgets(file, buf, BUFLEN) == Z_NULL || sscanf(buf, "%s %d %d", md5Tmp, &start, &past) != 3) { snprintf(buf, BUFLEN, "Error reading bytecode block #%lu at translation %u\n", i, tRec.id); error(buf); } tRec.blocks.emplace_back(TransRec::Block{MD5(md5Tmp), start, past}); } READ(" src.guards = %lu", &numGuards); for (size_t i = 0; i < numGuards; ++i) { char location[BUFLEN+1]; char type[BUFLEN+1]; if (gzgets(file, buf, BUFLEN) == Z_NULL || sscanf(buf, "%s :: %s", location, type) != 2) { snprintf(buf, BUFLEN, "Error reading guard #%lu at translation %u\n", i, tRec.id); error(buf); } tRec.guards.emplace_back(folly::to<std::string>( location, " :: ", type)); } READ(" kind = %u %*s", &kind); int isLLVM; READ(" isLLVM = %d", &isLLVM); tRec.isLLVM = isLLVM; int hasLoop; READ(" hasLoop = %d", &hasLoop); tRec.hasLoop = hasLoop; READ(" aStart = %p", (void**)&tRec.aStart); READ(" aLen = %x", &tRec.aLen); READ(" coldStart = %p", (void**)&tRec.acoldStart); READ(" coldLen = %x", &tRec.acoldLen); READ(" frozenStart = %p", (void**)&tRec.afrozenStart); READ(" frozenLen = %x", &tRec.afrozenLen); READ(" profCount = %" PRIu64 "", &profCount); READ(" bcMapping = %lu", &numBCMappings); for (size_t i = 0; i < numBCMappings; i++) { TransBCMapping bcMap; MD5Str md5Tmp; if (gzgets(file, buf, BUFLEN) == Z_NULL || sscanf(buf, "%s %d %p %p %p", md5Tmp, &bcMap.bcStart, (void**)&bcMap.aStart, (void**)&bcMap.acoldStart, (void**)&bcMap.afrozenStart) != 5) { snprintf(buf, BUFLEN, "Error reading bytecode mapping #%lu at translation %u\n", i, tRec.id); error(buf); } bcMap.md5 = MD5(md5Tmp); tRec.bcMapping.push_back(bcMap); } // push a sentinel bcMapping so that we can figure out stop offsets later on const TransBCMapping sentinel { tRec.md5, 0, tRec.aStart + tRec.aLen, tRec.acoldStart + tRec.acoldLen, tRec.afrozenStart + tRec.afrozenLen }; tRec.bcMapping.push_back(sentinel); READ_EMPTY(); READ_EMPTY(); tRec.src = SrcKey { funcId, tRec.bcStart, static_cast<bool>(resumed) }; tRec.kind = (TransKind)kind; always_assert(tid == tRec.id); addTrans(tRec, profCount); funcIds.insert(tRec.src.funcID()); if (tRec.aStart) { transAddrRanges.push_back( TransAddrRange(tRec.aStart, tRec.aStart + tRec.aLen - 1, tid)); addr2TransMap[tRec.aStart] = tid; } if (tRec.acoldStart) { transAddrRanges.push_back( TransAddrRange(tRec.acoldStart, tRec.acoldStart + tRec.acoldLen - 1, tid)); // If there's no code in 'a', then the entry must be in 'aCold' if (!tRec.aStart) { addr2TransMap[tRec.acoldStart] = tid; } } if (tRec.afrozenStart) { transAddrRanges.push_back( TransAddrRange(tRec.afrozenStart, tRec.afrozenStart + tRec.afrozenLen - 1, tid)); } } always_assert(nTranslations == translations.size()); sort(transAddrRanges.begin(), transAddrRanges.end()); gzclose(file); }