LCOV - code coverage report
Current view: top level - mm - dumpmemory.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 37 94.6 %
Date: 2015-06-10 18:10:59 Functions: 9 14 64.3 %

          Line data    Source code
       1             : /* src/mm/dumpmemory.cpp - dump memory management
       2             : 
       3             :    Copyright (C) 1996-2013
       4             :    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
       5             :    Copyright (C) 2008 Theobroma Systems Ltd.
       6             : 
       7             :    This file is part of CACAO.
       8             : 
       9             :    This program is free software; you can redistribute it and/or
      10             :    modify it under the terms of the GNU General Public License as
      11             :    published by the Free Software Foundation; either version 2, or (at
      12             :    your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful, but
      15             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :    General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program; if not, write to the Free Software
      21             :    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
      22             :    02110-1301, USA.
      23             : 
      24             : */
      25             : 
      26             : #include "mm/dumpmemory.hpp"
      27             : #include <stdio.h>                      // for fprintf, stderr
      28             : #include "config.h"                     // for ENABLE_MEMCHECK, etc
      29             : #include "mm/memory.hpp"                // for MEMORY_CANARY_SIZE, etc
      30             : #include "vm/os.hpp"                    // for os
      31             : #include "vm/vm.hpp"                    // for vm_abort
      32             : #include "vm/options.hpp"
      33             : 
      34             : STAT_DECLARE_GROUP(max_mem_stat)
      35             : STAT_DECLARE_GROUP(not_freed_mem_stat)
      36             : STAT_REGISTER_GROUP_VAR(int,maxdumpsize,0,"maxdumpsize","max. dump memory",max_mem_stat)
      37             : STAT_REGISTER_GROUP_VAR(int,globalallocateddumpsize,0,"globalallocateddumpsize","dump memory not freed",not_freed_mem_stat)
      38             : 
      39             : /*******************************************************************************
      40             : 
      41             :   This structure is used for dump memory allocation if cacao
      42             :   runs without threads.
      43             : 
      44             : *******************************************************************************/
      45             : 
      46             : /**
      47             :  * Allocate a new thread-local dump memory structure.
      48             :  */
      49         793 : DumpMemory::DumpMemory() : _size(0), _used(0)
      50             : {
      51         793 : }
      52             : 
      53             : 
      54             : /**
      55             :  * Stupid realloc implementation for dump memory.  Avoid, if possible.
      56             :  */
      57         174 : void* DumpMemory::reallocate(void* src, size_t len1, size_t len2)
      58             : {
      59         174 :         void* dst = allocate(len2);
      60             : 
      61         174 :         (void) os::memcpy(dst, src, len1);
      62             : 
      63             : #if defined(ENABLE_MEMCHECK)
      64             :         // Destroy the source.
      65             :         (void) os::memset(src, MEMORY_CLEAR_BYTE, len1);
      66             : #endif
      67             : 
      68         174 :         return dst;
      69             : }
      70             : 
      71             : 
      72             : /**
      73             :  * Add the given dump area to the area list.
      74             :  *
      75             :  * @param dm Pointer to dump area.
      76             :  */
      77     1305236 : void DumpMemory::add_area(DumpMemoryArea* dma)
      78             : {
      79     1305236 :         _areas.push_back(dma);
      80             : 
      81             :         // Increase the size count of the dump memory.
      82     1305221 :         _size += dma->get_size();
      83             : 
      84             :         STATISTICS(maxdumpsize.max(_size));
      85     1305211 : }
      86             : 
      87             : 
      88             : /**
      89             :  * Remove the given dump area from the area list.
      90             :  *
      91             :  * @param dm Pointer to dump area.
      92             :  */
      93     1305102 : void DumpMemory::remove_area(DumpMemoryArea* dma)
      94             : {
      95             :         // Sanity check.
      96     1305102 :         assert(_areas.back() == dma);
      97             : 
      98             :         // Remove the last area from the list.  The check above guarantees
      99             :         // we are removing the correct area.
     100     1305101 :         _areas.pop_back();
     101             : 
     102             :         // Decrease the size and used count.
     103     1305103 :         _size -= dma->get_size();
     104     1305101 :         _used -= dma->get_used();
     105     1305102 : }
     106             : 
     107             : 
     108             : /**
     109             :  * Allocate a new dump memory area.
     110             :  *
     111             :  * @ param size Required memory size.
     112             :  */
     113     1305229 : DumpMemoryArea::DumpMemoryArea(size_t size) : _size(0), _used(0)
     114             : {
     115             :         // Get the DumpMemory object of the current thread.
     116     1305232 :         DumpMemory* dm = DumpMemory::get_current();
     117             : 
     118             :         // Add this area to the areas list.
     119     1305229 :         dm->add_area(this);
     120           0 : }
     121             : 
     122             : 
     123             : /**
     124             :  * Release all dump memory blocks in the current dump area.
     125             :  */
     126     1305098 : DumpMemoryArea::~DumpMemoryArea()
     127             : {
     128             :         // Get the DumpMemory object of the current thread.
     129     1305098 :         DumpMemory* dm = DumpMemory::get_current();
     130             : 
     131             : #if defined(ENABLE_MEMCHECK)
     132             :         // Check canaries.
     133             : 
     134             :         check_canaries();
     135             : 
     136             :         // Iterate over all dump memory allocations about to be released.
     137             : 
     138             :         for (std::vector<DumpMemoryAllocation*>::iterator it = _allocs.begin(); it != _allocs.end(); it++) {
     139             :                 DumpMemoryAllocation* dma = *it;
     140             : 
     141             :                 // Invalidate the freed memory.
     142             :                 (void) os::memset(dma->get_mem(), MEMORY_CLEAR_BYTE, dma->get_size());
     143             : 
     144             :                 // Call the destructor of the current allocation.
     145             :                 delete dma;
     146             :         }
     147             : #endif /* defined(ENABLE_MEMCHECK) */
     148             : 
     149             :         // Free all memory blocks.
     150     2850596 :         for (std::vector<DumpMemoryBlock*>::iterator it = _blocks.begin(); it != _blocks.end(); it++) {
     151             :                 // Call the destructor of the current block.
     152     1545493 :                 delete *it;
     153             :         }
     154             : 
     155             :         // Remove this area for the area list.
     156     1305103 :         dm->remove_area(this);
     157           0 : }
     158             : 
     159             : 
     160             : /**
     161             :  * Allocate a dump memory block for the current dump memory area.
     162             :  *
     163             :  * @param size Required memory size.
     164             :  *
     165             :  * @return Pointer to the newly allocated block.
     166             :  */
     167     1545631 : DumpMemoryBlock* DumpMemoryArea::allocate_new_block(size_t size)
     168             : {
     169     1545631 :         DumpMemoryBlock* dmb = new DumpMemoryBlock(size);
     170     1545621 :         _blocks.push_back(dmb);
     171             : 
     172             : #if defined(ENABLE_STATISTICS)
     173             :         DumpMemory* dm = DumpMemory::get_current();
     174             :         dm->add_size(dmb->get_size());
     175             : 
     176             :         STATISTICS(maxdumpsize.max(dm->get_size()));
     177             : #endif
     178             : 
     179     1545635 :         return dmb;
     180             : }
     181             : 
     182             : 
     183             : /**
     184             :  * Checks canaries in this dump memory area. If any canary has been changed,
     185             :  * this function aborts the VM with an error message.
     186             :  */
     187             : #if defined(ENABLE_MEMCHECK)
     188             : void DumpMemoryArea::check_canaries()
     189             : {
     190             :         uint8_t* pm;
     191             : 
     192             :         // Iterate over all dump memory allocations.
     193             : 
     194             :         for (std::vector<DumpMemoryAllocation*>::iterator it = _allocs.begin(); it != _allocs.end(); it++) {
     195             :                 DumpMemoryAllocation* dma = *it;
     196             : 
     197             :                 // Check canaries.
     198             : 
     199             :                 pm = ((uint8_t *) dma->get_mem()) - MEMORY_CANARY_SIZE;
     200             : 
     201             :                 for (int i = 0; i < MEMORY_CANARY_SIZE; ++i) {
     202             :                         if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
     203             :                                 fprintf(stderr, "canary bytes:");
     204             : 
     205             :                                 for (int j = 0; j < MEMORY_CANARY_SIZE; ++j)
     206             :                                         fprintf(stderr, " %02x", pm[j]);
     207             : 
     208             :                                 fprintf(stderr,"\n");
     209             : 
     210             :                                 vm_abort("error: dump memory bottom canary killed: "
     211             :                                                  "%p (%d bytes allocated at %p)\n",
     212             :                                                  pm + i, dma->get_size(), dma->get_mem());
     213             :                         }
     214             :                 }
     215             : 
     216             :                 pm = ((uint8_t *) dma->get_mem()) + dma->get_size();
     217             : 
     218             :                 for (int i = 0; i < MEMORY_CANARY_SIZE; ++i) {
     219             :                         if (pm[i] != i + MEMORY_CANARY_FIRST_BYTE) {
     220             :                                 fprintf(stderr, "canary bytes:");
     221             : 
     222             :                                 for (int j = 0; j < MEMORY_CANARY_SIZE; ++j)
     223             :                                         fprintf(stderr, " %02x", pm[j]);
     224             : 
     225             :                                 fprintf(stderr, "\n");
     226             : 
     227             :                                 vm_abort("error: dump memory top canary killed: "
     228             :                                                  "%p (%d bytes allocated at %p)\n",
     229             :                                                  pm + i, dma->get_size(), dma->get_mem());
     230             :                         }
     231             :                 }
     232             :         }
     233             : }
     234             : #endif /* defined(ENABLE_MEMCHECK) */
     235             : 
     236             : 
     237             : /**
     238             :  * Allocate a memory block for the current dump memory block.
     239             :  *
     240             :  * @param size Required memory size.
     241             :  */
     242     1545635 : DumpMemoryBlock::DumpMemoryBlock(size_t size) : _size(0), _used(0), _block(0)
     243             : {
     244             :         // If requested size is greater than the default, make the new
     245             :         // memory block as big as the requested size.  Otherwise use the
     246             :         // default size.
     247     1545635 :         _size = (size > DEFAULT_SIZE) ? size : DEFAULT_SIZE;
     248             : 
     249             :         // Allocate a memory block.
     250     1545635 :         _block = memory_checked_alloc(_size);
     251             : 
     252             :         // The amount of globally allocated dump memory (thread safe).
     253             :         STATISTICS(globalallocateddumpsize += _size);
     254     1545621 : }
     255             : 
     256             : 
     257             : /**
     258             :  * Release the memory block for the dump memory block.
     259             :  *
     260             :  * @param size Required memory size.
     261             :  */
     262     1545491 : DumpMemoryBlock::~DumpMemoryBlock()
     263             : {
     264             :         // Release the memory block.
     265     1545491 :         mem_free(_block, /* XXX */ 1);
     266             : 
     267             :         // The amount of globally allocated dump memory (thread safe).
     268             :         STATISTICS(globalallocateddumpsize -= _size);
     269     1545496 : }
     270             : 
     271             : /*
     272             :  * These are local overrides for various environment variables in Emacs.
     273             :  * Please do not remove this and leave it at the end of the file, where
     274             :  * Emacs will automagically detect them.
     275             :  * ---------------------------------------------------------------------
     276             :  * Local variables:
     277             :  * mode: c++
     278             :  * indent-tabs-mode: t
     279             :  * c-basic-offset: 4
     280             :  * tab-width: 4
     281             :  * End:
     282             :  * vim:noexpandtab:sw=4:ts=4:
     283             :  */

Generated by: LCOV version 1.11