Changeset 332
- Timestamp:
- 08/20/07 18:36:46 (9 months ago)
- Files:
-
- eaccelerator/trunk/ChangeLog (modified) (2 diffs)
- eaccelerator/trunk/cache.c (modified) (1 diff)
- eaccelerator/trunk/ea_store.c (modified) (20 diffs)
- eaccelerator/trunk/ea_store.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
eaccelerator/trunk/ChangeLog
r331 r332 1 1 2007-08-20 Hans Rakers <hans at react.nl> 2 2 3 * Changed crash handler error message format to Apache-style error log 3 4 format as suggested in ticket #217 … … 15 16 16 17 2007-08-20 Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 18 17 19 * 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. 19 22 20 23 2007-08-19 Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 24 21 25 * Fix an E_NOTICE error in the control panel 22 26 * Improve storing of objects and fix bug #264 23 27 24 28 2007-08-16 Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 29 25 30 * Fix a typo in the config file. #269 26 31 eaccelerator/trunk/cache.c
r331 r332 253 253 /* set the refcount to 1 */ 254 254 q->value.refcount = 1; 255 store_zval(& q->value TSRMLS_CC);255 store_zval(&EAG(mem), &q->value TSRMLS_CC); 256 256 zend_hash_destroy(&EAG(strings)); 257 257 eaccelerator/trunk/ea_store.c
r328 r332 45 45 static size_t calc_string(char *str, int len TSRMLS_DC) 46 46 { 47 if (len > MAX_DUP_STR_LEN ||47 if (len > MAX_DUP_STR_LEN || 48 48 zend_hash_add(&EAG(strings), str, len, &str, sizeof(char *), NULL) == SUCCESS) { 49 49 EA_SIZE_ALIGN(len); 50 50 return len; 51 }51 } 52 52 return 0; 53 53 } … … 71 71 size_t size = 0; 72 72 73 size += sizeof(zval);73 size += sizeof(zval); 74 74 EA_SIZE_ALIGN(size); 75 size += calc_zval(*from TSRMLS_CC);75 size += calc_zval(*from TSRMLS_CC); 76 76 77 77 return size; … … 83 83 size_t size = 0; 84 84 85 size += sizeof(zend_property_info);85 size += sizeof(zend_property_info); 86 86 EA_SIZE_ALIGN(size); 87 87 88 size += calc_string(from->name, from->name_length + 1 TSRMLS_CC);88 size += calc_string(from->name, from->name_length + 1 TSRMLS_CC); 89 89 #ifdef INCLUDE_DOC_COMMENTS 90 90 #ifdef ZEND_ENGINE_2_1 … … 100 100 /* Calculate the size of an HashTable */ 101 101 static 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; 105 105 size_t size = 0; 106 106 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 *); 110 110 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; 115 115 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 } 120 120 return size; 121 121 } … … 125 125 size_t size = 0; 126 126 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: 129 129 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); 138 138 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 } 146 141 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 } 150 150 return size; 151 151 } … … 154 154 static size_t calc_op_array(zend_op_array * from TSRMLS_DC) 155 155 { 156 zend_op *opline;157 zend_op *end;156 zend_op *opline; 157 zend_op *end; 158 158 size_t size = 0; 159 159 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); 162 162 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); 165 165 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); 174 174 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 } 184 184 #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) { 210 210 size += from->last * sizeof(zend_op); 211 211 EA_SIZE_ALIGN(size); 212 212 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; 228 228 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; 233 233 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); 238 238 EA_SIZE_ALIGN(size); 239 size += calc_zval_hash(from->static_variables);240 }239 size += calc_zval_hash(from->static_variables); 240 } 241 241 #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; 245 245 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); 253 253 } 254 254 #ifdef INCLUDE_DOC_COMMENTS … … 267 267 { 268 268 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); 274 274 EA_SIZE_ALIGN(size); 275 275 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); 285 285 } 286 286 #ifdef INCLUDE_DOC_COMMENTS … … 289 289 } 290 290 #endif 291 291 292 292 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); 295 295 296 296 # 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)) { 299 299 # else 300 if (from->static_members != NULL) {300 if (from->static_members != NULL) { 301 301 # endif 302 size += sizeof(HashTable);302 size += sizeof(HashTable); 303 303 EA_SIZE_ALIGN(size); 304 size += calc_zval_hash(from->static_members);305 }304 size += calc_zval_hash(from->static_members); 305 } 306 306 #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); 310 310 311 311 return size; … … 316 316 size_t calc_size(char *key, zend_op_array * op_array, Bucket * f, Bucket * c TSRMLS_DC) 317 317 { 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; 322 322 size_t size = 0; 323 323 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; 326 326 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; 331 331 EA_SIZE_ALIGN(size); 332 332 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; 340 340 EA_SIZE_ALIGN(size); 341 341 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); 349 349 #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 370 static 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 386 typedef void *(*store_bucket_t) (char **, void * TSRMLS_DC); 387 typedef 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 401 static 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 410 static 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 489 void 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 513 static 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", 526 522 getpid(), from->function_name ? from->function_name : "(top)", 527 from->scope ? from->scope->name : "NULL"528 , from->type529 ));523 from->scope ? from->scope->name : "NULL" 524 , from->type 525 )); 530 526 #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", 532 528 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 } 568 559 # 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; 571 562 # 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; 578 569 #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