[llvm-commits] [llvm] r79567 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp

Bill Wendling isanbard at gmail.com
Thu Aug 20 15:02:24 PDT 2009


Author: void
Date: Thu Aug 20 17:02:24 2009
New Revision: 79567

URL: http://llvm.org/viewvc/llvm-project?rev=79567&view=rev
Log:
Attempt to comment this code more.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp?rev=79567&r1=79566&r2=79567&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfException.cpp Thu Aug 20 17:02:24 2009
@@ -272,6 +272,19 @@
 ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
                     SmallVectorImpl<ActionEntry> &Actions,
                     SmallVectorImpl<unsigned> &FirstActions) {
+
+  // The action table follows the call-site table in the LSDA. The individual
+  // records are of two types:
+  //
+  //   * Catch clause
+  //   * Exception specification
+  //
+  // The two record kinds have the same format, with only small differences.
+  // They are distinguished by the "switch value" field: Catch clauses
+  // (TypeInfos) have strictly positive switch values, and exception
+  // specifications (FilterIds) have strictly negative switch values. Value 0
+  // indicates a catch-all clause.
+  //
   // Negative type IDs index into FilterIds. Positive type IDs index into
   // TypeInfos.  The value written for a positive type ID is just the type ID
   // itself.  For a negative type ID, however, the value written is the
@@ -337,7 +350,7 @@
         SizeAction = SizeTypeID + TargetAsmInfo::getSLEB128Size(NextAction);
         SizeSiteActions += SizeAction;
 
-        ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
+        ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
         Actions.push_back(Action);
         PrevAction = &Actions.back();
       }
@@ -346,6 +359,11 @@
       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
     } // else identical - re-use previous FirstAction
 
+    // Information used when created the call-site table. The action record
+    // field of the call site record is the offset of the first associated
+    // action record, relative to the start of the actions table. This value is
+    // biased by 1 (1 in dicating the start of the actions table), and 0
+    // indicates that there are no actions.
     FirstActions.push_back(FirstAction);
 
     // Compute this sites contribution to size.
@@ -358,7 +376,7 @@
 }
 
 /// ComputeCallSiteTable - Compute the call-site table.  The entry for an invoke
-/// has a try-range containing the call, a non-zero landing pad and an
+/// has a try-range containing the call, a non-zero landing pad, and an
 /// appropriate action.  The entry for an ordinary call has a try-range
 /// containing the call and zero for the landing pad and the action.  Calls
 /// marked 'nounwind' have no entry and must not be contained in the try-range
@@ -402,18 +420,18 @@
         // Nope, it was just some random label.
         continue;
 
-      PadRange P = L->second;
+      const PadRange &P = L->second;
       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
              "Inconsistent landing pad map!");
 
-      // For Dwarf exception handling (SjLj handling doesn't use this)
-      // If some instruction between the previous try-range and this one may
-      // throw, create a call-site entry with no landing pad for the region
-      // between the try-ranges.
+      // For Dwarf exception handling (SjLj handling doesn't use this). If some
+      // instruction between the previous try-range and this one may throw,
+      // create a call-site entry with no landing pad for the region between the
+      // try-ranges.
       if (SawPotentiallyThrowing &&
           TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
-        CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
+        CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 };
         CallSites.push_back(Site);
         PreviousIsInvoke = false;
       }
@@ -423,9 +441,12 @@
 
       if (LandingPad->LandingPadLabel) {
         // This try-range is for an invoke.
-        CallSiteEntry Site = {BeginLabel, LastLabel,
-                              LandingPad->LandingPadLabel,
-                              FirstActions[P.PadIndex]};
+        CallSiteEntry Site = {
+          BeginLabel,
+          LastLabel,
+          LandingPad->LandingPadLabel,
+          FirstActions[P.PadIndex]
+        };
 
         // Try to merge with the previous call-site.
         if (PreviousIsInvoke) {
@@ -452,7 +473,7 @@
   // region following the try-range.
   if (SawPotentiallyThrowing &&
       TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
-    CallSiteEntry Site = {LastLabel, 0, 0, 0};
+    CallSiteEntry Site = { LastLabel, 0, 0, 0 };
     CallSites.push_back(Site);
   }
 }
@@ -468,14 +489,14 @@
 ///     invokes in the try.  There is also a reference to the landing pad that
 ///     handles the exception once processed.  Finally an index into the actions
 ///     table.
-///  2. The action table, in our case, is composed of pairs of type ids and next
+///  2. The action table, in our case, is composed of pairs of type IDs and next
 ///     action offset.  Starting with the action index from the landing pad
-///     site, each type Id is checked for a match to the current exception.  If
+///     site, each type ID is checked for a match to the current exception.  If
 ///     it matches then the exception and type id are passed on to the landing
 ///     pad.  Otherwise the next action is looked up.  This chain is terminated
 ///     with a next action of zero.  If no type id is found the the frame is
 ///     unwound and handling continues.
-///  3. Type id table contains references to all the C++ typeinfo for all
+///  3. Type ID table contains references to all the C++ typeinfo for all
 ///     catches in the function.  This tables is reversed indexed base 1.
 void DwarfException::EmitExceptionTable() {
   const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
@@ -575,14 +596,14 @@
 
   // Emit the header.
   Asm->EmitInt8(dwarf::DW_EH_PE_omit);
-  Asm->EOL("LPStart format (DW_EH_PE_omit)");
+  Asm->EOL("@LPStart format (DW_EH_PE_omit)");
 
 #if 0
   if (TypeInfos.empty() && FilterIds.empty()) {
     // If there are no typeinfos or filters, there is nothing to emit, optimize
     // by specifying the "omit" encoding.
     Asm->EmitInt8(dwarf::DW_EH_PE_omit);
-    Asm->EOL("TType format (DW_EH_PE_omit)");
+    Asm->EOL("@TType format (DW_EH_PE_omit)");
   } else {
     // Okay, we have actual filters or typeinfos to emit.  As such, we need to
     // pick a type encoding for them.  We're about to emit a list of pointers to
@@ -626,12 +647,12 @@
   // FIXME: does this apply to Dwarf also? The above #if 0 implies yes?
   if (!HaveTTData) {
     Asm->EmitInt8(dwarf::DW_EH_PE_omit);
-    Asm->EOL("TType format (DW_EH_PE_omit)");
+    Asm->EOL("@TType format (DW_EH_PE_omit)");
   } else {
     Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
-    Asm->EOL("TType format (DW_EH_PE_absptr)");
+    Asm->EOL("@TType format (DW_EH_PE_absptr)");
     Asm->EmitULEB128Bytes(TypeOffset);
-    Asm->EOL("TType base offset");
+    Asm->EOL("@TType base offset");
   }
 #endif
 
@@ -640,15 +661,22 @@
     Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
     Asm->EOL("Call site format (DW_EH_PE_udata4)");
     Asm->EmitULEB128Bytes(SizeSites);
-    Asm->EOL("Call-site table length");
+    Asm->EOL("Call site table length");
 
     // Emit the landing pad site information.
     unsigned idx = 0;
     for (SmallVectorImpl<CallSiteEntry>::const_iterator
          I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) {
       const CallSiteEntry &S = *I;
+
+      // Offset of the landing pad, counted in 16-byte bundles relative to the
+      // @LPStart address.
       Asm->EmitULEB128Bytes(idx);
       Asm->EOL("Landing pad");
+
+      // Offset of the first associated action record, relative to the start of
+      // the action table. This value is biased by 1 (1 indicates the start of
+      // the action table), and 0 indicates that there are no actions.
       Asm->EmitULEB128Bytes(S.Action);
       Asm->EOL("Action");
     }
@@ -656,12 +684,38 @@
     // DWARF Exception handling
     assert(TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
 
+    // The call-site table is a list of all call sites that may throw an
+    // exception (including C++ 'throw' statements) in the procedure
+    // fragment. It immediately follows the LSDA header. Each entry indicates,
+    // for a given call, the first corresponding action record and corresponding
+    // landing pad.
+    //
+    // The table begins with the number of bytes, stored as an LEB128
+    // compressed, unsigned integer. The records immediately follow the record
+    // count. They are sorted in increasing call-site address. Each record
+    // indicates:
+    //
+    //   * The position of the call-site.
+    //   * The position of the landing pad.
+    //   * The first action record for that call site.
+    //
+    // A missing entry in the call-site table indicates that a call is not
+    // supposed to throw. Such calls include:
+    //
+    //   * Calls to destructors within cleanup code. C++ semantics forbids these
+    //     calls to throw.
+    //   * Calls to intrinsic routines in the standard library which are known
+    //     not to throw (sin, memcpy, et al).
+    //
+    // If the runtime does not find the call-site entry for a given call, it
+    // will call `terminate()'.
+
+    // Emit the landing pad call site table.
     Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
     Asm->EOL("Call site format (DW_EH_PE_udata4)");
     Asm->EmitULEB128Bytes(SizeSites);
-    Asm->EOL("Call-site table length");
+    Asm->EOL("Call site table size");
 
-    // Emit the landing pad site information.
     for (SmallVectorImpl<CallSiteEntry>::const_iterator
          I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
       const CallSiteEntry &S = *I;
@@ -676,6 +730,9 @@
         BeginNumber = S.BeginLabel;
       }
 
+      // Offset of the call site relative to the previous call site, counted in
+      // number of 16-byte bundles. The first call site is counted relative to
+      // the start of the procedure fragment.
       EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
                         true, true);
       Asm->EOL("Region start");
@@ -688,6 +745,8 @@
 
       Asm->EOL("Region length");
 
+      // Offset of the landing pad, counted in 16-byte bundles relative to the
+      // @LPStart address.
       if (!S.PadLabel)
         Asm->EmitInt32(0);
       else
@@ -696,25 +755,61 @@
 
       Asm->EOL("Landing pad");
 
+      // Offset of the first associated action record, relative to the start of
+      // the action table. This value is biased by 1 (1 indicates the start of
+      // the action table), and 0 indicates that there are no actions.
       Asm->EmitULEB128Bytes(S.Action);
       Asm->EOL("Action");
     }
   }
 
-  // Emit the actions.
+  // Emit the Action Table.
   for (SmallVectorImpl<ActionEntry>::const_iterator
          I = Actions.begin(), E = Actions.end(); I != E; ++I) {
     const ActionEntry &Action = *I;
+
+    // Type Filter
+    //
+    //   Used by the runtime to match the type of the thrown exception to the
+    //   type of the catch clauses or the types in the exception specification.
+
     Asm->EmitSLEB128Bytes(Action.ValueForTypeID);
     Asm->EOL("TypeInfo index");
+
+    // Action Record
+    //
+    //   Self-relative signed displacement in bytes of the next action record,
+    //   or 0 if there is no next action record.
+
     Asm->EmitSLEB128Bytes(Action.NextAction);
     Asm->EOL("Next action");
   }
 
-  // Emit the type ids.
+  // Emit the Catch Clauses. The code for the catch clauses following the same
+  // try is similar to a switch statement. The catch clause action record
+  // informs the runtime about the type of a catch clause and about the
+  // associated switch value.
+  //
+  //  Action Record Fields:
+  //  
+  //   * Filter Value
+  //     Positive value, starting at 1. Index in the types table of the
+  //     __typeinfo for the catch-clause type. 1 is the first word preceding
+  //     TTBase, 2 is the second word, and so on. Used by the runtime to check
+  //     if the thrown exception type matches the catch-clause type. Back-end
+  //     generated switch statements check against this value.
+  //
+  //   * Next
+  //     Signed offset, in bytes from the start of this field, to the next
+  //     chained action record, or zero if none.
+  //
+  // The order of the action records determined by the next field is the order
+  // of the catch clauses as they appear in the source code, and must be kept in
+  // the same order. As a result, changing the order of the catch clause would
+  // change the semantics of the program.
   for (std::vector<GlobalVariable *>::const_reverse_iterator
          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
-    GlobalVariable *GV = *I;
+    const GlobalVariable *GV = *I;
     PrintRelDirective();
 
     if (GV) {
@@ -727,7 +822,7 @@
     Asm->EOL("TypeInfo");
   }
 
-  // Emit the filter typeids.
+  // Emit the Type Table.
   for (std::vector<unsigned>::const_iterator
          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
     unsigned TypeID = *I;





More information about the llvm-commits mailing list