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-08-04 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       21265 : void zend_interned_strings_init(TSRMLS_D)
      41             : {
      42             : #ifndef ZTS
      43       21265 :         size_t size = 1024 * 1024;
      44             : 
      45             : #if ZEND_DEBUG_INTERNED_STRINGS
      46             :         CG(interned_strings_start) = valloc(size);
      47             : #else
      48       21265 :         CG(interned_strings_start) = malloc(size);
      49             : #endif
      50             : 
      51       21265 :         CG(interned_strings_top) = CG(interned_strings_start);
      52       21265 :         CG(interned_strings_snapshot_top) = CG(interned_strings_start);
      53       21265 :         CG(interned_strings_end) = CG(interned_strings_start) + size;
      54             : 
      55       21265 :         zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
      56             :         
      57       21265 :         CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
      58       21265 :         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       21265 :         CG(interned_empty_string) = zend_new_interned_string_int("", sizeof(""), 0 TSRMLS_CC);
      66             : #endif
      67             : 
      68       21265 :         zend_new_interned_string = zend_new_interned_string_int;
      69       21265 :         zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
      70       21265 :         zend_interned_strings_restore = zend_interned_strings_restore_int;
      71       21265 : }
      72             : 
      73       21298 : 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       21298 :         free(CG(interned_strings).arBuckets);
      80       21298 :         free(CG(interned_strings_start));
      81             : #endif
      82       21298 : }
      83             : 
      84    96383772 : 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    96383772 :         if (IS_INTERNED(arKey)) {
      92       45012 :                 return arKey;
      93             :         }
      94             : 
      95    96338760 :         h = zend_inline_hash_func(arKey, nKeyLength);
      96    96338760 :         nIndex = h & CG(interned_strings).nTableMask;
      97    96338760 :         p = CG(interned_strings).arBuckets[nIndex];
      98   254733223 :         while (p != NULL) {
      99    78282908 :                 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
     100    16227231 :                         if (!memcmp(p->arKey, arKey, nKeyLength)) {
     101    16227205 :                                 if (free_src) {
     102    15694808 :                                         efree((void *)arKey);
     103             :                                 }
     104    16227205 :                                 return p->arKey;
     105             :                         }
     106             :                 }
     107    62055703 :                 p = p->pNext;
     108             :         }
     109             :         
     110   160223110 :         if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
     111    80111555 :             CG(interned_strings_end)) {
     112             :             /* no memory */
     113       31558 :                 return arKey;
     114             :         }
     115             : 
     116    80079997 :         p = (Bucket *) CG(interned_strings_top);
     117    80079997 :         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    80079997 :         p->arKey = (char*)(p+1);
     124    80079997 :         memcpy((char*)p->arKey, arKey, nKeyLength);
     125    80079997 :         if (free_src) {
     126    74994713 :                 efree((void *)arKey);
     127             :         }
     128    80079997 :         p->nKeyLength = nKeyLength;
     129    80079997 :         p->h = h;
     130    80079997 :         p->pData = &p->pDataPtr;
     131    80079997 :         p->pDataPtr = p;
     132             :         
     133    80079997 :         p->pNext = CG(interned_strings).arBuckets[nIndex];
     134    80079997 :         p->pLast = NULL;
     135    80079997 :         if (p->pNext) {
     136    41129471 :                 p->pNext->pLast = p;
     137             :         }
     138             : 
     139    80079997 :         HANDLE_BLOCK_INTERRUPTIONS();
     140             :         
     141    80079997 :         p->pListLast = CG(interned_strings).pListTail;
     142    80079997 :         CG(interned_strings).pListTail = p;
     143    80079997 :         p->pListNext = NULL;
     144    80079997 :         if (p->pListLast != NULL) {
     145    80058732 :                 p->pListLast->pListNext = p;
     146             :         }
     147    80079997 :         if (!CG(interned_strings).pListHead) {
     148       21265 :                 CG(interned_strings).pListHead = p;
     149             :         }
     150             : 
     151    80079997 :         CG(interned_strings).arBuckets[nIndex] = p;
     152             : 
     153    80079997 :         HANDLE_UNBLOCK_INTERRUPTIONS();
     154             : 
     155    80079997 :         CG(interned_strings).nNumOfElements++;
     156             : 
     157    80079997 :         if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
     158      191392 :                 if ((CG(interned_strings).nTableSize << 1) > 0) {      /* Let's double the table size */
     159      191392 :                         Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
     160             : 
     161      191392 :                         if (t) {
     162      191392 :                                 HANDLE_BLOCK_INTERRUPTIONS();
     163      191392 :                                 CG(interned_strings).arBuckets = t;
     164      191392 :                                 CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
     165      191392 :                                 CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
     166      191392 :                                 zend_hash_rehash(&CG(interned_strings));
     167      191392 :                                 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    80079997 :         return p->arKey;
     177             : #else
     178             :         return arKey;
     179             : #endif
     180             : }
     181             : 
     182       20897 : static void zend_interned_strings_snapshot_int(TSRMLS_D)
     183             : {
     184       20897 :         CG(interned_strings_snapshot_top) = CG(interned_strings_top);
     185       20897 : }
     186             : 
     187       20889 : static void zend_interned_strings_restore_int(TSRMLS_D)
     188             : {
     189             : #ifndef ZTS
     190             :         Bucket *p;
     191             :         int i;
     192             : #endif
     193             : 
     194       20889 :         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    85615001 :         for (i = 0; i < CG(interned_strings).nTableSize; i++) {
     202    85594112 :                 p = CG(interned_strings).arBuckets[i];
     203   171679877 :                 while (p && p->arKey > CG(interned_strings_top)) {
     204      491653 :                         CG(interned_strings).nNumOfElements--;
     205      491653 :                         if (p->pListLast != NULL) {
     206      491653 :                                 p->pListLast->pListNext = p->pListNext;
     207             :                         } else { 
     208           0 :                                 CG(interned_strings).pListHead = p->pListNext;
     209             :                         }
     210      491653 :                         if (p->pListNext != NULL) {
     211      430951 :                                 p->pListNext->pListLast = p->pListLast;
     212             :                         } else {
     213       60702 :                                 CG(interned_strings).pListTail = p->pListLast;
     214             :                         }
     215      491653 :                         p = p->pNext;
     216             :                 }
     217    85594112 :                 if (p) {
     218    51035355 :                         p->pLast = NULL;
     219             :                 }
     220    85594112 :                 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       20889 : }
     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 Mon, 04 Aug 2014 15:48:58 +0000 (25 days ago)

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