Changeset 332

Show
Ignore:
Timestamp:
08/20/07 18:36:46 (9 months ago)
Author:
bart
Message:

Rewrite store_* functions so they no longer use the EAG(mem) global.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ChangeLog

    r331 r332  
    112007-08-20  Hans Rakers <hans at react.nl> 
     2 
    23        * Changed crash handler error message format to Apache-style error log 
    34          format as suggested in ticket #217 
     
    1516 
    16172007-08-20  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
     18 
    1719        * Rewrite the calc_* funtions so they no longer uses the EAG(mem) global. 
    18         * Rewrite the fixup_* functions they no longer use the EAG(mem) global 
     20        * Rewrite the fixup_* functions so they no longer use the EAG(mem) global. 
     21        * Rewrite store_* functions so they no longer use the EAG(mem) global. 
    1922 
    20232007-08-19  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
     24 
    2125        * Fix an E_NOTICE error in the control panel 
    2226        * Improve storing of objects and fix bug #264 
    2327 
    24282007-08-16  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
     29 
    2530        * Fix a typo in the config file. #269 
    2631 
  • eaccelerator/trunk/cache.c

    r331 r332  
    253253        /* set the refcount to 1 */ 
    254254        q->value.refcount = 1; 
    255         store_zval(&q->value TSRMLS_CC); 
     255        store_zval(&EAG(mem), &q->value TSRMLS_CC); 
    256256        zend_hash_destroy(&EAG(strings)); 
    257257 
  • eaccelerator/trunk/ea_store.c

    r328 r332  
    4545static size_t calc_string(char *str, int len TSRMLS_DC) 
    4646{ 
    47        if (len > MAX_DUP_STR_LEN ||  
     47    if (len > MAX_DUP_STR_LEN ||  
    4848            zend_hash_add(&EAG(strings), str, len, &str, sizeof(char *), NULL) == SUCCESS) { 
    4949        EA_SIZE_ALIGN(len); 
    5050        return len; 
    51        
     51   
    5252    return 0; 
    5353} 
     
    7171    size_t size = 0; 
    7272 
    73        size += sizeof(zval); 
     73    size += sizeof(zval); 
    7474    EA_SIZE_ALIGN(size); 
    75        size += calc_zval(*from TSRMLS_CC); 
     75    size += calc_zval(*from TSRMLS_CC); 
    7676 
    7777    return size; 
     
    8383    size_t size = 0; 
    8484 
    85        size += sizeof(zend_property_info); 
     85    size += sizeof(zend_property_info); 
    8686    EA_SIZE_ALIGN(size); 
    8787 
    88        size += calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
     88    size += calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
    8989#ifdef INCLUDE_DOC_COMMENTS 
    9090#ifdef ZEND_ENGINE_2_1 
     
    100100/* Calculate the size of an HashTable */ 
    101101static size_t calc_hash_int(HashTable * source, Bucket * start, 
    102                                                  calc_bucket_t calc_bucket TSRMLS_DC) 
    103 { 
    104        Bucket *p; 
     102                          calc_bucket_t calc_bucket TSRMLS_DC) 
     103{ 
     104    Bucket *p; 
    105105    size_t size = 0; 
    106106 
    107        if (source->nNumOfElements > 0) { 
    108                if (!EAG(compress)) { 
    109                        size += source->nTableSize * sizeof(Bucket *); 
     107    if (source->nNumOfElements > 0) { 
     108        if (!EAG(compress)) { 
     109            size += source->nTableSize * sizeof(Bucket *); 
    110110            EA_SIZE_ALIGN(size); 
    111                
    112                p = start; 
    113                while (p) { 
    114                        size += offsetof(Bucket, arKey) + p->nKeyLength; 
     111       
     112        p = start; 
     113        while (p) { 
     114            size += offsetof(Bucket, arKey) + p->nKeyLength; 
    115115            EA_SIZE_ALIGN(size); 
    116                        size += calc_bucket(p->pData TSRMLS_CC); 
    117                        p = p->pListNext; 
    118                
    119        
     116            size += calc_bucket(p->pData TSRMLS_CC); 
     117            p = p->pListNext; 
     118       
     119   
    120120    return size; 
    121121} 
     
    125125    size_t size = 0; 
    126126 
    127        switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
    128        case IS_CONSTANT: 
     127    switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
     128        case IS_CONSTANT: 
    129129        case IS_OBJECT: /* object should have been serialized before storing them */ 
    130        case IS_STRING: 
    131                size += calc_string(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1 TSRMLS_CC); 
    132                break; 
    133  
    134        case IS_ARRAY: 
    135        case IS_CONSTANT_ARRAY: 
    136                if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
    137                        size += sizeof(HashTable); 
     130        case IS_STRING: 
     131            size += calc_string(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1 TSRMLS_CC); 
     132            break; 
     133 
     134        case IS_ARRAY: 
     135        case IS_CONSTANT_ARRAY: 
     136            if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
     137                size += sizeof(HashTable); 
    138138                EA_SIZE_ALIGN(size); 
    139                         size += calc_zval_hash(Z_ARRVAL_P(zv)); 
    140                 } 
    141                 break; 
    142  
    143         case IS_RESOURCE: 
    144                 DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache resources\n", getpid())); 
    145                 zend_bailout(); 
     139                size += calc_zval_hash(Z_ARRVAL_P(zv)); 
     140            } 
    146141            break; 
    147         default: 
    148                 break; 
    149         } 
     142 
     143        case IS_RESOURCE: 
     144            DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache resources\n", getpid())); 
     145            zend_bailout(); 
     146            break; 
     147        default: 
     148            break; 
     149    } 
    150150    return size; 
    151151} 
     
    154154static size_t calc_op_array(zend_op_array * from TSRMLS_DC) 
    155155{ 
    156        zend_op *opline; 
    157        zend_op *end; 
     156    zend_op *opline; 
     157    zend_op *end; 
    158158    size_t size = 0; 
    159159 
    160        if (from->type == ZEND_INTERNAL_FUNCTION) { 
    161                size += sizeof(zend_internal_function); 
     160    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     161        size += sizeof(zend_internal_function); 
    162162        EA_SIZE_ALIGN(size); 
    163        } else if (from->type == ZEND_USER_FUNCTION) { 
    164                size += sizeof(ea_op_array); 
     163    } else if (from->type == ZEND_USER_FUNCTION) { 
     164        size += sizeof(ea_op_array); 
    165165        EA_SIZE_ALIGN(size); 
    166        } else { 
    167                DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache function \"%s\"\n", getpid(), from->function_name)); 
    168                zend_bailout(); 
    169        
    170 #ifdef ZEND_ENGINE_2 
    171        if (from->num_args > 0) { 
    172                zend_uint i; 
    173                size += from->num_args * sizeof(zend_arg_info); 
     166    } else { 
     167        DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache function \"%s\"\n", getpid(), from->function_name)); 
     168        zend_bailout(); 
     169   
     170#ifdef ZEND_ENGINE_2 
     171    if (from->num_args > 0) { 
     172        zend_uint i; 
     173        size += from->num_args * sizeof(zend_arg_info); 
    174174        EA_SIZE_ALIGN(size); 
    175                for (i = 0; i < from->num_args; i++) { 
    176                        if (from->arg_info[i].name) { 
    177                                size += calc_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
    178             } 
    179                        if (from->arg_info[i].class_name) { 
    180                                size += calc_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
    181             } 
    182                
    183        
     175        for (i = 0; i < from->num_args; i++) { 
     176            if (from->arg_info[i].name) { 
     177                size += calc_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
     178            } 
     179            if (from->arg_info[i].class_name) { 
     180                size += calc_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
     181            } 
     182       
     183   
    184184#else 
    185        if (from->arg_types != NULL) { 
    186            size += calc_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); 
    187     } 
    188 #endif 
    189        if (from->function_name != NULL) { 
    190                size += calc_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); 
    191     } 
    192 #ifdef ZEND_ENGINE_2 
    193        if (from->scope != NULL) { 
    194                // HOESH: the same problem? 
    195                Bucket *q = CG(class_table)->pListHead; 
    196                while (q != NULL) { 
    197                        if (*(zend_class_entry **) q->pData == from->scope) { 
    198                                size += calc_string(q->arKey, q->nKeyLength TSRMLS_CC); 
    199                                break; 
    200                        
    201                        q = q->pListNext; 
    202                
    203        
    204 #endif 
    205        if (from->type == ZEND_INTERNAL_FUNCTION) { 
    206                return; 
    207     } 
    208  
    209        if (from->opcodes != NULL) { 
     185    if (from->arg_types != NULL) { 
     186        size += calc_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); 
     187    } 
     188#endif 
     189    if (from->function_name != NULL) { 
     190        size += calc_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); 
     191    } 
     192#ifdef ZEND_ENGINE_2 
     193    if (from->scope != NULL) { 
     194        // HOESH: the same problem? 
     195        Bucket *q = CG(class_table)->pListHead; 
     196        while (q != NULL) { 
     197            if (*(zend_class_entry **) q->pData == from->scope) { 
     198                size += calc_string(q->arKey, q->nKeyLength TSRMLS_CC); 
     199                break; 
     200           
     201            q = q->pListNext; 
     202       
     203   
     204#endif 
     205    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     206        return; 
     207    } 
     208 
     209    if (from->opcodes != NULL) { 
    210210        size += from->last * sizeof(zend_op); 
    211211        EA_SIZE_ALIGN(size); 
    212212 
    213                opline = from->opcodes; 
    214                end = opline + from->last; 
    215                EAG(compress) = 0; 
    216                for (; opline < end; opline++) { 
    217                        if (opline->op1.op_type == IS_CONST) { 
    218                                size += calc_zval(&opline->op1.u.constant TSRMLS_CC); 
    219             } 
    220                        if (opline->op2.op_type == IS_CONST) { 
    221                                size += calc_zval(&opline->op2.u.constant TSRMLS_CC); 
    222             } 
    223                
    224                EAG(compress) = 1; 
    225        
    226        if (from->brk_cont_array != NULL) { 
    227                size += sizeof(zend_brk_cont_element) * from->last_brk_cont; 
     213        opline = from->opcodes; 
     214        end = opline + from->last; 
     215        EAG(compress) = 0; 
     216        for (; opline < end; opline++) { 
     217            if (opline->op1.op_type == IS_CONST) { 
     218                size += calc_zval(&opline->op1.u.constant TSRMLS_CC); 
     219            } 
     220            if (opline->op2.op_type == IS_CONST) { 
     221                size += calc_zval(&opline->op2.u.constant TSRMLS_CC); 
     222            } 
     223       
     224        EAG(compress) = 1; 
     225   
     226    if (from->brk_cont_array != NULL) { 
     227        size += sizeof(zend_brk_cont_element) * from->last_brk_cont; 
    228228        EA_SIZE_ALIGN(size); 
    229        
    230 #ifdef ZEND_ENGINE_2 
    231        if (from->try_catch_array != NULL) { 
    232                size += sizeof(zend_try_catch_element) * from->last_try_catch; 
     229   
     230#ifdef ZEND_ENGINE_2 
     231    if (from->try_catch_array != NULL) { 
     232        size += sizeof(zend_try_catch_element) * from->last_try_catch; 
    233233        EA_SIZE_ALIGN(size); 
    234        
    235 #endif 
    236        if (from->static_variables != NULL) { 
    237                size += sizeof(HashTable); 
     234   
     235#endif 
     236    if (from->static_variables != NULL) { 
     237        size += sizeof(HashTable); 
    238238        EA_SIZE_ALIGN(size); 
    239                size += calc_zval_hash(from->static_variables); 
    240        
     239        size += calc_zval_hash(from->static_variables); 
     240   
    241241#ifdef ZEND_ENGINE_2_1 
    242        if (from->vars != NULL) { 
    243                int i; 
    244                size += sizeof(zend_compiled_variable) * from->last_var; 
     242    if (from->vars != NULL) { 
     243        int i; 
     244        size += sizeof(zend_compiled_variable) * from->last_var; 
    245245        EA_SIZE_ALIGN(size); 
    246                for (i = 0; i < from->last_var; i ++) { 
    247                        size += calc_string(from->vars[i].name, from->vars[i].name_len+1 TSRMLS_CC); 
    248                
    249        
    250 #endif 
    251        if (from->filename != NULL) { 
    252                size += calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     246        for (i = 0; i < from->last_var; i ++) { 
     247            size += calc_string(from->vars[i].name, from->vars[i].name_len+1 TSRMLS_CC); 
     248       
     249   
     250#endif 
     251    if (from->filename != NULL) { 
     252        size += calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
    253253    } 
    254254#ifdef INCLUDE_DOC_COMMENTS 
     
    267267{ 
    268268    size_t size = 0; 
    269        if (from->type != ZEND_USER_CLASS) { 
    270                DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache internal class \"%s\"\n", getpid(), from->name)); 
    271                zend_bailout(); 
    272        
    273        size += sizeof(ea_class_entry); 
     269    if (from->type != ZEND_USER_CLASS) { 
     270        DBG(ea_debug_error, ("[%d] EACCELERATOR can't cache internal class \"%s\"\n", getpid(), from->name)); 
     271        zend_bailout(); 
     272   
     273    size += sizeof(ea_class_entry); 
    274274    EA_SIZE_ALIGN(size); 
    275275 
    276        if (from->name != NULL) { 
    277                size += calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
    278     } 
    279        if (from->parent != NULL && from->parent->name) { 
    280                size += calc_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 
    281     } 
    282 #ifdef ZEND_ENGINE_2 
    283        if (from->filename != NULL) { 
    284                size += calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     276    if (from->name != NULL) { 
     277        size += calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
     278    } 
     279    if (from->parent != NULL && from->parent->name) { 
     280        size += calc_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 
     281    } 
     282#ifdef ZEND_ENGINE_2 
     283    if (from->filename != NULL) { 
     284        size += calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
    285285    } 
    286286#ifdef INCLUDE_DOC_COMMENTS 
     
    289289     } 
    290290#endif 
    291          
     291     
    292292    size += calc_zval_hash(&from->constants_table); 
    293        size += calc_zval_hash(&from->default_properties); 
    294        size += calc_hash(&from->properties_info, (calc_bucket_t) calc_property_info); 
     293    size += calc_zval_hash(&from->default_properties); 
     294    size += calc_hash(&from->properties_info, (calc_bucket_t) calc_property_info); 
    295295 
    296296#  ifdef ZEND_ENGINE_2_1 
    297        size += calc_zval_hash(&from->default_static_members); 
    298        if ((from->static_members != NULL) && (from->static_members != &from->default_static_members)) { 
     297    size += calc_zval_hash(&from->default_static_members); 
     298    if ((from->static_members != NULL) && (from->static_members != &from->default_static_members)) { 
    299299#  else 
    300        if (from->static_members != NULL) { 
     300    if (from->static_members != NULL) { 
    301301#  endif 
    302                size += sizeof(HashTable); 
     302        size += sizeof(HashTable); 
    303303        EA_SIZE_ALIGN(size); 
    304                size += calc_zval_hash(from->static_members); 
    305        
     304        size += calc_zval_hash(from->static_members); 
     305   
    306306#else 
    307        size += calc_zval_hash(&from->default_properties); 
    308 #endif 
    309        size += calc_hash(&from->function_table, (calc_bucket_t) calc_op_array); 
     307    size += calc_zval_hash(&from->default_properties); 
     308#endif 
     309    size += calc_hash(&from->function_table, (calc_bucket_t) calc_op_array); 
    310310 
    311311    return size; 
     
    316316size_t calc_size(char *key, zend_op_array * op_array, Bucket * f, Bucket * c TSRMLS_DC) 
    317317{ 
    318        Bucket *b; 
    319        char *x; 
    320        int len = strlen(key); 
    321        EAG(compress) = 1; 
     318    Bucket *b; 
     319    char *x; 
     320    int len = strlen(key); 
     321    EAG(compress) = 1; 
    322322    size_t size = 0; 
    323323 
    324        zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); 
    325        size += offsetof(ea_cache_entry, realfilename) + len + 1; 
     324    zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); 
     325    size += offsetof(ea_cache_entry, realfilename) + len + 1; 
    326326    EA_SIZE_ALIGN(size); 
    327        zend_hash_add(&EAG(strings), key, len + 1, &key, sizeof(char *), NULL); 
    328        b = c; 
    329        while (b != NULL) { 
    330                size += offsetof(ea_fc_entry, htabkey) + b->nKeyLength; 
     327    zend_hash_add(&EAG(strings), key, len + 1, &key, sizeof(char *), NULL); 
     328    b = c; 
     329    while (b != NULL) { 
     330        size += offsetof(ea_fc_entry, htabkey) + b->nKeyLength; 
    331331        EA_SIZE_ALIGN(size); 
    332332 
    333                x = b->arKey; 
    334                zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
    335                b = b->pListNext; 
    336        
    337        b = f; 
    338        while (b != NULL) { 
    339                size += offsetof(ea_fc_entry, htabkey) + b->nKeyLength; 
     333        x = b->arKey; 
     334        zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
     335        b = b->pListNext; 
     336   
     337    b = f; 
     338    while (b != NULL) { 
     339        size += offsetof(ea_fc_entry, htabkey) + b->nKeyLength; 
    340340        EA_SIZE_ALIGN(size); 
    341341     
    342                x = b->arKey; 
    343                zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
    344                b = b->pListNext; 
    345        
    346        while (c != NULL) { 
    347 #ifdef ZEND_ENGINE_2 
    348                size += calc_class_entry(*(zend_class_entry **) c->pData TSRMLS_CC); 
     342        x = b->arKey; 
     343        zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
     344        b = b->pListNext; 
     345   
     346    while (c != NULL) { 
     347#ifdef ZEND_ENGINE_2 
     348        size += calc_class_entry(*(zend_class_entry **) c->pData TSRMLS_CC); 
    349349#else 
    350                 size += calc_class_entry((zend_class_entry *) c->pData TSRMLS_CC); 
    351 #endif 
    352                 c = c->pListNext; 
    353         } 
    354         while (f != NULL) { 
    355                 size += calc_op_array((zend_op_array *) f->pData TSRMLS_CC); 
    356                 f = f->pListNext; 
    357         } 
    358         size += calc_op_array(op_array TSRMLS_CC); 
    359         zend_hash_destroy(&EAG(strings)); 
    360  
    361         return size; 
    362 
    363  
    364 static inline char *store_string(char *str, int len TSRMLS_DC) 
    365 
    366         char *p; 
    367         if (len > MAX_DUP_STR_LEN) { 
    368                 EACCELERATOR_ALIGN(EAG(mem)); 
    369                 p = (char *) EAG(mem); 
    370                 EAG(mem) += len; 
    371                 memcpy(p, str, len); 
    372         } else if (zend_hash_find(&EAG(strings), str, len, (void *) &p) == SUCCESS) { 
    373                 p = *(char **) p; 
    374         } else { 
    375                 EACCELERATOR_ALIGN(EAG(mem)); 
    376                 p = (char *) EAG(mem); 
    377                 EAG(mem) += len; 
    378                 memcpy(p, str, len); 
    379                 zend_hash_add(&EAG(strings), str, len, (void *) &p, sizeof(char *), NULL); 
    380         } 
    381         return p; 
    382 
    383  
    384 typedef void *(*store_bucket_t) (void *TSRMLS_DC); 
    385 typedef void *(*check_bucket_t) (Bucket*, zend_class_entry*); 
    386  
    387 #define store_hash_ex(to, from, start, store_bucket, check_bucket, from_ce) \ 
    388   store_hash_int(to, from, start, store_bucket, check_bucket, from_ce) 
    389  
    390 #define store_hash(to, from, store_bucket, check_bucket, from_ce) \ 
    391   store_hash_ex(to, from, (from)->pListHead, store_bucket, check_bucket, from_ce) 
    392  
    393 #define store_zval_hash(to, from) \ 
    394   store_hash(to, from, (store_bucket_t)store_zval_ptr, NULL, NULL) 
    395  
    396 #define store_zval_hash_ex(to, from, start) \ 
    397   store_hash_ex(to, from, start, (store_bucket_t)store_zval_ptr, NULL) 
    398  
    399 static zval *store_zval_ptr(zval * from TSRMLS_DC) 
    400 
    401         zval *to; 
    402         EACCELERATOR_ALIGN(EAG(mem)); 
    403         to = (zval *) EAG(mem); 
    404         EAG(mem) += sizeof(zval); 
    405         memcpy(to, from, sizeof(zval)); 
    406         store_zval(to TSRMLS_CC); 
    407         return to; 
    408 
    409  
    410 static void store_hash_int(HashTable * target, HashTable * source,  
    411                                                    Bucket * start, store_bucket_t copy_bucket, 
    412                                                                    check_bucket_t check_bucket, 
    413                                                                    zend_class_entry * from_ce) 
    414 
    415         Bucket *p, *np, *prev_p; 
    416         TSRMLS_FETCH(); 
    417  
    418         memcpy(target, source, sizeof(HashTable)); 
    419  
    420         if (source->nNumOfElements > 0) { 
    421                 if (!EAG(compress)) { 
    422                         EACCELERATOR_ALIGN(EAG(mem)); 
    423                         target->arBuckets = (Bucket **) EAG(mem); 
    424                         EAG(mem) += target->nTableSize * sizeof(Bucket *); 
    425                         memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); 
    426                 } 
    427  
    428                 target->pDestructor = NULL; 
    429                 target->persistent = 1; 
    430                 target->pListHead = NULL; 
    431                 target->pListTail = NULL; 
    432  
    433                 p = start; 
    434                 prev_p = NULL; 
    435                 np = NULL; 
    436                 while (p) { 
    437                         /* If a check function has been defined, run it */ 
    438                         if (check_bucket) { 
    439                                 /* If the check function returns ZEND_HASH_APPLY_REMOVE, don't store this record, skip over it */ 
    440                                 if(check_bucket(p, from_ce)) { 
    441                                         p = p->pListNext; 
    442                                         target->nNumOfElements--; 
    443                                         /* skip to next itteration */ 
    444                                         continue; 
    445                                 } 
    446                         } 
    447  
    448                         EACCELERATOR_ALIGN(EAG(mem)); 
    449                         np = (Bucket *) EAG(mem); 
    450                         EAG(mem) += offsetof(Bucket, arKey) + p->nKeyLength; 
    451  
    452                         if (!EAG(compress)) { 
    453                                 int nIndex = p->h % source->nTableSize; 
    454                                 if (target->arBuckets[nIndex]) { 
    455                                         np->pNext = target->arBuckets[nIndex]; 
    456                                         np->pLast = NULL; 
    457                                         np->pNext->pLast = np; 
    458                                 } else { 
    459                                         np->pNext = NULL; 
    460                                         np->pLast = NULL; 
    461                                 } 
    462                                 target->arBuckets[nIndex] = np; 
    463                         } 
    464                         np->h = p->h; 
    465                         np->nKeyLength = p->nKeyLength; 
    466  
    467                         if (p->pDataPtr == NULL) { 
    468                                 np->pData = copy_bucket(p->pData TSRMLS_CC); 
    469                                 np->pDataPtr = NULL; 
    470                         } else { 
    471                                 np->pDataPtr = copy_bucket(p->pDataPtr TSRMLS_CC); 
    472                                 np->pData = &np->pDataPtr; 
    473                         } 
    474  
    475                         np->pListLast = prev_p; 
    476                         np->pListNext = NULL; 
    477  
    478                         memcpy(np->arKey, p->arKey, p->nKeyLength); 
    479  
    480                         if (prev_p) { 
    481                                 prev_p->pListNext = np; 
    482                         } else { 
    483                                 target->pListHead = np; 
    484                         } 
    485                         prev_p = np; 
    486                         p = p->pListNext; 
    487                 } 
    488                 target->pListTail = np; 
    489                 target->pInternalPointer = target->pListHead; 
    490         } 
    491 
    492  
    493 void store_zval(zval * zv TSRMLS_DC) 
    494 
    495         switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
    496         case IS_CONSTANT: 
    497     case IS_OBJECT: /* object should have been serialized before storing them */ 
    498         case IS_STRING: 
    499                 Z_STRVAL_P(zv) = store_string(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1 TSRMLS_CC); 
    500                 break; 
    501         case IS_ARRAY: 
    502         case IS_CONSTANT_ARRAY: 
    503                 if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
    504                         HashTable *p; 
    505                         EACCELERATOR_ALIGN(EAG(mem)); 
    506                         p = (HashTable *) EAG(mem); 
    507                         EAG(mem) += sizeof(HashTable); 
    508                         store_zval_hash(p, Z_ARRVAL_P(zv)); 
    509                         Z_ARRVAL_P(zv) = p; 
    510                 } 
    511                 break; 
    512         default: 
    513                 break; 
    514         } 
    515 
    516  
    517 static ea_op_array *store_op_array(zend_op_array * from TSRMLS_DC) 
    518 
    519         ea_op_array *to; 
    520         zend_op *opline; 
    521         zend_op *end; 
    522  
    523         DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    524 #ifdef ZEND_ENGINE_2 
    525         DBG(ea_debug_printf, (EA_DEBUG, "[%d] store_op_array: %s [scope=%s type=%x]\n",  
     350        size += calc_class_entry((zend_class_entry *) c->pData TSRMLS_CC); 
     351#endif 
     352        c = c->pListNext; 
     353    } 
     354    while (f != NULL) { 
     355        size += calc_op_array((zend_op_array *) f->pData TSRMLS_CC); 
     356        f = f->pListNext; 
     357    } 
     358    size += calc_op_array(op_array TSRMLS_CC); 
     359    zend_hash_destroy(&EAG(strings)); 
     360 
     361    return size; 
     362
     363 
     364// this macro returns the current position to place data and advances the pointer 
     365// to the next positions and aligns it 
     366#define ALLOCATE(at, len) (*at);\ 
     367    (*at) += (len); \ 
     368    EACCELERATOR_ALIGN((*at)); 
     369 
     370static inline char *store_string(char **at, char *str, int len TSRMLS_DC) 
     371
     372    char *p; 
     373    if (len > MAX_DUP_STR_LEN) { 
     374        p = ALLOCATE(at, len); 
     375        memcpy(p, str, len); 
     376    } else if (zend_hash_find(&EAG(strings), str, len, (void *) &p) == SUCCESS) { 
     377        p = *(char **) p; 
     378    } else { 
     379        p = ALLOCATE(at, len); 
     380        memcpy(p, str, len); 
     381        zend_hash_add(&EAG(strings), str, len, (void *) &p, sizeof(char *), NULL); 
     382    } 
     383    return p; 
     384
     385 
     386typedef void *(*store_bucket_t) (char **, void * TSRMLS_DC); 
     387typedef void *(*check_bucket_t) (Bucket *, zend_class_entry *); 
     388 
     389#define store_hash_ex(p, to, from, start, store_bucket, check_bucket, from_ce) \ 
     390  store_hash_int(p, to, from, start, store_bucket, check_bucket, from_ce) 
     391 
     392#define store_hash(p, to, from, store_bucket, check_bucket, from_ce) \ 
     393  store_hash_ex(p, to, from, (from)->pListHead, store_bucket, check_bucket, from_ce) 
     394 
     395#define store_zval_hash(p, to, from) \ 
     396  store_hash(p, to, from, (store_bucket_t)store_zval_ptr, NULL, NULL) 
     397 
     398#define store_zval_hash_ex(p, to, from, start) \ 
     399  store_hash_ex(p, to, from, start, (store_bucket_t)store_zval_ptr, NULL) 
     400 
     401static zval *store_zval_ptr(char **at, zval *from TSRMLS_DC) 
     402
     403    zval *to = (zval *)ALLOCATE(at, sizeof(zval)); 
     404 
     405    memcpy(to, from, sizeof(zval)); 
     406    store_zval(at, to TSRMLS_CC); 
     407    return to; 
     408
     409 
     410static void store_hash_int(char **at, HashTable *target, HashTable *source,  
     411                           Bucket *start, store_bucket_t copy_bucket, 
     412                                   check_bucket_t check_bucket, 
     413                                   zend_class_entry *from_ce) 
     414
     415    Bucket *p, *np, *prev_p; 
     416    TSRMLS_FETCH(); 
     417 
     418    memcpy(target, source, sizeof(HashTable)); 
     419 
     420    if (source->nNumOfElements > 0) { 
     421        if (!EAG(compress)) { 
     422            target->arBuckets = (Bucket **)ALLOCATE(at, target->nTableSize * sizeof(Bucket *)); 
     423            memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); 
     424        } 
     425 
     426        target->pDestructor = NULL; 
     427        target->persistent = 1; 
     428        target->pListHead = NULL; 
     429        target->pListTail = NULL; 
     430 
     431        p = start; 
     432        prev_p = NULL; 
     433        np = NULL; 
     434        while (p) { 
     435            /* If a check function has been defined, run it */ 
     436            if (check_bucket) { 
     437                /* If the check function returns ZEND_HASH_APPLY_REMOVE, don't store this record, skip over it */ 
     438                if(check_bucket(p, from_ce)) { 
     439                    p = p->pListNext; 
     440                    target->nNumOfElements--; 
     441                    /* skip to next itteration */ 
     442                    continue; 
     443                } 
     444            } 
     445 
     446            np = (Bucket *)ALLOCATE(at, offsetof(Bucket, arKey) + p->nKeyLength); 
     447 
     448            if (!EAG(compress)) { 
     449                int nIndex = p->h % source->nTableSize; 
     450                if (target->arBuckets[nIndex]) { 
     451                    np->pNext = target->arBuckets[nIndex]; 
     452                    np->pLast = NULL; 
     453                    np->pNext->pLast = np; 
     454                } else { 
     455                    np->pNext = NULL; 
     456                    np->pLast = NULL; 
     457                } 
     458                target->arBuckets[nIndex] = np; 
     459            } 
     460            np->h = p->h; 
     461            np->nKeyLength = p->nKeyLength; 
     462 
     463            if (p->pDataPtr == NULL) { 
     464                np->pData = copy_bucket(at, p->pData TSRMLS_CC); 
     465                np->pDataPtr = NULL; 
     466            } else { 
     467                np->pDataPtr = copy_bucket(at, p->pDataPtr TSRMLS_CC); 
     468                np->pData = &np->pDataPtr; 
     469            } 
     470 
     471            np->pListLast = prev_p; 
     472            np->pListNext = NULL; 
     473 
     474            memcpy(np->arKey, p->arKey, p->nKeyLength); 
     475 
     476            if (prev_p) { 
     477                prev_p->pListNext = np; 
     478            } else { 
     479                target->pListHead = np; 
     480            } 
     481            prev_p = np; 
     482            p = p->pListNext; 
     483        } 
     484        target->pListTail = np; 
     485        target->pInternalPointer = target->pListHead; 
     486    } 
     487
     488 
     489void store_zval(char **at, zval *zv TSRMLS_DC) 
     490
     491    switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
     492        case IS_CONSTANT: 
     493        case IS_OBJECT: /* object should have been serialized before storing them */ 
     494        case IS_STRING: 
     495            Z_STRVAL_P(zv) = store_string(at, Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1 TSRMLS_CC); 
     496            break; 
     497 
     498        case IS_ARRAY: 
     499        case IS_CONSTANT_ARRAY: 
     500            if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
     501                HashTable *q; 
     502                q = (HashTable *)ALLOCATE(at, sizeof(HashTable)); 
     503                store_zval_hash(at, q, Z_ARRVAL_P(zv)); 
     504                Z_ARRVAL_P(zv) = q; 
     505            } 
     506            break; 
     507 
     508        default: 
     509            break; 
     510    } 
     511
     512 
     513static ea_op_array *store_op_array(char **at, zend_op_array * from TSRMLS_DC) 
     514
     515    ea_op_array *to; 
     516    zend_op *opline; 
     517    zend_op *end; 
     518 
     519    DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     520#ifdef ZEND_ENGINE_2 
     521    DBG(ea_debug_printf, (EA_DEBUG, "[%d] store_op_array: %s [scope=%s type=%x]\n",  
    526522            getpid(), from->function_name ? from->function_name : "(top)", 
    527                        from->scope ? from->scope->name : "NULL" 
    528                        , from->type 
    529                )); 
     523            from->scope ? from->scope->name : "NULL" 
     524            , from->type 
     525        )); 
    530526#else 
    531        DBG(ea_debug_printf, (EA_DEBUG, "[%d] store_op_array: %s [scope=%s type=%x]\n",  
     527    DBG(ea_debug_printf, (EA_DEBUG, "[%d] store_op_array: %s [scope=%s type=%x]\n",  
    532528            getpid(), from->function_name ? from->function_name : "(top)", 
    533                         "NULL" 
    534                         , from->type 
    535                 )); 
    536 #endif 
    537  
    538         if (from->type == ZEND_INTERNAL_FUNCTION) { 
    539                 EACCELERATOR_ALIGN(EAG(mem)); 
    540                 to = (ea_op_array *) EAG(mem); 
    541                 EAG(mem) += offsetof(ea_op_array, opcodes); 
    542         } else if (from->type == ZEND_USER_FUNCTION) { 
    543                 EACCELERATOR_ALIGN(EAG(mem)); 
    544                 to = (ea_op_array *) EAG(mem); 
    545                 EAG(mem) += sizeof(ea_op_array); 
    546         } else { 
    547                 return NULL; 
    548         } 
    549  
    550         to->type = from->type; 
    551 #ifdef ZEND_ENGINE_2 
    552         to->num_args = from->num_args; 
    553         to->required_num_args = from->required_num_args; 
    554         if (from->num_args > 0) { 
    555                 zend_uint i; 
    556                 EACCELERATOR_ALIGN(EAG(mem)); 
    557                 to->arg_info = (zend_arg_info *) EAG(mem); 
    558                 EAG(mem) += from->num_args * sizeof(zend_arg_info); 
    559                 for (i = 0; i < from->num_args; i++) { 
    560                         if (from->arg_info[i].name) { 
    561                                 to->arg_info[i].name = store_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
    562                                 to->arg_info[i].name_len = from->arg_info[i].name_len; 
    563                         } 
    564                         if (from->arg_info[i].class_name) { 
    565                                 to->arg_info[i].class_name = store_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
    566                                 to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; 
    567                         } 
     529            "NULL" 
     530            , from->type 
     531        )); 
     532#endif       
     533 
     534    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     535        to = (ea_op_array *)ALLOCATE(at, offsetof(ea_op_array, opcodes)); 
     536    } else if (from->type == ZEND_USER_FUNCTION) { 
     537        to = (ea_op_array *)ALLOCATE(at, sizeof(ea_op_array)); 
     538    } else { 
     539        return NULL; 
     540    } 
     541 
     542    to->type = from->type; 
     543#ifdef ZEND_ENGINE_2 
     544    to->num_args = from->num_args; 
     545    to->required_num_args = from->required_num_args; 
     546    if (from->num_args > 0) { 
     547        zend_uint i; 
     548        to->arg_info = (zend_arg_info *)ALLOCATE(at, from->num_args * sizeof(zend_arg_info)); 
     549 
     550        for (i = 0; i < from->num_args; i++) { 
     551            if (from->arg_info[i].name) { 
     552                to->arg_info[i].name = store_string(at, from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
     553                to->arg_info[i].name_len = from->arg_info[i].name_len; 
     554            } 
     555            if (from->arg_info[i].class_name) { 
     556                to->arg_info[i].class_name = store_string(at, from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
     557                to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; 
     558            } 
    568559#  ifdef ZEND_ENGINE_2_1 
    569                        /* php 5.1 introduces this in zend_arg_info for array type hinting */ 
    570                        to->arg_info[i].array_type_hint = from->arg_info[i].array_type_hint; 
     560            /* php 5.1 introduces this in zend_arg_info for array type hinting */ 
     561            to->arg_info[i].array_type_hint = from->arg_info[i].array_type_hint; 
    571562#  endif 
    572                        to->arg_info[i].allow_null = from->arg_info[i].allow_null; 
    573                        to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; 
    574                        to->arg_info[i].return_reference = from->arg_info[i].return_reference; 
    575                
    576        
    577        to->pass_rest_by_reference = from->pass_rest_by_reference; 
     563            to->arg_info[i].allow_null = from->arg_info[i].allow_null; 
     564            to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; 
     565            to->arg_info[i].return_reference = from->arg_info[i].return_reference; 
     566       
     567   
     568    to->pass_rest_by_reference = from->pass_rest_by_reference; 
    578569#else 
    579        if (from->arg_types != NULL) 
    580                to->arg_types = (unsigned char *) store_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); 
    581 #endif 
    582        if (from->function_name != NULL) 
    583                to->function_name = store_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); 
    584 #ifdef ZEND_ENGINE_2 
    585        to->fn_flags = from->fn_flags; 
    586        to->scope_name = NULL; 
    587        to->scope_name_len = 0; 
    588        if (from->scope != NULL) { 
    589                Bucket *q = CG(class_table)->pListHead; 
    590                while (q != NULL) { 
    591                        if (*(zend_class_entry **) q->pData == from->scope) { 
    592                                to->scope_name = store_string(q->arKey, q->nKeyLength TSRMLS_CC); 
    593                                to->scope_name_len = q->nKeyLength - 1; 
    594  
    595                                DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    596                                DBG(ea_debug_printf, (EA_DEBUG,  
     570&nbs