]> git.sur5r.net Git - cc65/commitdiff
Add reference counting to line infos. This allows better tracking of the ones
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 14:36:38 +0000 (14:36 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 18 Aug 2011 14:36:38 +0000 (14:36 +0000)
that are actually used.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5212 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/asserts.c
src/ca65/condasm.c
src/ca65/error.c
src/ca65/fragment.c
src/ca65/lineinfo.c
src/ca65/lineinfo.h
src/ca65/main.c
src/ca65/scanner.c
src/ca65/symentry.c
src/ca65/ulabel.c
src/ca65/ulabel.h

index d70f8f6023e230ff3dc33aa2270479ddd0ce1589..84b2621c700b4daa7bfe17a276ebc30bcd298683 100644 (file)
@@ -84,7 +84,7 @@ static Assertion* NewAssertion (ExprNode* Expr, AssertAction Action, unsigned Ms
     A->Action   = Action;
     A->Msg      = Msg;
     A->LI       = EmptyCollection;
-    GetFullLineInfo (&A->LI, 1);
+    GetFullLineInfo (&A->LI);
 
     /* Return the new struct */
     return A;
index 274b1a1d9451af770eba134c27e4c377a5ce5374..a14bbc2f6b0e3fb12a5d68bf719ee6c2c45246a4 100644 (file)
@@ -175,7 +175,7 @@ static IfDesc* AllocIf (const char* Directive, int NeedTerm)
         ID->Flags |= ifParentCond;
     }
     ID->LineInfos = EmptyCollection;
-    GetFullLineInfo (&ID->LineInfos, 0);
+    GetFullLineInfo (&ID->LineInfos);
     ID->Name = Directive;
 
     /* One more slot allocated */
@@ -198,6 +198,7 @@ static void FreeIf (void)
            Done = 1;
                } else {
                    Done = (ID->Flags & ifNeedTerm) != 0;
+            ReleaseFullLineInfo (&ID->LineInfos);
             DoneCollection (&ID->LineInfos);
             --IfCount;
                }
@@ -229,7 +230,8 @@ void DoConditionals (void)
 
                 /* Remember the data for the .ELSE */
                 if (D) {
-                    GetFullLineInfo (&D->LineInfos, 0);
+                    ReleaseFullLineInfo (&D->LineInfos);
+                    GetFullLineInfo (&D->LineInfos);
                     D->Name = ".ELSE";
                 }
 
index 7592c45578f8a9eeab9dfb940ae99e23b6e61bf0..85511d10744ccd6013df531e56e814fe2c2afd84 100644 (file)
@@ -190,7 +190,7 @@ void Warning (unsigned Level, const char* Format, ...)
         Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
 
         /* Get line infos for the current position */
-        GetFullLineInfo (&LineInfos, 0);
+        GetFullLineInfo (&LineInfos);
 
         /* Output the message */
         va_start (ap, Format);
@@ -198,6 +198,7 @@ void Warning (unsigned Level, const char* Format, ...)
         va_end (ap);
 
         /* Free the line info list */
+        ReleaseFullLineInfo (&LineInfos);
         DoneCollection (&LineInfos);
     }
 }
@@ -265,7 +266,7 @@ void Error (const char* Format, ...)
     Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
 
     /* Get line infos for the current position */
-    GetFullLineInfo (&LineInfos, 0);
+    GetFullLineInfo (&LineInfos);
 
     /* Output the message */
     va_start (ap, Format);
@@ -273,6 +274,7 @@ void Error (const char* Format, ...)
     va_end (ap);
 
     /* Free the line info list */
+    ReleaseFullLineInfo (&LineInfos);
     DoneCollection (&LineInfos);
 }
 
@@ -297,7 +299,7 @@ void ErrorSkip (const char* Format, ...)
     Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
 
     /* Get line infos for the current position */
-    GetFullLineInfo (&LineInfos, 0);
+    GetFullLineInfo (&LineInfos);
 
     /* Output the message */
     va_start (ap, Format);
@@ -305,6 +307,7 @@ void ErrorSkip (const char* Format, ...)
     va_end (ap);
 
     /* Free the line info list */
+    ReleaseFullLineInfo (&LineInfos);
     DoneCollection (&LineInfos);
 
     /* Skip tokens until we reach the end of the line */
index 4660490f98b6e1c1bdab8048e3bf6e8ae80cdb74..059371e77374c24cbfa2138b340b0a0b411f47b4 100644 (file)
@@ -59,7 +59,7 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len)
     F->Next    = 0;
     F->LineList = 0;
     F->LI       = EmptyCollection;
-    GetFullLineInfo (&F->LI, 1);
+    GetFullLineInfo (&F->LI);
     F->Len     = Len;
     F->Type    = Type;
 
index ad5cb8f35cd30d0491d4849c9ca9396d2fac93da..cddd17ac3c0a652b92318a85ed83561cadf3dd14 100644 (file)
@@ -87,8 +87,7 @@ struct LineInfo {
     HashNode        Node;               /* Hash table node */
     unsigned        Id;                 /* Index */
     LineInfoKey     Key;                /* Key for this line info */
-    unsigned char   Hashed;             /* True if in hash list */
-    unsigned char   Referenced;         /* Force reference even if no spans */
+    unsigned        RefCount;           /* Reference counter */
     Collection      Spans;              /* Segment spans for this line info */
     Collection      OpenSpans;          /* List of currently open spans */
 };
@@ -183,11 +182,13 @@ static LineInfo* NewLineInfo (const LineInfoKey* Key)
     InitHashNode (&LI->Node);
     LI->Id        = ~0U;
     LI->Key       = *Key;
-    LI->Hashed    = 0;
-    LI->Referenced= 0;
+    LI->RefCount  = 0;
     InitCollection (&LI->Spans);
     InitCollection (&LI->OpenSpans);
 
+    /* Add it to the hash table, so we will find it if necessary */
+    HT_InsertEntry (&LineInfoTab, LI);
+
     /* Return the new struct */
     return LI;
 }
@@ -208,22 +209,21 @@ static void FreeLineInfo (LineInfo* LI)
 
 
 
-static void RememberLineInfo (LineInfo* LI)
-/* Remember a LineInfo by adding it to the hash table and the global list.
- * This will also assign the id which is actually the list position.
- */
+static int CheckLineInfo (void* Entry, void* Data attribute ((unused)))
+/* Called from HT_Walk. Remembers used line infos and assigns them an id */
 {
-    /* Assign the id */
-    LI->Id = CollCount (&LineInfoList);
-
-    /* Remember it in the global list */
-    CollAppend (&LineInfoList, LI);
-
-    /* Add it to the hash table, so we will find it if necessary */
-    HT_InsertEntry (&LineInfoTab, LI);
-
-    /* Remember that we have it */
-    LI->Hashed = 1;
+    /* Entry is actually a line info */
+    LineInfo* LI = Entry;
+
+    /* The entry is used if there are spans or the ref counter is non zero */
+    if (LI->RefCount > 0 || CollCount (&LI->Spans) > 0) {
+        LI->Id = CollCount (&LineInfoList);
+        CollAppend (&LineInfoList, LI);
+        return 0;       /* Keep the entry */
+    } else {
+        FreeLineInfo (LI);
+        return 1;       /* Remove entry from table */
+    }
 }
 
 
@@ -258,6 +258,12 @@ void DoneLineInfo (void)
     while (Count) {
         EndLine (CollAt (&CurLineInfo, --Count));
     }
+
+    /* Walk over the entries in the hash table and sort them into used and
+     * unused ones. Add the used ones to the line info list and assign them
+     * an id.
+     */
+    HT_Walk (&LineInfoTab, CheckLineInfo, 0);
 }
 
 
@@ -282,18 +288,6 @@ void EndLine (LineInfo* LI)
      * line infos.
      */
     CollDeleteItem (&CurLineInfo, LI);
-
-    /* If this line info is already hashed, we're done. Otherwise, if it is
-     * marked as referenced or has non empty spans, remember it. It it is not
-     * referenced or doesn't have open spans, delete it.
-     */
-    if (!LI->Hashed) {
-        if (LI->Referenced || CollCount (&LI->Spans) > 0) {
-            RememberLineInfo (LI);
-        } else {
-            FreeLineInfo (LI);
-        }
-    }
 }
 
 
@@ -353,21 +347,39 @@ void NewAsmLine (void)
 
 
 
-void GetFullLineInfo (Collection* LineInfos, int ForceRef)
+LineInfo* GetAsmLineInfo (void)
+/* Return the line info for the current assembler file. The function will
+ * bump the reference counter before returning the line info.
+ */
+{
+    ++AsmLineInfo->RefCount;
+    return AsmLineInfo;
+}
+
+
+
+void ReleaseLineInfo (LineInfo* LI)
+/* Decrease the reference count for a line info */
+{
+    /* Decrease the reference counter */
+    CHECK (LI->RefCount > 0);
+    ++LI->RefCount;
+}
+
+
+
+void GetFullLineInfo (Collection* LineInfos)
 /* Return full line infos, that is line infos for currently active Slots. The
- * function will clear LineInfos before usage. If ForceRef is not zero, a
- * forced reference will be added to all line infos, with the consequence that
- * they won't get deleted, even if there is no code or data generated for these
- * lines.
+ * infos will be added to the given collection, existing entries will be left
+ * intact. The reference count of all added entries will be increased.
  */
 {
     unsigned I;
 
-    /* Clear the collection */
-    CollDeleteAll (LineInfos);
-
-    /* Grow the collection as necessary */
-    CollGrow (LineInfos, CollCount (&CurLineInfo));
+    /* If the collection is currently empty, grow it as necessary */
+    if (CollCount (LineInfos) == 0) {
+        CollGrow (LineInfos, CollCount (&CurLineInfo));
+    }
 
     /* Copy all valid line infos to the collection */
     for (I = 0; I < CollCount (&CurLineInfo); ++I) {
@@ -375,10 +387,8 @@ void GetFullLineInfo (Collection* LineInfos, int ForceRef)
         /* Get the line info from the slot */
         LineInfo* LI = CollAt (&CurLineInfo, I);
 
-        /* Mark it as referenced */
-        if (ForceRef) {
-            LI->Referenced = 1;
-        }
+        /* Bump the reference counter */
+        ++LI->RefCount;
 
         /* Return it to the caller */
         CollAppend (LineInfos, LI);
@@ -387,6 +397,25 @@ void GetFullLineInfo (Collection* LineInfos, int ForceRef)
 
 
 
+void ReleaseFullLineInfo (Collection* LineInfos)
+/* Decrease the reference count for a collection full of LineInfos, then clear
+ * the collection.
+ */
+{
+    unsigned I;
+
+    /* Walk over all entries */
+    for (I = 0; I < CollCount (LineInfos); ++I) {
+        /* Release the the line info */
+        ReleaseLineInfo (CollAt (LineInfos, I));
+    }
+
+    /* Delete all entries */
+    CollDeleteAll (LineInfos);
+}
+
+
+
 const FilePos* GetSourcePos (const LineInfo* LI)
 /* Return the source file position from the given line info */
 {
@@ -417,6 +446,7 @@ void WriteLineInfo (const Collection* LineInfos)
         /* Get a pointer to the line info */
         const LineInfo* LI = CollConstAt (LineInfos, I);
 
+        /* Safety */
         CHECK (LI->Id != ~0U);
 
         /* Write the index to the file */
index 17d2dfd438020d8914a67fe095f38655912210b4..94b51ae4f2a2eda578a0813492824fd99b4d7b8b 100644 (file)
@@ -81,12 +81,23 @@ void NewAsmLine (void);
  * changed, end the old and start the new line as necessary.
  */
 
-void GetFullLineInfo (Collection* LineInfos, int ForceRef);
+LineInfo* GetAsmLineInfo (void);
+/* Return the line info for the current assembler file. The function will
+ * bump the reference counter before returning the line info.
+ */
+
+void ReleaseLineInfo (LineInfo* LI);
+/* Decrease the reference count for a line info */
+
+void GetFullLineInfo (Collection* LineInfos);
 /* Return full line infos, that is line infos for currently active Slots. The
- * function will clear LineInfos before usage. If ForceRef is not zero, a
- * forced reference will be added to all line infos, with the consequence that
- * they won't get deleted, even if there is no code or data generated for these
- * lines.
+ * infos will be added to the given collection, existing entries will be left
+ * intact. The reference count of all added entries will be increased.
+ */
+
+void ReleaseFullLineInfo (Collection* LineInfos);
+/* Decrease the reference count for a collection full of LineInfos, then clear
+ * the collection.
  */
 
 const FilePos* GetSourcePos (const LineInfo* LI);
index 1104f5b68a8350217bf50ef31ce2769f4d1fd2af..17aca8efc18199b841cfdef09559d7916b6e9ffa 100644 (file)
@@ -1011,9 +1011,9 @@ int main (int argc, char* argv [])
         CheckPseudo ();
     }
 
-    /* If we didn't have any errors, check the unnamed labels */
+    /* If we didn't have any errors, check and cleanup the unnamed labels */
     if (ErrorCount == 0) {
-        ULabCheck ();
+        ULabDone ();                                  
     }
 
     /* If we didn't have any errors, check the symbol table */
index bb31799dc81ecf2046cec85e3911dcbc325b8bdb..04f217ceb51d7ea60532d4c0f1ce68dcc1a51856 100644 (file)
@@ -1142,12 +1142,13 @@ CharAgain:
             } else if (CComments) {
                 /* Remember the position, then skip the '*' */
                 Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
-                GetFullLineInfo (&LineInfos, 0);
+                GetFullLineInfo (&LineInfos);
                 NextChar ();
                 do {
                     while (C !=  '*') {
                         if (C == EOF) {
                             LIError (&LineInfos, "Unterminated comment");
+                            ReleaseFullLineInfo (&LineInfos);
                             DoneCollection (&LineInfos);
                             goto CharAgain;
                         }
@@ -1156,6 +1157,7 @@ CharAgain:
                     NextChar ();
                 } while (C != '/');
                 NextChar ();
+                ReleaseFullLineInfo (&LineInfos);
                 DoneCollection (&LineInfos);
                 goto Again;
             }
index d46f21ac0a1e8ee59f2b64e7232a304041ec490f..cb250478b0c03bb0a7a05ea1de68a04847df4e72 100644 (file)
@@ -87,7 +87,7 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
     S->Locals            = 0;
     S->Sym.Tab    = 0;
     S->LineInfos  = EmptyCollection;
-    GetFullLineInfo (&S->LineInfos, 1);
+    GetFullLineInfo (&S->LineInfos);
     for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
         S->GuessedUse[I] = 0;
     }
index 023dd13757e12f3fcf461d952f58ec0a37a3df41..768312c1978a97e70f21b984d6bf01b3e39c53c9 100644 (file)
@@ -83,7 +83,7 @@ static ULabel* NewULabel (ExprNode* Val)
 
     /* Initialize the fields */
     L->LineInfos = EmptyCollection;
-    GetFullLineInfo (&L->LineInfos, 0);
+    GetFullLineInfo (&L->LineInfos);
     L->Val       = Val;
     L->Ref       = 0;
 
@@ -160,8 +160,9 @@ void ULabDef (void)
         */
        ULabel* L = CollAtUnchecked (&ULabList, ULabDefCount);
        CHECK (L->Val == 0);
-       L->Val = GenCurrentPC ();
-        GetFullLineInfo (&L->LineInfos, 0);
+       L->Val = GenCurrentPC ();     
+        ReleaseFullLineInfo (&L->LineInfos);
+        GetFullLineInfo (&L->LineInfos);
     } else {
        /* There is no such label, create it */
                NewULabel (GenCurrentPC ());
@@ -198,8 +199,10 @@ ExprNode* ULabResolve (unsigned Index)
 
 
 
-void ULabCheck (void)
-/* Run through all unnamed labels and check for anomalies and errors */
+void ULabDone (void)
+/* Run through all unnamed labels, check for anomalies and errors and do 
+ * necessary cleanups.
+ */
 {
     /* Check if there are undefined labels */
     unsigned I = ULabDefCount;
@@ -210,13 +213,14 @@ void ULabCheck (void)
     }
 
     /* Walk over all labels and emit a warning if any unreferenced ones
-     * are found.
+     * are found. Remove line infos because they're no longer needed.
      */
     for (I = 0; I < CollCount (&ULabList); ++I) {
         ULabel* L = CollAtUnchecked (&ULabList, I);
         if (L->Ref == 0) {
             LIWarning (&L->LineInfos, 1, "No reference to unnamed label");
         }
+        ReleaseFullLineInfo (&L->LineInfos);
     }
 }
 
index ea2e46767eecd6446ed0cfa274e7373728bdf280..9e8d1b37f664c77f2ed3f1bb244df1b128f798fc 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -64,8 +64,10 @@ ExprNode* ULabResolve (unsigned Index);
  * if a label is still undefined in this phase.
  */
 
-void ULabCheck (void);
-/* Run through all unnamed labels and check for anomalies and errors */
+void ULabDone (void);
+/* Run through all unnamed labels, check for anomalies and errors and do
+ * necessary cleanups.
+ */