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: 88 89 98.9 %
Date: 2014-08-30 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       20225 : void zend_interned_strings_init(TSRMLS_D)
      41             : {
      42             : #ifndef ZTS
      43       20225 :         size_t size = 1024 * 1024;
      44             : 
      45             : #if ZEND_DEBUG_INTERNED_STRINGS
      46             :         CG(interned_strings_start) = valloc(size);
      47             : #else
      48       20225 :         CG(interned_strings_start) = malloc(size);
      49             : #endif
      50             : 
      51       20225 :         CG(interned_strings_top) = CG(interned_strings_start);
      52       20225 :         CG(interned_strings_snapshot_top) = CG(interned_strings_start);
      53       20225 :         CG(interned_strings_end) = CG(interned_strings_start) + size;
      54             : 
      55       20225 :         zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
      56             :         
      57       20225 :         CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
      58       20225 :         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             : #endif
      65             : 
      66       20225 :         zend_new_interned_string = zend_new_interned_string_int;
      67       20225 :         zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
      68       20225 :         zend_interned_strings_restore = zend_interned_strings_restore_int;
      69       20225 : }
      70             : 
      71       20260 : void zend_interned_strings_dtor(TSRMLS_D)
      72             : {
      73             : #ifndef ZTS
      74             : #if ZEND_DEBUG_INTERNED_STRINGS
      75             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
      76             : #endif
      77       20260 :         free(CG(interned_strings).arBuckets);
      78       20260 :         free(CG(interned_strings_start));
      79             : #endif
      80       20260 : }
      81             : 
      82    85185786 : static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
      83             : {
      84             : #ifndef ZTS
      85             :         ulong h;
      86             :         uint nIndex;
      87             :         Bucket *p;
      88             : 
      89    85185786 :         if (IS_INTERNED(arKey)) {
      90       43871 :                 return arKey;
      91             :         }
      92             : 
      93    85141915 :         h = zend_inline_hash_func(arKey, nKeyLength);
      94    85141915 :         nIndex = h & CG(interned_strings).nTableMask;
      95    85141915 :         p = CG(interned_strings).arBuckets[nIndex];
      96   224504587 :         while (p != NULL) {
      97    68178592 :                 if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
      98    13957862 :                         if (!memcmp(p->arKey, arKey, nKeyLength)) {
      99    13957835 :                                 if (free_src) {
     100    13471662 :                                         efree((void *)arKey);
     101             :                                 }
     102    13957835 :                                 return p->arKey;
     103             :                         }
     104             :                 }
     105    54220757 :                 p = p->pNext;
     106             :         }
     107             :         
     108   142368160 :         if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
     109    71184080 :             CG(interned_strings_end)) {
     110             :             /* no memory */
     111      178464 :                 return arKey;
     112             :         }
     113             : 
     114    71005616 :         p = (Bucket *) CG(interned_strings_top);
     115    71005616 :         CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
     116             : 
     117             : #if ZEND_DEBUG_INTERNED_STRINGS
     118             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
     119             : #endif
     120             :         
     121    71005616 :         p->arKey = (char*)(p+1);
     122    71005616 :         memcpy((char*)p->arKey, arKey, nKeyLength);
     123    71005616 :         if (free_src) {
     124    66553690 :                 efree((void *)arKey);
     125             :         }
     126    71005616 :         p->nKeyLength = nKeyLength;
     127    71005616 :         p->h = h;
     128    71005616 :         p->pData = &p->pDataPtr;
     129    71005616 :         p->pDataPtr = p;
     130             :         
     131    71005616 :         p->pNext = CG(interned_strings).arBuckets[nIndex];
     132    71005616 :         p->pLast = NULL;
     133    71005616 :         if (p->pNext) {
     134    35981865 :                 p->pNext->pLast = p;
     135             :         }
     136             : 
     137    71005616 :         HANDLE_BLOCK_INTERRUPTIONS();
     138             :         
     139    71005616 :         p->pListLast = CG(interned_strings).pListTail;
     140    71005616 :         CG(interned_strings).pListTail = p;
     141    71005616 :         p->pListNext = NULL;
     142    71005616 :         if (p->pListLast != NULL) {
     143    70985391 :                 p->pListLast->pListNext = p;
     144             :         }
     145    71005616 :         if (!CG(interned_strings).pListHead) {
     146       20225 :                 CG(interned_strings).pListHead = p;
     147             :         }
     148             : 
     149    71005616 :         CG(interned_strings).arBuckets[nIndex] = p;
     150             : 
     151    71005616 :         HANDLE_UNBLOCK_INTERRUPTIONS();
     152             : 
     153    71005616 :         CG(interned_strings).nNumOfElements++;
     154             : 
     155    71005616 :         if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
     156      182029 :                 if ((CG(interned_strings).nTableSize << 1) > 0) {      /* Let's double the table size */
     157      182029 :                         Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
     158             : 
     159      182029 :                         if (t) {
     160      182029 :                                 HANDLE_BLOCK_INTERRUPTIONS();
     161      182029 :                                 CG(interned_strings).arBuckets = t;
     162      182029 :                                 CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
     163      182029 :                                 CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
     164      182029 :                                 zend_hash_rehash(&CG(interned_strings));
     165      182029 :                                 HANDLE_UNBLOCK_INTERRUPTIONS();
     166             :                         }
     167             :                 }
     168             :         }
     169             : 
     170             : #if ZEND_DEBUG_INTERNED_STRINGS
     171             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
     172             : #endif
     173             : 
     174    71005616 :         return p->arKey;
     175             : #else
     176             :         return arKey;
     177             : #endif
     178             : }
     179             : 
     180       20225 : static void zend_interned_strings_snapshot_int(TSRMLS_D)
     181             : {
     182       20225 :         CG(interned_strings_snapshot_top) = CG(interned_strings_top);
     183       20225 : }
     184             : 
     185       20219 : static void zend_interned_strings_restore_int(TSRMLS_D)
     186             : {
     187             : #ifndef ZTS
     188             :         Bucket *p;
     189             :         int i;
     190             : #endif
     191             : 
     192       20219 :         CG(interned_strings_top) = CG(interned_strings_snapshot_top);
     193             : 
     194             : #ifndef ZTS
     195             : #if ZEND_DEBUG_INTERNED_STRINGS
     196             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
     197             : #endif
     198             : 
     199    82857723 :         for (i = 0; i < CG(interned_strings).nTableSize; i++) {
     200    82837504 :                 p = CG(interned_strings).arBuckets[i];
     201   166181034 :                 while (p && p->arKey > CG(interned_strings_top)) {
     202      506026 :                         CG(interned_strings).nNumOfElements--;
     203      506026 :                         if (p->pListLast != NULL) {
     204      506026 :                                 p->pListLast->pListNext = p->pListNext;
     205             :                         } else { 
     206           0 :                                 CG(interned_strings).pListHead = p->pListNext;
     207             :                         }
     208      506026 :                         if (p->pListNext != NULL) {
     209      447853 :                                 p->pListNext->pListLast = p->pListLast;
     210             :                         } else {
     211       58173 :                                 CG(interned_strings).pListTail = p->pListLast;
     212             :                         }
     213      506026 :                         p = p->pNext;
     214             :                 }
     215    82837504 :                 if (p) {
     216    47233940 :                         p->pLast = NULL;
     217             :                 }
     218    82837504 :                 CG(interned_strings).arBuckets[i] = p;
     219             :         }
     220             : 
     221             : #if ZEND_DEBUG_INTERNED_STRINGS
     222             :         mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
     223             : #endif
     224             : #endif
     225       20219 : }
     226             : 
     227             : /*
     228             :  * Local variables:
     229             :  * tab-width: 4
     230             :  * c-basic-offset: 4
     231             :  * indent-tabs-mode: t
     232             :  * End:
     233             :  */

Generated by: LCOV version 1.10

Generated at Sun, 31 Aug 2014 02:21:37 +0000 (2 days ago)

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