LCOV - code coverage report
Current view: top level - sal/rtl/source - alloc_global.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 98 103 95.1 %
Date: 2012-08-25 Functions: 14 14 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 43 56 76.8 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include "alloc_impl.hxx"
      30                 :            : #include "rtl/alloc.h"
      31                 :            : #include <sal/log.hxx>
      32                 :            : #include <sal/macros.h>
      33                 :            : 
      34                 :            : #include <cassert>
      35                 :            : #include <string.h>
      36                 :            : #include <stdio.h>
      37                 :            : 
      38                 :            : #include "internal/rtllifecycle.h"
      39                 :            : 
      40                 :            : AllocMode alloc_mode = AMode_UNSET;
      41                 :            : 
      42                 :            : #if !defined(FORCE_SYSALLOC)
      43                 :       3013 : static void determine_alloc_mode()
      44                 :            : {
      45                 :            :     assert(alloc_mode == AMode_UNSET);
      46                 :       3013 :     alloc_mode = (getenv("G_SLICE") == NULL ? AMode_CUSTOM : AMode_SYSTEM);
      47                 :       3013 : }
      48                 :            : 
      49                 :            : /* ================================================================= *
      50                 :            :  *
      51                 :            :  * custom allocator includes.
      52                 :            :  *
      53                 :            :  * ================================================================= */
      54                 :            : 
      55                 :            : #include "sal/macros.h"
      56                 :            : 
      57                 :            : /* ================================================================= *
      58                 :            :  *
      59                 :            :  * custom allocator internals.
      60                 :            :  *
      61                 :            :  * ================================================================= */
      62                 :            : 
      63                 :            : static const sal_Size g_alloc_sizes[] =
      64                 :            : {
      65                 :            :     /* powers of 2**(1/4) */
      66                 :            :     4 *    4,           6 *    4,
      67                 :            :     4 *    8, 5 *    8, 6 *    8, 7 *    8,
      68                 :            :     4 *   16, 5 *   16, 6 *   16, 7 *   16,
      69                 :            :     4 *   32, 5 *   32, 6 *   32, 7 *   32,
      70                 :            :     4 *   64, 5 *   64, 6 *   64, 7 *   64,
      71                 :            :     4 *  128, 5 *  128, 6 *  128, 7 *  128,
      72                 :            :     4 *  256, 5 *  256, 6 *  256, 7 *  256,
      73                 :            :     4 *  512, 5 *  512, 6 *  512, 7 *  512,
      74                 :            :     4 * 1024, 5 * 1024, 6 * 1024, 7 * 1024,
      75                 :            :     4 * 2048, 5 * 2048, 6 * 2048, 7 * 2048,
      76                 :            :     4 * 4096
      77                 :            : };
      78                 :            : 
      79                 :            : #define RTL_MEMORY_CACHED_LIMIT 4 * 4096
      80                 :            : #define RTL_MEMORY_CACHED_SIZES (SAL_N_ELEMENTS(g_alloc_sizes))
      81                 :            : 
      82                 :            : static rtl_cache_type * g_alloc_caches[RTL_MEMORY_CACHED_SIZES] =
      83                 :            : {
      84                 :            :     0,
      85                 :            : };
      86                 :            : 
      87                 :            : #define RTL_MEMALIGN       8
      88                 :            : #define RTL_MEMALIGN_SHIFT 3
      89                 :            : 
      90                 :            : static rtl_cache_type * g_alloc_table[RTL_MEMORY_CACHED_LIMIT >> RTL_MEMALIGN_SHIFT] =
      91                 :            : {
      92                 :            :     0,
      93                 :            : };
      94                 :            : 
      95                 :            : static rtl_arena_type * gp_alloc_arena = 0;
      96                 :            : 
      97                 :            : /* ================================================================= *
      98                 :            :  *
      99                 :            :  * custom allocator implemenation.
     100                 :            :  *
     101                 :            :  * ================================================================= */
     102                 :            : 
     103                 :            : void *
     104                 :  129625921 : SAL_CALL rtl_allocateMemory_CUSTOM (sal_Size n) SAL_THROW_EXTERN_C()
     105                 :            : {
     106                 :  129625921 :     void * p = 0;
     107         [ +  + ]:  129625921 :     if (n > 0)
     108                 :            :     {
     109                 :            :         char *     addr;
     110                 :  129580212 :         sal_Size   size = RTL_MEMORY_ALIGN(n + RTL_MEMALIGN, RTL_MEMALIGN);
     111                 :            : 
     112                 :            :         assert(RTL_MEMALIGN >= sizeof(sal_Size));
     113         [ -  + ]:  129580212 :         if (n >= SAL_MAX_SIZE - (RTL_MEMALIGN + RTL_MEMALIGN - 1))
     114                 :            :         {
     115                 :            :             /* requested size too large for roundup alignment */
     116                 :          0 :             return 0;
     117                 :            :         }
     118                 :            : 
     119                 :            : try_alloc:
     120         [ +  + ]:  129582954 :         if (size <= RTL_MEMORY_CACHED_LIMIT)
     121                 :  129473172 :             addr = (char*)rtl_cache_alloc(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT]);
     122                 :            :         else
     123                 :     109782 :             addr = (char*)rtl_arena_alloc (gp_alloc_arena, &size);
     124                 :            : 
     125         [ +  + ]:  129582954 :         if (addr != 0)
     126                 :            :         {
     127                 :  129580212 :             ((sal_Size*)(addr))[0] = size;
     128                 :  129580212 :             p = addr + RTL_MEMALIGN;
     129                 :            :         }
     130         [ +  - ]:       2742 :         else if (gp_alloc_arena == 0)
     131                 :            :         {
     132         [ +  - ]:       2742 :             ensureMemorySingleton();
     133         [ +  - ]:       2742 :             if (gp_alloc_arena)
     134                 :            :             {
     135                 :            :                 /* try again */
     136                 :  129582954 :                 goto try_alloc;
     137                 :            :             }
     138                 :            :         }
     139                 :            :     }
     140                 :  129625921 :     return (p);
     141                 :            : }
     142                 :            : 
     143                 :            : /* ================================================================= */
     144                 :            : 
     145                 :  126574105 : void SAL_CALL rtl_freeMemory_CUSTOM (void * p) SAL_THROW_EXTERN_C()
     146                 :            : {
     147         [ +  + ]:  126574105 :     if (p != 0)
     148                 :            :     {
     149                 :  126538499 :         char *   addr = (char*)(p) - RTL_MEMALIGN;
     150                 :  126538499 :         sal_Size size = ((sal_Size*)(addr))[0];
     151                 :            : 
     152         [ +  + ]:  126538499 :         if (size <= RTL_MEMORY_CACHED_LIMIT)
     153                 :  126429871 :             rtl_cache_free(g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT], addr);
     154                 :            :         else
     155                 :     108628 :             rtl_arena_free (gp_alloc_arena, addr, size);
     156                 :            :     }
     157                 :  126574105 : }
     158                 :            : 
     159                 :            : /* ================================================================= */
     160                 :            : 
     161                 :    5500105 : void * SAL_CALL rtl_reallocateMemory_CUSTOM (void * p, sal_Size n) SAL_THROW_EXTERN_C()
     162                 :            : {
     163         [ +  - ]:    5500105 :     if (n > 0)
     164                 :            :     {
     165         [ +  - ]:    5500105 :         if (p != 0)
     166                 :            :         {
     167                 :    5500105 :             void *   p_old = p;
     168                 :    5500105 :             sal_Size n_old = ((sal_Size*)( (char*)(p) - RTL_MEMALIGN  ))[0] - RTL_MEMALIGN;
     169                 :            : 
     170                 :    5500105 :             p = rtl_allocateMemory (n);
     171         [ +  - ]:    5500105 :             if (p != 0)
     172                 :            :             {
     173         [ +  + ]:    5500105 :                 memcpy (p, p_old, SAL_MIN(n, n_old));
     174                 :    5500105 :                 rtl_freeMemory (p_old);
     175                 :            :             }
     176                 :            :         }
     177                 :            :         else
     178                 :            :         {
     179                 :          0 :             p = rtl_allocateMemory (n);
     180                 :            :         }
     181                 :            :     }
     182         [ #  # ]:          0 :     else if (p != 0)
     183                 :            :     {
     184                 :          0 :         rtl_freeMemory (p), p = 0;
     185                 :            :     }
     186                 :    5500105 :     return (p);
     187                 :            : }
     188                 :            : 
     189                 :            : #endif
     190                 :            : 
     191                 :            : /* ================================================================= *
     192                 :            :  *
     193                 :            :  * custom allocator initialization / finalization.
     194                 :            :  *
     195                 :            :  * ================================================================= */
     196                 :            : 
     197                 :       2742 : void rtl_memory_init()
     198                 :            : {
     199                 :            : #if !defined(FORCE_SYSALLOC)
     200                 :            :     {
     201                 :            :         /* global memory arena */
     202                 :            :         assert(gp_alloc_arena == 0);
     203                 :            : 
     204                 :            :         gp_alloc_arena = rtl_arena_create (
     205                 :            :             "rtl_alloc_arena",
     206                 :            :             2048,     /* quantum */
     207                 :            :             0,        /* w/o quantum caching */
     208                 :            :             0,        /* default source */
     209                 :            :             rtl_arena_alloc,
     210                 :            :             rtl_arena_free,
     211                 :            :             0         /* flags */
     212                 :       2742 :         );
     213                 :            :         assert(gp_alloc_arena != 0);
     214                 :            :     }
     215                 :            :     {
     216                 :            :         sal_Size size;
     217                 :       2742 :         int i, n = RTL_MEMORY_CACHED_SIZES;
     218                 :            : 
     219         [ +  + ]:     109680 :         for (i = 0; i < n; i++)
     220                 :            :         {
     221                 :            :             char name[RTL_CACHE_NAME_LENGTH + 1];
     222                 :     106938 :             (void) snprintf (name, sizeof(name), "rtl_alloc_%lu", g_alloc_sizes[i]);
     223                 :     106938 :             g_alloc_caches[i] = rtl_cache_create (name, g_alloc_sizes[i], 0, NULL, NULL, NULL, NULL, NULL, 0);
     224                 :            :         }
     225                 :            : 
     226                 :       2742 :         size = RTL_MEMALIGN;
     227         [ +  + ]:     109680 :         for (i = 0; i < n; i++)
     228                 :            :         {
     229         [ +  + ]:    5722554 :             while (size <= g_alloc_sizes[i])
     230                 :            :             {
     231                 :    5615616 :                 g_alloc_table[(size - 1) >> RTL_MEMALIGN_SHIFT] = g_alloc_caches[i];
     232                 :    5615616 :                 size += RTL_MEMALIGN;
     233                 :            :             }
     234                 :            :         }
     235                 :            :     }
     236                 :            : #endif
     237                 :            :     // SAL_INFO("sal", "rtl_memory_init completed");
     238                 :       2742 : }
     239                 :            : 
     240                 :            : /* ================================================================= */
     241                 :            : 
     242                 :       2742 : void rtl_memory_fini()
     243                 :            : {
     244                 :            : #if !defined(FORCE_SYSALLOC)
     245                 :            :     int i, n;
     246                 :            : 
     247                 :            :     /* clear g_alloc_table */
     248                 :       2742 :     memset (g_alloc_table, 0, sizeof(g_alloc_table));
     249                 :            : 
     250                 :            :     /* cleanup g_alloc_caches */
     251         [ +  + ]:     109680 :     for (i = 0, n = RTL_MEMORY_CACHED_SIZES; i < n; i++)
     252                 :            :     {
     253         [ +  - ]:     106938 :         if (g_alloc_caches[i] != 0)
     254                 :            :         {
     255                 :     106938 :             rtl_cache_destroy (g_alloc_caches[i]);
     256                 :     106938 :             g_alloc_caches[i] = 0;
     257                 :            :         }
     258                 :            :     }
     259                 :            : 
     260                 :            :     /* cleanup gp_alloc_arena */
     261         [ +  - ]:       2742 :     if (gp_alloc_arena != 0)
     262                 :            :     {
     263                 :       2742 :         rtl_arena_destroy (gp_alloc_arena);
     264                 :       2742 :         gp_alloc_arena = 0;
     265                 :            :     }
     266                 :            : #endif
     267                 :            :     // SAL_INFO("sal", "rtl_memory_fini completed");
     268                 :       2742 : }
     269                 :            : 
     270                 :            : /* ================================================================= *
     271                 :            :  *
     272                 :            :  * system allocator implemenation.
     273                 :            :  *
     274                 :            :  * ================================================================= */
     275                 :            : 
     276                 :  106202503 : void * SAL_CALL rtl_allocateMemory_SYSTEM (sal_Size n)
     277                 :            : {
     278                 :  106202503 :     return malloc (n);
     279                 :            : }
     280                 :            : 
     281                 :            : /* ================================================================= */
     282                 :            : 
     283                 :  105557097 : void SAL_CALL rtl_freeMemory_SYSTEM (void * p)
     284                 :            : {
     285                 :  105557097 :     free (p);
     286                 :  105557097 : }
     287                 :            : 
     288                 :            : /* ================================================================= */
     289                 :            : 
     290                 :     923936 : void * SAL_CALL rtl_reallocateMemory_SYSTEM (void * p, sal_Size n)
     291                 :            : {
     292                 :     923936 :     return realloc (p, n);
     293                 :            : }
     294                 :            : 
     295                 :            : /* ================================================================= */
     296                 :            : 
     297                 :  235828012 : void* SAL_CALL rtl_allocateMemory (sal_Size n) SAL_THROW_EXTERN_C()
     298                 :            : {
     299                 :            :     SAL_WARN_IF(
     300                 :            :         n >= SAL_MAX_INT32, "sal",
     301                 :            :         "suspicious massive alloc " << n);
     302                 :            : #if !defined(FORCE_SYSALLOC)
     303                 :  235831459 :     while (1)
     304                 :            :     {
     305         [ +  + ]:  235831015 :         if (alloc_mode == AMode_CUSTOM)
     306                 :            :         {
     307                 :  129625920 :             return rtl_allocateMemory_CUSTOM(n);
     308                 :            :         }
     309         [ +  + ]:  106205095 :         if (alloc_mode == AMode_SYSTEM)
     310                 :            :         {
     311                 :  106202092 :             return rtl_allocateMemory_SYSTEM(n);
     312                 :            :         }
     313                 :       3003 :         determine_alloc_mode();
     314                 :            :     }
     315                 :            : #else
     316                 :            :     return rtl_allocateMemory_SYSTEM(n);
     317                 :            : #endif
     318                 :            : }
     319                 :            : 
     320                 :    6424041 : void* SAL_CALL rtl_reallocateMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
     321                 :            : {
     322                 :            :     SAL_WARN_IF(
     323                 :            :         n >= SAL_MAX_INT32, "sal",
     324                 :            :         "suspicious massive alloc " << n);
     325                 :            : #if !defined(FORCE_SYSALLOC)
     326                 :    6424041 :     while (1)
     327                 :            :     {
     328         [ +  + ]:    6424041 :         if (alloc_mode == AMode_CUSTOM)
     329                 :            :         {
     330                 :    5500105 :             return rtl_reallocateMemory_CUSTOM(p,n);
     331                 :            :         }
     332         [ +  - ]:     923936 :         if (alloc_mode == AMode_SYSTEM)
     333                 :            :         {
     334                 :     923936 :             return rtl_reallocateMemory_SYSTEM(p,n);
     335                 :            :         }
     336                 :          0 :         determine_alloc_mode();
     337                 :            :     }
     338                 :            : #else
     339                 :            :     return rtl_reallocateMemory_SYSTEM(p,n);
     340                 :            : #endif
     341                 :            : }
     342                 :            : 
     343                 :  232131059 : void SAL_CALL rtl_freeMemory (void * p) SAL_THROW_EXTERN_C()
     344                 :            : {
     345                 :            : #if !defined(FORCE_SYSALLOC)
     346                 :         10 :     while (1)
     347                 :            :     {
     348         [ +  + ]:  232131059 :         if (alloc_mode == AMode_CUSTOM)
     349                 :            :         {
     350                 :  126574104 :             rtl_freeMemory_CUSTOM(p);
     351                 :  232131377 :             return;
     352                 :            :         }
     353         [ +  + ]:  105556955 :         if (alloc_mode == AMode_SYSTEM)
     354                 :            :         {
     355                 :  105556945 :             rtl_freeMemory_SYSTEM(p);
     356                 :  105557272 :             return;
     357                 :            :         }
     358                 :         10 :         determine_alloc_mode();
     359                 :            :     }
     360                 :            : #else
     361                 :            :     rtl_freeMemory_SYSTEM(p);
     362                 :            : #endif
     363                 :            : }
     364                 :            : 
     365                 :            : /* ================================================================= *
     366                 :            :  *
     367                 :            :  * rtl_(allocate|free)ZeroMemory() implemenation.
     368                 :            :  *
     369                 :            :  * ================================================================= */
     370                 :            : 
     371                 :      68140 : void * SAL_CALL rtl_allocateZeroMemory (sal_Size n) SAL_THROW_EXTERN_C()
     372                 :            : {
     373                 :      68140 :     void * p = rtl_allocateMemory (n);
     374         [ +  + ]:      68140 :     if (p != 0)
     375                 :      22436 :         memset (p, 0, n);
     376                 :      68140 :     return (p);
     377                 :            : }
     378                 :            : 
     379                 :            : /* ================================================================= */
     380                 :            : 
     381                 :       2330 : void SAL_CALL rtl_freeZeroMemory (void * p, sal_Size n) SAL_THROW_EXTERN_C()
     382                 :            : {
     383         [ +  - ]:       2330 :     if (p != 0)
     384                 :            :     {
     385                 :       2330 :         memset (p, 0, n);
     386                 :       2330 :         rtl_freeMemory (p);
     387                 :            :     }
     388                 :       2330 : }
     389                 :            : 
     390                 :            : /* ================================================================= */
     391                 :            : 
     392                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10