LLVM API Documentation
00001 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines a JITDwarfEmitter object that is used by the JIT to 00011 // write dwarf tables to memory. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "JIT.h" 00016 #include "JITDwarfEmitter.h" 00017 #include "llvm/Function.h" 00018 #include "llvm/ADT/DenseMap.h" 00019 #include "llvm/CodeGen/MachineCodeEmitter.h" 00020 #include "llvm/CodeGen/MachineFunction.h" 00021 #include "llvm/CodeGen/MachineLocation.h" 00022 #include "llvm/CodeGen/MachineModuleInfo.h" 00023 #include "llvm/ExecutionEngine/JITMemoryManager.h" 00024 #include "llvm/Target/TargetAsmInfo.h" 00025 #include "llvm/Target/TargetData.h" 00026 #include "llvm/Target/TargetInstrInfo.h" 00027 #include "llvm/Target/TargetFrameInfo.h" 00028 #include "llvm/Target/TargetMachine.h" 00029 #include "llvm/Target/TargetRegisterInfo.h" 00030 00031 using namespace llvm; 00032 00033 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : Jit(theJit) {} 00034 00035 00036 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F, 00037 MachineCodeEmitter& mce, 00038 unsigned char* StartFunction, 00039 unsigned char* EndFunction) { 00040 const TargetMachine& TM = F.getTarget(); 00041 TD = TM.getTargetData(); 00042 needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding(); 00043 stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection(); 00044 RI = TM.getRegisterInfo(); 00045 MCE = &mce; 00046 00047 unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction, 00048 EndFunction); 00049 00050 unsigned char* Result = 0; 00051 unsigned char* EHFramePtr = 0; 00052 00053 const std::vector<Function *> Personalities = MMI->getPersonalities(); 00054 EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]); 00055 00056 Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr, 00057 StartFunction, EndFunction, ExceptionTable); 00058 00059 return Result; 00060 } 00061 00062 00063 void 00064 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr, 00065 const std::vector<MachineMove> &Moves) const { 00066 unsigned PointerSize = TD->getPointerSize(); 00067 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ? 00068 PointerSize : -PointerSize; 00069 bool IsLocal = false; 00070 unsigned BaseLabelID = 0; 00071 00072 for (unsigned i = 0, N = Moves.size(); i < N; ++i) { 00073 const MachineMove &Move = Moves[i]; 00074 unsigned LabelID = Move.getLabelID(); 00075 00076 if (LabelID) { 00077 LabelID = MMI->MappedLabel(LabelID); 00078 00079 // Throw out move if the label is invalid. 00080 if (!LabelID) continue; 00081 } 00082 00083 intptr_t LabelPtr = 0; 00084 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID); 00085 00086 const MachineLocation &Dst = Move.getDestination(); 00087 const MachineLocation &Src = Move.getSource(); 00088 00089 // Advance row if new location. 00090 if (BaseLabelPtr && LabelID && (BaseLabelID != LabelID || !IsLocal)) { 00091 MCE->emitByte(dwarf::DW_CFA_advance_loc4); 00092 MCE->emitInt32(LabelPtr - BaseLabelPtr); 00093 00094 BaseLabelID = LabelID; 00095 BaseLabelPtr = LabelPtr; 00096 IsLocal = true; 00097 } 00098 00099 // If advancing cfa. 00100 if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { 00101 if (!Src.isReg()) { 00102 if (Src.getReg() == MachineLocation::VirtualFP) { 00103 MCE->emitByte(dwarf::DW_CFA_def_cfa_offset); 00104 } else { 00105 MCE->emitByte(dwarf::DW_CFA_def_cfa); 00106 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true)); 00107 } 00108 00109 int Offset = -Src.getOffset(); 00110 00111 MCE->emitULEB128Bytes(Offset); 00112 } else { 00113 assert(0 && "Machine move no supported yet."); 00114 } 00115 } else if (Src.isReg() && 00116 Src.getReg() == MachineLocation::VirtualFP) { 00117 if (Dst.isReg()) { 00118 MCE->emitByte(dwarf::DW_CFA_def_cfa_register); 00119 MCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true)); 00120 } else { 00121 assert(0 && "Machine move no supported yet."); 00122 } 00123 } else { 00124 unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true); 00125 int Offset = Dst.getOffset() / stackGrowth; 00126 00127 if (Offset < 0) { 00128 MCE->emitByte(dwarf::DW_CFA_offset_extended_sf); 00129 MCE->emitULEB128Bytes(Reg); 00130 MCE->emitSLEB128Bytes(Offset); 00131 } else if (Reg < 64) { 00132 MCE->emitByte(dwarf::DW_CFA_offset + Reg); 00133 MCE->emitULEB128Bytes(Offset); 00134 } else { 00135 MCE->emitByte(dwarf::DW_CFA_offset_extended); 00136 MCE->emitULEB128Bytes(Reg); 00137 MCE->emitULEB128Bytes(Offset); 00138 } 00139 } 00140 } 00141 } 00142 00143 /// SharedTypeIds - How many leading type ids two landing pads have in common. 00144 static unsigned SharedTypeIds(const LandingPadInfo *L, 00145 const LandingPadInfo *R) { 00146 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 00147 unsigned LSize = LIds.size(), RSize = RIds.size(); 00148 unsigned MinSize = LSize < RSize ? LSize : RSize; 00149 unsigned Count = 0; 00150 00151 for (; Count != MinSize; ++Count) 00152 if (LIds[Count] != RIds[Count]) 00153 return Count; 00154 00155 return Count; 00156 } 00157 00158 00159 /// PadLT - Order landing pads lexicographically by type id. 00160 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) { 00161 const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds; 00162 unsigned LSize = LIds.size(), RSize = RIds.size(); 00163 unsigned MinSize = LSize < RSize ? LSize : RSize; 00164 00165 for (unsigned i = 0; i != MinSize; ++i) 00166 if (LIds[i] != RIds[i]) 00167 return LIds[i] < RIds[i]; 00168 00169 return LSize < RSize; 00170 } 00171 00172 namespace { 00173 00174 struct KeyInfo { 00175 static inline unsigned getEmptyKey() { return -1U; } 00176 static inline unsigned getTombstoneKey() { return -2U; } 00177 static unsigned getHashValue(const unsigned &Key) { return Key; } 00178 static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; } 00179 static bool isPod() { return true; } 00180 }; 00181 00182 /// ActionEntry - Structure describing an entry in the actions table. 00183 struct ActionEntry { 00184 int ValueForTypeID; // The value to write - may not be equal to the type id. 00185 int NextAction; 00186 struct ActionEntry *Previous; 00187 }; 00188 00189 /// PadRange - Structure holding a try-range and the associated landing pad. 00190 struct PadRange { 00191 // The index of the landing pad. 00192 unsigned PadIndex; 00193 // The index of the begin and end labels in the landing pad's label lists. 00194 unsigned RangeIndex; 00195 }; 00196 00197 typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType; 00198 00199 /// CallSiteEntry - Structure describing an entry in the call-site table. 00200 struct CallSiteEntry { 00201 unsigned BeginLabel; // zero indicates the start of the function. 00202 unsigned EndLabel; // zero indicates the end of the function. 00203 unsigned PadLabel; // zero indicates that there is no landing pad. 00204 unsigned Action; 00205 }; 00206 00207 } 00208 00209 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF, 00210 unsigned char* StartFunction, 00211 unsigned char* EndFunction) const { 00212 // Map all labels and get rid of any dead landing pads. 00213 MMI->TidyLandingPads(); 00214 00215 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 00216 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 00217 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 00218 if (PadInfos.empty()) return 0; 00219 00220 // Sort the landing pads in order of their type ids. This is used to fold 00221 // duplicate actions. 00222 SmallVector<const LandingPadInfo *, 64> LandingPads; 00223 LandingPads.reserve(PadInfos.size()); 00224 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 00225 LandingPads.push_back(&PadInfos[i]); 00226 std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 00227 00228 // Negative type ids index into FilterIds, positive type ids index into 00229 // TypeInfos. The value written for a positive type id is just the type 00230 // id itself. For a negative type id, however, the value written is the 00231 // (negative) byte offset of the corresponding FilterIds entry. The byte 00232 // offset is usually equal to the type id, because the FilterIds entries 00233 // are written using a variable width encoding which outputs one byte per 00234 // entry as long as the value written is not too large, but can differ. 00235 // This kind of complication does not occur for positive type ids because 00236 // type infos are output using a fixed width encoding. 00237 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i]. 00238 SmallVector<int, 16> FilterOffsets; 00239 FilterOffsets.reserve(FilterIds.size()); 00240 int Offset = -1; 00241 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(), 00242 E = FilterIds.end(); I != E; ++I) { 00243 FilterOffsets.push_back(Offset); 00244 Offset -= TargetAsmInfo::getULEB128Size(*I); 00245 } 00246 00247 // Compute the actions table and gather the first action index for each 00248 // landing pad site. 00249 SmallVector<ActionEntry, 32> Actions; 00250 SmallVector<unsigned, 64> FirstActions; 00251 FirstActions.reserve(LandingPads.size()); 00252 00253 int FirstAction = 0; 00254 unsigned SizeActions = 0; 00255 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 00256 const LandingPadInfo *LP = LandingPads[i]; 00257 const std::vector<int> &TypeIds = LP->TypeIds; 00258 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0; 00259 unsigned SizeSiteActions = 0; 00260 00261 if (NumShared < TypeIds.size()) { 00262 unsigned SizeAction = 0; 00263 ActionEntry *PrevAction = 0; 00264 00265 if (NumShared) { 00266 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size(); 00267 assert(Actions.size()); 00268 PrevAction = &Actions.back(); 00269 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + 00270 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 00271 for (unsigned j = NumShared; j != SizePrevIds; ++j) { 00272 SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 00273 SizeAction += -PrevAction->NextAction; 00274 PrevAction = PrevAction->Previous; 00275 } 00276 } 00277 00278 // Compute the actions. 00279 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { 00280 int TypeID = TypeIds[I]; 00281 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 00282 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 00283 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); 00284 00285 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 00286 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); 00287 SizeSiteActions += SizeAction; 00288 00289 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; 00290 Actions.push_back(Action); 00291 00292 PrevAction = &Actions.back(); 00293 } 00294 00295 // Record the first action of the landing pad site. 00296 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 00297 } // else identical - re-use previous FirstAction 00298 00299 FirstActions.push_back(FirstAction); 00300 00301 // Compute this sites contribution to size. 00302 SizeActions += SizeSiteActions; 00303 } 00304 00305 // Compute the call-site table. Entries must be ordered by address. 00306 SmallVector<CallSiteEntry, 64> CallSites; 00307 00308 RangeMapType PadMap; 00309 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 00310 const LandingPadInfo *LandingPad = LandingPads[i]; 00311 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 00312 unsigned BeginLabel = LandingPad->BeginLabels[j]; 00313 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 00314 PadRange P = { i, j }; 00315 PadMap[BeginLabel] = P; 00316 } 00317 } 00318 00319 bool MayThrow = false; 00320 unsigned LastLabel = 0; 00321 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 00322 I != E; ++I) { 00323 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 00324 MI != E; ++MI) { 00325 if (!MI->isLabel()) { 00326 MayThrow |= MI->getDesc().isCall(); 00327 continue; 00328 } 00329 00330 unsigned BeginLabel = MI->getOperand(0).getImm(); 00331 assert(BeginLabel && "Invalid label!"); 00332 00333 if (BeginLabel == LastLabel) 00334 MayThrow = false; 00335 00336 RangeMapType::iterator L = PadMap.find(BeginLabel); 00337 00338 if (L == PadMap.end()) 00339 continue; 00340 00341 PadRange P = L->second; 00342 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 00343 00344 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 00345 "Inconsistent landing pad map!"); 00346 00347 // If some instruction between the previous try-range and this one may 00348 // throw, create a call-site entry with no landing pad for the region 00349 // between the try-ranges. 00350 if (MayThrow) { 00351 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; 00352 CallSites.push_back(Site); 00353 } 00354 00355 LastLabel = LandingPad->EndLabels[P.RangeIndex]; 00356 CallSiteEntry Site = {BeginLabel, LastLabel, 00357 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]}; 00358 00359 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel && 00360 "Invalid landing pad!"); 00361 00362 // Try to merge with the previous call-site. 00363 if (CallSites.size()) { 00364 CallSiteEntry &Prev = CallSites.back(); 00365 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 00366 // Extend the range of the previous entry. 00367 Prev.EndLabel = Site.EndLabel; 00368 continue; 00369 } 00370 } 00371 00372 // Otherwise, create a new call-site. 00373 CallSites.push_back(Site); 00374 } 00375 } 00376 // If some instruction between the previous try-range and the end of the 00377 // function may throw, create a call-site entry with no landing pad for the 00378 // region following the try-range. 00379 if (MayThrow) { 00380 CallSiteEntry Site = {LastLabel, 0, 0, 0}; 00381 CallSites.push_back(Site); 00382 } 00383 00384 // Final tallies. 00385 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start. 00386 sizeof(int32_t) + // Site length. 00387 sizeof(int32_t)); // Landing pad. 00388 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) 00389 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); 00390 00391 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize(); 00392 00393 unsigned TypeOffset = sizeof(int8_t) + // Call site format 00394 // Call-site table length 00395 TargetAsmInfo::getULEB128Size(SizeSites) + 00396 SizeSites + SizeActions + SizeTypes; 00397 00398 unsigned TotalSize = sizeof(int8_t) + // LPStart format 00399 sizeof(int8_t) + // TType format 00400 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset 00401 TypeOffset; 00402 00403 unsigned SizeAlign = (4 - TotalSize) & 3; 00404 00405 // Begin the exception table. 00406 MCE->emitAlignment(4); 00407 for (unsigned i = 0; i != SizeAlign; ++i) { 00408 MCE->emitByte(0); 00409 // Asm->EOL("Padding"); 00410 } 00411 00412 unsigned char* DwarfExceptionTable = (unsigned char*)MCE->getCurrentPCValue(); 00413 00414 // Emit the header. 00415 MCE->emitByte(dwarf::DW_EH_PE_omit); 00416 // Asm->EOL("LPStart format (DW_EH_PE_omit)"); 00417 MCE->emitByte(dwarf::DW_EH_PE_absptr); 00418 // Asm->EOL("TType format (DW_EH_PE_absptr)"); 00419 MCE->emitULEB128Bytes(TypeOffset); 00420 // Asm->EOL("TType base offset"); 00421 MCE->emitByte(dwarf::DW_EH_PE_udata4); 00422 // Asm->EOL("Call site format (DW_EH_PE_udata4)"); 00423 MCE->emitULEB128Bytes(SizeSites); 00424 // Asm->EOL("Call-site table length"); 00425 00426 // Emit the landing pad site information. 00427 for (unsigned i = 0; i < CallSites.size(); ++i) { 00428 CallSiteEntry &S = CallSites[i]; 00429 intptr_t BeginLabelPtr = 0; 00430 intptr_t EndLabelPtr = 0; 00431 00432 if (!S.BeginLabel) { 00433 BeginLabelPtr = (intptr_t)StartFunction; 00434 MCE->emitInt32(0); 00435 } else { 00436 BeginLabelPtr = MCE->getLabelAddress(S.BeginLabel); 00437 MCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction); 00438 } 00439 00440 // Asm->EOL("Region start"); 00441 00442 if (!S.EndLabel) { 00443 EndLabelPtr = (intptr_t)EndFunction; 00444 MCE->emitInt32((intptr_t)EndFunction - BeginLabelPtr); 00445 } else { 00446 EndLabelPtr = MCE->getLabelAddress(S.EndLabel); 00447 MCE->emitInt32(EndLabelPtr - BeginLabelPtr); 00448 } 00449 //Asm->EOL("Region length"); 00450 00451 if (!S.PadLabel) { 00452 MCE->emitInt32(0); 00453 } else { 00454 unsigned PadLabelPtr = MCE->getLabelAddress(S.PadLabel); 00455 MCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction); 00456 } 00457 // Asm->EOL("Landing pad"); 00458 00459 MCE->emitULEB128Bytes(S.Action); 00460 // Asm->EOL("Action"); 00461 } 00462 00463 // Emit the actions. 00464 for (unsigned I = 0, N = Actions.size(); I != N; ++I) { 00465 ActionEntry &Action = Actions[I]; 00466 00467 MCE->emitSLEB128Bytes(Action.ValueForTypeID); 00468 //Asm->EOL("TypeInfo index"); 00469 MCE->emitSLEB128Bytes(Action.NextAction); 00470 //Asm->EOL("Next action"); 00471 } 00472 00473 // Emit the type ids. 00474 for (unsigned M = TypeInfos.size(); M; --M) { 00475 GlobalVariable *GV = TypeInfos[M - 1]; 00476 00477 if (GV) { 00478 if (TD->getPointerSize() == sizeof(int32_t)) { 00479 MCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV)); 00480 } else { 00481 MCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV)); 00482 } 00483 } else { 00484 if (TD->getPointerSize() == sizeof(int32_t)) 00485 MCE->emitInt32(0); 00486 else 00487 MCE->emitInt64(0); 00488 } 00489 // Asm->EOL("TypeInfo"); 00490 } 00491 00492 // Emit the filter typeids. 00493 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { 00494 unsigned TypeID = FilterIds[j]; 00495 MCE->emitULEB128Bytes(TypeID); 00496 //Asm->EOL("Filter TypeInfo index"); 00497 } 00498 00499 MCE->emitAlignment(4); 00500 00501 return DwarfExceptionTable; 00502 } 00503 00504 unsigned char* 00505 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const { 00506 unsigned PointerSize = TD->getPointerSize(); 00507 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ? 00508 PointerSize : -PointerSize; 00509 00510 unsigned char* StartCommonPtr = (unsigned char*)MCE->getCurrentPCValue(); 00511 // EH Common Frame header 00512 MCE->allocateSpace(4, 0); 00513 unsigned char* FrameCommonBeginPtr = (unsigned char*)MCE->getCurrentPCValue(); 00514 MCE->emitInt32((int)0); 00515 MCE->emitByte(dwarf::DW_CIE_VERSION); 00516 MCE->emitString(Personality ? "zPLR" : "zR"); 00517 MCE->emitULEB128Bytes(1); 00518 MCE->emitSLEB128Bytes(stackGrowth); 00519 MCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true)); 00520 00521 if (Personality) { 00522 MCE->emitULEB128Bytes(7); 00523 00524 // Direct encoding, because we use the function pointer. Not relative, 00525 // because the current PC value may be bigger than the personality 00526 // function pointer. 00527 MCE->emitByte(dwarf::DW_EH_PE_sdata4); 00528 00529 MCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality))); 00530 00531 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 00532 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 00533 00534 } else { 00535 MCE->emitULEB128Bytes(1); 00536 MCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4); 00537 } 00538 00539 std::vector<MachineMove> Moves; 00540 RI->getInitialFrameState(Moves); 00541 EmitFrameMoves(0, Moves); 00542 MCE->emitAlignment(PointerSize); 00543 00544 MCE->emitInt32At((uintptr_t*)StartCommonPtr, 00545 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - 00546 FrameCommonBeginPtr)); 00547 00548 return StartCommonPtr; 00549 } 00550 00551 00552 unsigned char* 00553 JITDwarfEmitter::EmitEHFrame(const Function* Personality, 00554 unsigned char* StartCommonPtr, 00555 unsigned char* StartFunction, 00556 unsigned char* EndFunction, 00557 unsigned char* ExceptionTable) const { 00558 unsigned PointerSize = TD->getPointerSize(); 00559 00560 // EH frame header. 00561 unsigned char* StartEHPtr = (unsigned char*)MCE->getCurrentPCValue(); 00562 MCE->allocateSpace(4, 0); 00563 unsigned char* FrameBeginPtr = (unsigned char*)MCE->getCurrentPCValue(); 00564 // FDE CIE Offset 00565 MCE->emitInt32(FrameBeginPtr - StartCommonPtr); 00566 MCE->emitInt32(StartFunction - (unsigned char*)MCE->getCurrentPCValue()); 00567 MCE->emitInt32(EndFunction - StartFunction); 00568 00569 // If there is a personality and landing pads then point to the language 00570 // specific data area in the exception table. 00571 if (MMI->getPersonalityIndex()) { 00572 MCE->emitULEB128Bytes(4); 00573 00574 if (!MMI->getLandingPads().empty()) { 00575 MCE->emitInt32(ExceptionTable - (unsigned char*)MCE->getCurrentPCValue()); 00576 } else { 00577 MCE->emitInt32((int)0); 00578 } 00579 } else { 00580 MCE->emitULEB128Bytes(0); 00581 } 00582 00583 // Indicate locations of function specific callee saved registers in 00584 // frame. 00585 EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves()); 00586 00587 MCE->emitAlignment(PointerSize); 00588 00589 // Indicate the size of the table 00590 MCE->emitInt32At((uintptr_t*)StartEHPtr, 00591 (uintptr_t)((unsigned char*)MCE->getCurrentPCValue() - 00592 StartEHPtr)); 00593 00594 // Double zeroes for the unwind runtime 00595 if (PointerSize == 8) { 00596 MCE->emitInt64(0); 00597 MCE->emitInt64(0); 00598 } else { 00599 MCE->emitInt32(0); 00600 MCE->emitInt32(0); 00601 } 00602 00603 00604 return StartEHPtr; 00605 } 00606 00607 unsigned JITDwarfEmitter::GetDwarfTableSizeInBytes(MachineFunction& F, 00608 MachineCodeEmitter& mce, 00609 unsigned char* StartFunction, 00610 unsigned char* EndFunction) { 00611 const TargetMachine& TM = F.getTarget(); 00612 TD = TM.getTargetData(); 00613 needsIndirectEncoding = TM.getTargetAsmInfo()->getNeedsIndirectEncoding(); 00614 stackGrowthDirection = TM.getFrameInfo()->getStackGrowthDirection(); 00615 RI = TM.getRegisterInfo(); 00616 MCE = &mce; 00617 unsigned FinalSize = 0; 00618 00619 FinalSize += GetExceptionTableSizeInBytes(&F); 00620 00621 const std::vector<Function *> Personalities = MMI->getPersonalities(); 00622 FinalSize += 00623 GetCommonEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()]); 00624 00625 FinalSize += GetEHFrameSizeInBytes(Personalities[MMI->getPersonalityIndex()], 00626 StartFunction); 00627 00628 return FinalSize; 00629 } 00630 00631 /// RoundUpToAlign - Add the specified alignment to FinalSize and returns 00632 /// the new value. 00633 static unsigned RoundUpToAlign(unsigned FinalSize, unsigned Alignment) { 00634 if (Alignment == 0) Alignment = 1; 00635 // Since we do not know where the buffer will be allocated, be pessimistic. 00636 return FinalSize + Alignment; 00637 } 00638 00639 unsigned 00640 JITDwarfEmitter::GetEHFrameSizeInBytes(const Function* Personality, 00641 unsigned char* StartFunction) const { 00642 unsigned PointerSize = TD->getPointerSize(); 00643 unsigned FinalSize = 0; 00644 // EH frame header. 00645 FinalSize += PointerSize; 00646 // FDE CIE Offset 00647 FinalSize += 3 * PointerSize; 00648 // If there is a personality and landing pads then point to the language 00649 // specific data area in the exception table. 00650 if (MMI->getPersonalityIndex()) { 00651 FinalSize += TargetAsmInfo::getULEB128Size(4); 00652 FinalSize += PointerSize; 00653 } else { 00654 FinalSize += TargetAsmInfo::getULEB128Size(0); 00655 } 00656 00657 // Indicate locations of function specific callee saved registers in 00658 // frame. 00659 FinalSize += GetFrameMovesSizeInBytes((intptr_t)StartFunction, 00660 MMI->getFrameMoves()); 00661 00662 FinalSize = RoundUpToAlign(FinalSize, 4); 00663 00664 // Double zeroes for the unwind runtime 00665 FinalSize += 2 * PointerSize; 00666 00667 return FinalSize; 00668 } 00669 00670 unsigned JITDwarfEmitter::GetCommonEHFrameSizeInBytes(const Function* Personality) 00671 const { 00672 00673 unsigned PointerSize = TD->getPointerSize(); 00674 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ? 00675 PointerSize : -PointerSize; 00676 unsigned FinalSize = 0; 00677 // EH Common Frame header 00678 FinalSize += PointerSize; 00679 FinalSize += 4; 00680 FinalSize += 1; 00681 FinalSize += Personality ? 5 : 3; // "zPLR" or "zR" 00682 FinalSize += TargetAsmInfo::getULEB128Size(1); 00683 FinalSize += TargetAsmInfo::getSLEB128Size(stackGrowth); 00684 FinalSize += 1; 00685 00686 if (Personality) { 00687 FinalSize += TargetAsmInfo::getULEB128Size(7); 00688 00689 // Encoding 00690 FinalSize+= 1; 00691 //Personality 00692 FinalSize += PointerSize; 00693 00694 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel); 00695 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel); 00696 00697 } else { 00698 FinalSize += TargetAsmInfo::getULEB128Size(1); 00699 FinalSize += TargetAsmInfo::getULEB128Size(dwarf::DW_EH_PE_pcrel); 00700 } 00701 00702 std::vector<MachineMove> Moves; 00703 RI->getInitialFrameState(Moves); 00704 FinalSize += GetFrameMovesSizeInBytes(0, Moves); 00705 FinalSize = RoundUpToAlign(FinalSize, 4); 00706 return FinalSize; 00707 } 00708 00709 unsigned 00710 JITDwarfEmitter::GetFrameMovesSizeInBytes(intptr_t BaseLabelPtr, 00711 const std::vector<MachineMove> &Moves) const { 00712 unsigned PointerSize = TD->getPointerSize(); 00713 int stackGrowth = stackGrowthDirection == TargetFrameInfo::StackGrowsUp ? 00714 PointerSize : -PointerSize; 00715 bool IsLocal = BaseLabelPtr; 00716 unsigned FinalSize = 0; 00717 00718 for (unsigned i = 0, N = Moves.size(); i < N; ++i) { 00719 const MachineMove &Move = Moves[i]; 00720 unsigned LabelID = Move.getLabelID(); 00721 00722 if (LabelID) { 00723 LabelID = MMI->MappedLabel(LabelID); 00724 00725 // Throw out move if the label is invalid. 00726 if (!LabelID) continue; 00727 } 00728 00729 intptr_t LabelPtr = 0; 00730 if (LabelID) LabelPtr = MCE->getLabelAddress(LabelID); 00731 00732 const MachineLocation &Dst = Move.getDestination(); 00733 const MachineLocation &Src = Move.getSource(); 00734 00735 // Advance row if new location. 00736 if (BaseLabelPtr && LabelID && (BaseLabelPtr != LabelPtr || !IsLocal)) { 00737 FinalSize++; 00738 FinalSize += PointerSize; 00739 BaseLabelPtr = LabelPtr; 00740 IsLocal = true; 00741 } 00742 00743 // If advancing cfa. 00744 if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { 00745 if (!Src.isReg()) { 00746 if (Src.getReg() == MachineLocation::VirtualFP) { 00747 ++FinalSize; 00748 } else { 00749 ++FinalSize; 00750 unsigned RegNum = RI->getDwarfRegNum(Src.getReg(), true); 00751 FinalSize += TargetAsmInfo::getULEB128Size(RegNum); 00752 } 00753 00754 int Offset = -Src.getOffset(); 00755 00756 FinalSize += TargetAsmInfo::getULEB128Size(Offset); 00757 } else { 00758 assert(0 && "Machine move no supported yet."); 00759 } 00760 } else if (Src.isReg() && 00761 Src.getReg() == MachineLocation::VirtualFP) { 00762 if (Dst.isReg()) { 00763 ++FinalSize; 00764 unsigned RegNum = RI->getDwarfRegNum(Dst.getReg(), true); 00765 FinalSize += TargetAsmInfo::getULEB128Size(RegNum); 00766 } else { 00767 assert(0 && "Machine move no supported yet."); 00768 } 00769 } else { 00770 unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true); 00771 int Offset = Dst.getOffset() / stackGrowth; 00772 00773 if (Offset < 0) { 00774 ++FinalSize; 00775 FinalSize += TargetAsmInfo::getULEB128Size(Reg); 00776 FinalSize += TargetAsmInfo::getSLEB128Size(Offset); 00777 } else if (Reg < 64) { 00778 ++FinalSize; 00779 FinalSize += TargetAsmInfo::getULEB128Size(Offset); 00780 } else { 00781 ++FinalSize; 00782 FinalSize += TargetAsmInfo::getULEB128Size(Reg); 00783 FinalSize += TargetAsmInfo::getULEB128Size(Offset); 00784 } 00785 } 00786 } 00787 return FinalSize; 00788 } 00789 00790 unsigned 00791 JITDwarfEmitter::GetExceptionTableSizeInBytes(MachineFunction* MF) const { 00792 unsigned FinalSize = 0; 00793 00794 // Map all labels and get rid of any dead landing pads. 00795 MMI->TidyLandingPads(); 00796 00797 const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); 00798 const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); 00799 const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); 00800 if (PadInfos.empty()) return 0; 00801 00802 // Sort the landing pads in order of their type ids. This is used to fold 00803 // duplicate actions. 00804 SmallVector<const LandingPadInfo *, 64> LandingPads; 00805 LandingPads.reserve(PadInfos.size()); 00806 for (unsigned i = 0, N = PadInfos.size(); i != N; ++i) 00807 LandingPads.push_back(&PadInfos[i]); 00808 std::sort(LandingPads.begin(), LandingPads.end(), PadLT); 00809 00810 // Negative type ids index into FilterIds, positive type ids index into 00811 // TypeInfos. The value written for a positive type id is just the type 00812 // id itself. For a negative type id, however, the value written is the 00813 // (negative) byte offset of the corresponding FilterIds entry. The byte 00814 // offset is usually equal to the type id, because the FilterIds entries 00815 // are written using a variable width encoding which outputs one byte per 00816 // entry as long as the value written is not too large, but can differ. 00817 // This kind of complication does not occur for positive type ids because 00818 // type infos are output using a fixed width encoding. 00819 // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i]. 00820 SmallVector<int, 16> FilterOffsets; 00821 FilterOffsets.reserve(FilterIds.size()); 00822 int Offset = -1; 00823 for(std::vector<unsigned>::const_iterator I = FilterIds.begin(), 00824 E = FilterIds.end(); I != E; ++I) { 00825 FilterOffsets.push_back(Offset); 00826 Offset -= TargetAsmInfo::getULEB128Size(*I); 00827 } 00828 00829 // Compute the actions table and gather the first action index for each 00830 // landing pad site. 00831 SmallVector<ActionEntry, 32> Actions; 00832 SmallVector<unsigned, 64> FirstActions; 00833 FirstActions.reserve(LandingPads.size()); 00834 00835 int FirstAction = 0; 00836 unsigned SizeActions = 0; 00837 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 00838 const LandingPadInfo *LP = LandingPads[i]; 00839 const std::vector<int> &TypeIds = LP->TypeIds; 00840 const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0; 00841 unsigned SizeSiteActions = 0; 00842 00843 if (NumShared < TypeIds.size()) { 00844 unsigned SizeAction = 0; 00845 ActionEntry *PrevAction = 0; 00846 00847 if (NumShared) { 00848 const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size(); 00849 assert(Actions.size()); 00850 PrevAction = &Actions.back(); 00851 SizeAction = TargetAsmInfo::getSLEB128Size(PrevAction->NextAction) + 00852 TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 00853 for (unsigned j = NumShared; j != SizePrevIds; ++j) { 00854 SizeAction -= TargetAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID); 00855 SizeAction += -PrevAction->NextAction; 00856 PrevAction = PrevAction->Previous; 00857 } 00858 } 00859 00860 // Compute the actions. 00861 for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) { 00862 int TypeID = TypeIds[I]; 00863 assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!"); 00864 int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID; 00865 unsigned SizeTypeID = TargetAsmInfo::getSLEB128Size(ValueForTypeID); 00866 00867 int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0; 00868 SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction); 00869 SizeSiteActions += SizeAction; 00870 00871 ActionEntry Action = {ValueForTypeID, NextAction, PrevAction}; 00872 Actions.push_back(Action); 00873 00874 PrevAction = &Actions.back(); 00875 } 00876 00877 // Record the first action of the landing pad site. 00878 FirstAction = SizeActions + SizeSiteActions - SizeAction + 1; 00879 } // else identical - re-use previous FirstAction 00880 00881 FirstActions.push_back(FirstAction); 00882 00883 // Compute this sites contribution to size. 00884 SizeActions += SizeSiteActions; 00885 } 00886 00887 // Compute the call-site table. Entries must be ordered by address. 00888 SmallVector<CallSiteEntry, 64> CallSites; 00889 00890 RangeMapType PadMap; 00891 for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { 00892 const LandingPadInfo *LandingPad = LandingPads[i]; 00893 for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) { 00894 unsigned BeginLabel = LandingPad->BeginLabels[j]; 00895 assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); 00896 PadRange P = { i, j }; 00897 PadMap[BeginLabel] = P; 00898 } 00899 } 00900 00901 bool MayThrow = false; 00902 unsigned LastLabel = 0; 00903 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); 00904 I != E; ++I) { 00905 for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end(); 00906 MI != E; ++MI) { 00907 if (!MI->isLabel()) { 00908 MayThrow |= MI->getDesc().isCall(); 00909 continue; 00910 } 00911 00912 unsigned BeginLabel = MI->getOperand(0).getImm(); 00913 assert(BeginLabel && "Invalid label!"); 00914 00915 if (BeginLabel == LastLabel) 00916 MayThrow = false; 00917 00918 RangeMapType::iterator L = PadMap.find(BeginLabel); 00919 00920 if (L == PadMap.end()) 00921 continue; 00922 00923 PadRange P = L->second; 00924 const LandingPadInfo *LandingPad = LandingPads[P.PadIndex]; 00925 00926 assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] && 00927 "Inconsistent landing pad map!"); 00928 00929 // If some instruction between the previous try-range and this one may 00930 // throw, create a call-site entry with no landing pad for the region 00931 // between the try-ranges. 00932 if (MayThrow) { 00933 CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0}; 00934 CallSites.push_back(Site); 00935 } 00936 00937 LastLabel = LandingPad->EndLabels[P.RangeIndex]; 00938 CallSiteEntry Site = {BeginLabel, LastLabel, 00939 LandingPad->LandingPadLabel, FirstActions[P.PadIndex]}; 00940 00941 assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel && 00942 "Invalid landing pad!"); 00943 00944 // Try to merge with the previous call-site. 00945 if (CallSites.size()) { 00946 CallSiteEntry &Prev = CallSites.back(); 00947 if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) { 00948 // Extend the range of the previous entry. 00949 Prev.EndLabel = Site.EndLabel; 00950 continue; 00951 } 00952 } 00953 00954 // Otherwise, create a new call-site. 00955 CallSites.push_back(Site); 00956 } 00957 } 00958 // If some instruction between the previous try-range and the end of the 00959 // function may throw, create a call-site entry with no landing pad for the 00960 // region following the try-range. 00961 if (MayThrow) { 00962 CallSiteEntry Site = {LastLabel, 0, 0, 0}; 00963 CallSites.push_back(Site); 00964 } 00965 00966 // Final tallies. 00967 unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start. 00968 sizeof(int32_t) + // Site length. 00969 sizeof(int32_t)); // Landing pad. 00970 for (unsigned i = 0, e = CallSites.size(); i < e; ++i) 00971 SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action); 00972 00973 unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize(); 00974 00975 unsigned TypeOffset = sizeof(int8_t) + // Call site format 00976 // Call-site table length 00977 TargetAsmInfo::getULEB128Size(SizeSites) + 00978 SizeSites + SizeActions + SizeTypes; 00979 00980 unsigned TotalSize = sizeof(int8_t) + // LPStart format 00981 sizeof(int8_t) + // TType format 00982 TargetAsmInfo::getULEB128Size(TypeOffset) + // TType base offset 00983 TypeOffset; 00984 00985 unsigned SizeAlign = (4 - TotalSize) & 3; 00986 00987 // Begin the exception table. 00988 FinalSize = RoundUpToAlign(FinalSize, 4); 00989 for (unsigned i = 0; i != SizeAlign; ++i) { 00990 ++FinalSize; 00991 } 00992 00993 unsigned PointerSize = TD->getPointerSize(); 00994 00995 // Emit the header. 00996 ++FinalSize; 00997 // Asm->EOL("LPStart format (DW_EH_PE_omit)"); 00998 ++FinalSize; 00999 // Asm->EOL("TType format (DW_EH_PE_absptr)"); 01000 ++FinalSize; 01001 // Asm->EOL("TType base offset"); 01002 ++FinalSize; 01003 // Asm->EOL("Call site format (DW_EH_PE_udata4)"); 01004 ++FinalSize; 01005 // Asm->EOL("Call-site table length"); 01006 01007 // Emit the landing pad site information. 01008 for (unsigned i = 0; i < CallSites.size(); ++i) { 01009 CallSiteEntry &S = CallSites[i]; 01010 01011 // Asm->EOL("Region start"); 01012 FinalSize += PointerSize; 01013 01014 //Asm->EOL("Region length"); 01015 FinalSize += PointerSize; 01016 01017 // Asm->EOL("Landing pad"); 01018 FinalSize += PointerSize; 01019 01020 FinalSize += TargetAsmInfo::getULEB128Size(S.Action); 01021 // Asm->EOL("Action"); 01022 } 01023 01024 // Emit the actions. 01025 for (unsigned I = 0, N = Actions.size(); I != N; ++I) { 01026 ActionEntry &Action = Actions[I]; 01027 01028 //Asm->EOL("TypeInfo index"); 01029 FinalSize += TargetAsmInfo::getSLEB128Size(Action.ValueForTypeID); 01030 //Asm->EOL("Next action"); 01031 FinalSize += TargetAsmInfo::getSLEB128Size(Action.NextAction); 01032 } 01033 01034 // Emit the type ids. 01035 for (unsigned M = TypeInfos.size(); M; --M) { 01036 // Asm->EOL("TypeInfo"); 01037 FinalSize += PointerSize; 01038 } 01039 01040 // Emit the filter typeids. 01041 for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) { 01042 unsigned TypeID = FilterIds[j]; 01043 FinalSize += TargetAsmInfo::getULEB128Size(TypeID); 01044 //Asm->EOL("Filter TypeInfo index"); 01045 } 01046 01047 FinalSize = RoundUpToAlign(FinalSize, 4); 01048 01049 return FinalSize; 01050 }