PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_string.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 89 90 98.9 %
Date: 2014-04-16 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        | 
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Dmitry Stogov <dmitry@zend.com>                             |
      16             :    +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : /* $Id: $ */
      20             : 
      21             : #include "zend.h"
      22             : #include "zend_globals.h"
      23             : 
      24             : #ifndef ZEND_DEBUG_INTERNED_STRINGS
      25             : # define ZEND_DEBUG_INTERNED_STRINGS 0
      26             : #endif
      27             : 
      28             : #if ZEND_DEBUG_INTERNED_STRINGS
      29             : # include <sys/mman.h>
      30             : #endif
      31             : 
      32             : ZEND_API const char *(*zend_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
      33             : ZEND_API void (*zend_interned_strings_snapshot)(TSRMLS_D);
      34             : ZEND_API void (*zend_interned_strings_restore)(TSRMLS_D);
      35             : 
      36             : static const char *zend_new_interned_string_int(const char *str, int len, int free_src TSRMLS_DC);
      37             : static void zend_interned_strings_snapshot_int(TSRMLS_D);
      38             : static void zend_interned_strings_restore_int(TSRMLS_D);
      39             : 
      40       21159 : void zend_interned_strings_init(TSRMLS_D)
      41             : {
      42             : #ifndef ZTS
      43       21159 :         size_t size = 1024 * 1024;
      44             : 
      45             : #if ZEND_DEBUG_INTERNED_STRINGS
      46             :         CG(interned_strings_start) = valloc(size);
      47             : #else
      48       21159 :         CG(interned_strings_start) = malloc(size);
      49             : #endif
      50             : 
      51       21159 :         CG(interned_strings_top) = CG(interned_strings_start);
      52       21159 :         CG(interned_strings_snapshot_top) = CG(interned_strings_start);
      53       21159 :         CG(interned_strings_end) = CG(interned_strings_start) + size;
      54             : 
      55       21159 :         zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
      56             :         
      57       21159 :         CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
      58       21159 :         CG(interned_strings).arBuckets = (Bucket **) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket *), CG(interned_strings).persistent);
      59             : 
      60             : #if ZEND_DEBUG_INTERNED_STRINGS
      61             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
      62             : #endif
      63             : 
      64             :     /* interned empty string */
      65       21159 :         CG(interned_empty_string) = zend_new_interned_string_int("", sizeof(""), 0 TSRMLS_CC);
      66             : #endif
      67             : 
      68       21159 :         zend_new_interned_string = zend_new_interned_string_int;
      69       21159 :         zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
      70       21159 :         zend_interned_strings_restore = zend_interned_strings_restore_int;
      71       21159 : }
      72             : 
      73       21192 : void zend_interned_strings_dtor(TSRMLS_D)
      74             : {
      75             : #ifndef ZTS
      76             : #if ZEND_DEBUG_INTERNED_STRINGS
      77             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
      78             : #endif
      79       21192 :         free(CG(interned_strings).arBuckets);
      80       21192 :         free(CG(interned_strings_start));
      81             : #endif
      82       21192 : }
      83             : 
      84    95881532 : static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
      85             : {
      86             : #ifndef ZTS
      87             :         ulong h;
      88             :         uint nIndex;
      89             :         Bucket *p;
      90             : 
      91    95881532 :         if (IS_INTERNED(arKey)) {
      92       44816 :                 return arKey;
      93             :         }
      94             : 
      95    95836716 :         h = zend_inline_hash_func(arKey, nKeyLength);
      96    95836716 :         nIndex = h & CG(interned_strings).nTableMask;
      97    95836716 :         p = CG(interned_strings).arBuckets[nIndex];
      98   253397942 :         while (p != NULL) {
      99    77870569 :                 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
     100    16146085 :                         if (!memcmp(p->arKey, arKey, nKeyLength)) {
     101    16146059 :                                 if (free_src) {
     102    15616312 :                                         efree((void *)arKey);
     103             :                                 }
     104    16146059 :                                 return p->arKey;
     105             :                         }
     106             :                 }
     107    61724510 :                 p = p->pNext;
     108             :         }
     109             :         
     110   159381314 :         if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
     111    79690657 :             CG(interned_strings_end)) {
     112             :             /* no memory */
     113       31556 :                 return arKey;
     114             :         }
     115             : 
     116    79659101 :         p = (Bucket *) CG(interned_strings_top);
     117    79659101 :         CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
     118             : 
     119             : #if ZEND_DEBUG_INTERNED_STRINGS
     120             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
     121             : #endif
     122             :         
     123    79659101 :         p->arKey = (char*)(p+1);
     124    79659101 :         memcpy((char*)p->arKey, arKey, nKeyLength);
     125    79659101 :         if (free_src) {
     126    74599157 :                 efree((void *)arKey);
     127             :         }
     128    79659101 :         p->nKeyLength = nKeyLength;
     129    79659101 :         p->h = h;
     130    79659101 :         p->pData = &p->pDataPtr;
     131    79659101 :         p->pDataPtr = p;
     132             :         
     133    79659101 :         p->pNext = CG(interned_strings).arBuckets[nIndex];
     134    79659101 :         p->pLast = NULL;
     135    79659101 :         if (p->pNext) {
     136    40902726 :                 p->pNext->pLast = p;
     137             :         }
     138             : 
     139    79659101 :         HANDLE_BLOCK_INTERRUPTIONS();
     140             :         
     141    79659101 :         p->pListLast = CG(interned_strings).pListTail;
     142    79659101 :         CG(interned_strings).pListTail = p;
     143    79659101 :         p->pListNext = NULL;
     144    79659101 :         if (p->pListLast != NULL) {
     145    79637942 :                 p->pListLast->pListNext = p;
     146             :         }
     147    79659101 :         if (!CG(interned_strings).pListHead) {
     148       21159 :                 CG(interned_strings).pListHead = p;
     149             :         }
     150             : 
     151    79659101 :         CG(interned_strings).arBuckets[nIndex] = p;
     152             : 
     153    79659101 :         HANDLE_UNBLOCK_INTERRUPTIONS();
     154             : 
     155    79659101 :         CG(interned_strings).nNumOfElements++;
     156             : 
     157    79659101 :         if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
     158      190438 :                 if ((CG(interned_strings).nTableSize << 1) > 0) {      /* Let's double the table size */
     159      190438 :                         Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
     160             : 
     161      190438 :                         if (t) {
     162      190438 :                                 HANDLE_BLOCK_INTERRUPTIONS();
     163      190438 :                                 CG(interned_strings).arBuckets = t;
     164      190438 :                                 CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
     165      190438 :                                 CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
     166      190438 :                                 zend_hash_rehash(&CG(interned_strings));
     167      190438 :                                 HANDLE_UNBLOCK_INTERRUPTIONS();
     168             :                         }
     169             :                 }
     170             :         }
     171             : 
     172             : #if ZEND_DEBUG_INTERNED_STRINGS
     173             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
     174             : #endif
     175             : 
     176    79659101 :         return p->arKey;
     177             : #else
     178             :         return arKey;
     179             : #endif
     180             : }
     181             : 
     182       20805 : static void zend_interned_strings_snapshot_int(TSRMLS_D)
     183             : {
     184       20805 :         CG(interned_strings_snapshot_top) = CG(interned_strings_top);
     185       20805 : }
     186             : 
     187       20797 : static void zend_interned_strings_restore_int(TSRMLS_D)
     188             : {
     189             : #ifndef ZTS
     190             :         Bucket *p;
     191             :         int i;
     192             : #endif
     193             : 
     194       20797 :         CG(interned_strings_top) = CG(interned_strings_snapshot_top);
     195             : 
     196             : #ifndef ZTS
     197             : #if ZEND_DEBUG_INTERNED_STRINGS
     198             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
     199             : #endif
     200             : 
     201    85238077 :         for (i = 0; i < CG(interned_strings).nTableSize; i++) {
     202    85217280 :                 p = CG(interned_strings).arBuckets[i];
     203   170923248 :                 while (p && p->arKey > CG(interned_strings_top)) {
     204      488688 :                         CG(interned_strings).nNumOfElements--;
     205      488688 :                         if (p->pListLast != NULL) {
     206      488688 :                                 p->pListLast->pListNext = p->pListNext;
     207             :                         } else { 
     208           0 :                                 CG(interned_strings).pListHead = p->pListNext;
     209             :                         }
     210      488688 :                         if (p->pListNext != NULL) {
     211      428335 :                                 p->pListNext->pListLast = p->pListLast;
     212             :                         } else {
     213       60353 :                                 CG(interned_strings).pListTail = p->pListLast;
     214             :                         }
     215      488688 :                         p = p->pNext;
     216             :                 }
     217    85217280 :                 if (p) {
     218    50810598 :                         p->pLast = NULL;
     219             :                 }
     220    85217280 :                 CG(interned_strings).arBuckets[i] = p;
     221             :         }
     222             : 
     223             : #if ZEND_DEBUG_INTERNED_STRINGS
     224             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
     225             : #endif
     226             : #endif
     227       20797 : }
     228             : 
     229             : /*
     230             :  * Local variables:
     231             :  * tab-width: 4
     232             :  * c-basic-offset: 4
     233             :  * indent-tabs-mode: t
     234             :  * End:
     235             :  */

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:41 +0000 (7 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.