Tidy up m_wordfm.
First, as the allocator function does not fail, there is no need
to assert its return value.
Second, remove commented out (since r8765) function VG_(isEmptyFM).
Third, remove VG_(getNodeSizeFM) from the API. The details of the
implementation do not need to be exposed.
Fourth, for consistency require that the copy functions for keys and
values in VG_(dopyFM) (which are essentially like allocators) return
non-NULL values for non-NULL arguments if they return.
Fifth, document NULL-ness of return values for VG_(newFM), VG_(dopyFM),
and VG_(newBag). Remove pointless asserts at call sites.
Six, change avl_dopy to assert that the node the function is
supposed to copy is not NULL. It is called that way anyhow. With 
that change the function never returns NULL which allows us to
simplify the call sites. Checking the return value is no longer needed.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14535 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_wordfm.c b/coregrind/m_wordfm.c
index f3e517c..2038245 100644
--- a/coregrind/m_wordfm.c
+++ b/coregrind/m_wordfm.c
@@ -506,10 +506,10 @@
                     const HChar* cc )
 {
    AvlNode* nyu;
-   if (! nd)
-      return NULL;
+
+   vg_assert(nd != NULL);
+
    nyu = alloc_nofail(cc, sizeof(AvlNode));
-   tl_assert(nyu);
    
    nyu->child[0] = nd->child[0];
    nyu->child[1] = nd->child[1];
@@ -518,8 +518,6 @@
    /* Copy key */
    if (dopyK) {
       nyu->key = dopyK( nd->key );
-      if (nd->key != 0 && nyu->key == 0)
-         return NULL; /* oom in key dcopy */
    } else {
       /* copying assumedly unboxed keys */
       nyu->key = nd->key;
@@ -528,8 +526,6 @@
    /* Copy val */
    if (dopyV) {
       nyu->val = dopyV( nd->val );
-      if (nd->val != 0 && nyu->val == 0)
-         return NULL; /* oom in val dcopy */
    } else {
       /* copying assumedly unboxed vals */
       nyu->val = nd->val;
@@ -539,14 +535,10 @@
    if (nyu->child[0]) {
       nyu->child[0] = avl_dopy( nyu->child[0], dopyK, dopyV, 
                                 alloc_nofail, cc );
-      if (! nyu->child[0])
-         return NULL;
    }
    if (nyu->child[1]) {
       nyu->child[1] = avl_dopy( nyu->child[1], dopyK, dopyV,
                                 alloc_nofail, cc );
-      if (! nyu->child[1])
-         return NULL;
    }
 
    return nyu;
@@ -582,7 +574,6 @@
                      Word  (*kCmp)(UWord,UWord) )
 {
    WordFM* fm = alloc_nofail(cc, sizeof(WordFM));
-   tl_assert(fm);
    initFM(fm, alloc_nofail, cc, dealloc, kCmp);
    return fm;
 }
@@ -797,7 +788,7 @@
    return False;
 }
 
-// clear the I'm iterating flag
+// Finish an FM iteration
 void VG_(doneIterFM) ( WordFM* fm )
 {
 }
@@ -810,7 +801,6 @@
    tl_assert(fm->stackTop == 0);
 
    nyu = fm->alloc_nofail( fm->cc, sizeof(WordFM) );
-   tl_assert(nyu);
 
    *nyu = *fm;
 
@@ -828,12 +818,6 @@
    return nyu;
 }
 
-// admin: what's the 'common' allocation size (for tree nodes?)
-SizeT VG_(getNodeSizeFM)( void )
-{
-   return sizeof(AvlNode);
-}
-
 //------------------------------------------------------------------//
 //---                         end WordFM                         ---//
 //---                       Implementation                       ---//
diff --git a/helgrind/hg_errors.c b/helgrind/hg_errors.c
index 21ed9c1..93ea58d 100644
--- a/helgrind/hg_errors.c
+++ b/helgrind/hg_errors.c
@@ -76,7 +76,6 @@
    if (!string_table) {
       string_table = VG_(newFM)( HG_(zalloc), "hg.sts.1",
                                  HG_(free), string_table_cmp );
-      tl_assert(string_table);
    }
    if (VG_(lookupFM)( string_table,
                       NULL, (UWord*)&copy, (UWord)str )) {
@@ -164,7 +163,6 @@
    if (!map_LockN_to_P) {
       map_LockN_to_P = VG_(newFM)( HG_(zalloc), "hg.mLPfLN.1",
                                    HG_(free), lock_unique_cmp );
-      tl_assert(map_LockN_to_P);
    }
    if (!VG_(lookupFM)( map_LockN_to_P, NULL, (UWord*)&lkp, (UWord)lkn)) {
       lkp = HG_(zalloc)( "hg.mLPfLN.2", sizeof(Lock) );
diff --git a/helgrind/hg_main.c b/helgrind/hg_main.c
index 9691e0c..4453954 100644
--- a/helgrind/hg_main.c
+++ b/helgrind/hg_main.c
@@ -600,7 +600,6 @@
    tl_assert(map_locks == NULL);
    map_locks = VG_(newFM)( HG_(zalloc), "hg.ids.2", HG_(free), 
                            NULL/*unboxed Word cmp*/);
-   tl_assert(map_locks != NULL);
 
    tl_assert(univ_lsets == NULL);
    univ_lsets = HG_(newWordSetU)( HG_(zalloc), "hg.ids.4", HG_(free),
@@ -2170,7 +2169,6 @@
    if (UNLIKELY(map_cond_to_CVInfo == NULL)) {
       map_cond_to_CVInfo = VG_(newFM)( HG_(zalloc),
                                        "hg.mctCI.1", HG_(free), NULL );
-      tl_assert(map_cond_to_CVInfo != NULL);
    }
 }
 
@@ -2653,7 +2651,6 @@
    if (map_sem_to_SO_stack == NULL) {
       map_sem_to_SO_stack = VG_(newFM)( HG_(zalloc), "hg.mstSs.1",
                                         HG_(free), NULL );
-      tl_assert(map_sem_to_SO_stack != NULL);
    }
 }
 
@@ -2873,7 +2870,6 @@
    if (UNLIKELY(map_barrier_to_Bar == NULL)) {
       map_barrier_to_Bar = VG_(newFM)( HG_(zalloc),
                                        "hg.mbtBI.1", HG_(free), NULL );
-      tl_assert(map_barrier_to_Bar != NULL);
    }
 }
 
@@ -3205,7 +3201,6 @@
    if (UNLIKELY(map_usertag_to_SO == NULL)) {
       map_usertag_to_SO = VG_(newFM)( HG_(zalloc),
                                       "hg.mutS.1", HG_(free), NULL );
-      tl_assert(map_usertag_to_SO != NULL);
    }
 }
 
@@ -3385,8 +3380,6 @@
 
    laog_exposition = VG_(newFM)( HG_(zalloc), "hg.laog__init.2", HG_(free), 
                                  cmp_LAOGLinkExposition );
-   tl_assert(laog);
-   tl_assert(laog_exposition);
 }
 
 static void laog__show ( const HChar* who ) {
@@ -4744,7 +4737,6 @@
    if (UNLIKELY(map_pthread_t_to_Thread == NULL)) {
       map_pthread_t_to_Thread = VG_(newFM)( HG_(zalloc), "hg.mpttT.1", 
                                             HG_(free), NULL );
-      tl_assert(map_pthread_t_to_Thread != NULL);
    }
 }
 
diff --git a/helgrind/libhb_core.c b/helgrind/libhb_core.c
index bd26f28..e1a18a7 100644
--- a/helgrind/libhb_core.c
+++ b/helgrind/libhb_core.c
@@ -1758,7 +1758,6 @@
    map_shmem = VG_(newFM)( HG_(zalloc), "libhb.zsm_init.1 (map_shmem)",
                            HG_(free), 
                            NULL/*unboxed UWord cmp*/);
-   tl_assert(map_shmem != NULL);
    shmem__invalidate_scache();
 
    /* a SecMap must contain an integral number of CacheLines */
@@ -2489,7 +2488,6 @@
    vts_set = VG_(newFM)( HG_(zalloc), "libhb.vts_set_init.1",
                          HG_(free),
                          (Word(*)(UWord,UWord))VTS__cmp_structural );
-   tl_assert(vts_set);
 }
 
 /* Given a VTS, look in vts_set to see if we already have a
diff --git a/include/pub_tool_wordfm.h b/include/pub_tool_wordfm.h
index f0fdb58..bd7e221 100644
--- a/include/pub_tool_wordfm.h
+++ b/include/pub_tool_wordfm.h
@@ -77,7 +77,8 @@
    VG_(initIterAtFM), VG_(nextIterFM), VG_(doneIterFM) to iterate over
    sections of the map, or the whole thing.  If kCmp is NULL then the
    ordering used is unsigned word ordering (UWord) on the key
-   values. */
+   values.
+   The function never returns NULL. */
 WordFM* VG_(newFM) ( void* (*alloc_nofail)( const HChar* cc, SizeT ),
                      const HChar* cc,
                      void  (*dealloc)(void*),
@@ -129,11 +130,6 @@
 // since it involves walking the whole tree.
 UWord VG_(sizeFM) ( WordFM* fm );
 
-// Is fm empty?  This at least is an O(1) operation.
-// Code is present in m_wordfm.c but commented out due to no
-// current usage.  Un-comment (and TEST IT) if required.
-//Bool VG_(isEmptyFM)( WordFM* fm );
-
 // set up FM for iteration
 void VG_(initIterFM) ( WordFM* fm );
 
@@ -148,21 +144,18 @@
 Bool VG_(nextIterFM) ( WordFM* fm,
                        /*OUT*/UWord* pKey, /*OUT*/UWord* pVal );
 
-// clear the I'm iterating flag
+// Finish an FM iteration
 void VG_(doneIterFM) ( WordFM* fm );
 
 // Deep copy a FM.  If dopyK is NULL, keys are copied verbatim.
 // If non-null, dopyK is applied to each key to generate the
-// version in the new copy.  In that case, if the argument to dopyK
-// is non-NULL but the result is NULL, it is assumed that dopyK
-// could not allocate memory, in which case the copy is abandoned
-// and NULL is returned.  Ditto with dopyV for values.
+// version in the new copy.  dopyK may be called with a NULL argument
+// in which case it should return NULL. For all other argument values
+// dopyK must not return NULL. Ditto with dopyV for values.
+// VG_(dopyFM) never returns NULL.
 WordFM* VG_(dopyFM) ( WordFM* fm,
                       UWord(*dopyK)(UWord), UWord(*dopyV)(UWord) );
 
-// admin: what's the 'common' allocation size (for tree nodes?)
-SizeT VG_(getNodeSizeFM)( void );
-
 //------------------------------------------------------------------//
 //---                         end WordFM                         ---//
 //---                      Public interface                      ---//
@@ -175,7 +168,7 @@
 
 typedef  struct _WordBag  WordBag; /* opaque */
 
-/* Allocate and initialise a WordBag */
+/* Allocate and initialise a WordBag. Never returns NULL. */
 WordBag* VG_(newBag) ( void* (*alloc_nofail)( const HChar* cc, SizeT ),
                        const HChar* cc,
                        void  (*dealloc)(void*) );