示例#1
0
/* {{{ mysqlnd_arena_alloc */
static zend_always_inline void* mysqlnd_arena_alloc(zend_arena **arena_ptr, size_t size)
{
	zend_arena *arena = *arena_ptr;
	char *ptr = arena->ptr;

	size = ZEND_MM_ALIGNED_SIZE(size);

	if (EXPECTED(size <= (size_t)(arena->end - ptr))) {
		arena->ptr = ptr + size;
	} else {
		size_t arena_size =
			UNEXPECTED((size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) > (size_t)(arena->end - (char*) arena)) ?
				(size + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena))) :
				(size_t)(arena->end - (char*) arena);
		zend_arena *new_arena = (zend_arena*)mnd_emalloc(arena_size);

		ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
		new_arena->ptr = (char*) new_arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena)) + size;
		new_arena->end = (char*) new_arena + arena_size;
		new_arena->prev = arena;
		*arena_ptr = new_arena;
	}

	return (void*) ptr;
}
zend_execute_data *sw_zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC)
{
	zend_execute_data *execute_data;

	size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
	size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
	size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
	size_t call_slots_size = ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * op_array->nested_calls;
	size_t stack_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * op_array->used_stack;
	size_t total_size = execute_data_size + Ts_size + CVs_size + call_slots_size + stack_size;

        execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
        execute_data = (zend_execute_data*)((char*)execute_data + Ts_size);
        execute_data->prev_execute_data = EG(current_execute_data);


        memset(EX_CV_NUM(execute_data, 0), 0, sizeof(zval **) * op_array->last_var);

	execute_data->call_slots = (call_slot*)((char *)execute_data + execute_data_size + CVs_size);


	execute_data->op_array = op_array;

	EG(argument_stack)->top = zend_vm_stack_frame_base(execute_data);

	execute_data->object = NULL;
	execute_data->current_this = NULL;
	execute_data->old_error_reporting = NULL;
	execute_data->symbol_table = EG(active_symbol_table);
	execute_data->call = NULL;
	EG(current_execute_data) = execute_data;
	execute_data->nested = nested;

	if (!op_array->run_time_cache && op_array->last_cache_slot) {
		op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
	}

	if (op_array->this_var != -1 && EG(This)) {
 		Z_ADDREF_P(EG(This)); /* For $this pointer */
		if (!EG(active_symbol_table)) {
			SW_EX_CV(op_array->this_var) = (zval **) SW_EX_CV_NUM(execute_data, op_array->last_var + op_array->this_var);
			*SW_EX_CV(op_array->this_var) = EG(This);
		} else {
			if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) EX_CV_NUM(execute_data, op_array->this_var))==FAILURE) {
				Z_DELREF_P(EG(This));
			}
		}
	}

	execute_data->opline = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
	EG(opline_ptr) = &(execute_data->opline);

	execute_data->function_state.function = (zend_function *) op_array;
	execute_data->function_state.arguments = NULL;

	return execute_data;
}
示例#3
0
static void *zend_file_cache_serialize_interned(zend_string              *str,
                                                zend_file_cache_metainfo *info)
{
	size_t len;
	void *ret;

	/* check if the same interned string was already stored */
	ret = zend_shared_alloc_get_xlat_entry(str);
	if (ret) {
		return ret;
	}

	len = ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)));
	ret = (void*)(info->str_size | Z_UL(1));
	zend_shared_alloc_register_xlat_entry(str, ret);
	if (info->str_size + len > ZSTR_LEN((zend_string*)ZCG(mem))) {
		size_t new_len = info->str_size + len;
		ZCG(mem) = (void*)zend_string_realloc(
			(zend_string*)ZCG(mem),
			((_ZSTR_HEADER_SIZE + 1 + new_len + 4095) & ~0xfff) - (_ZSTR_HEADER_SIZE + 1),
			0);
	}
	memcpy(ZSTR_VAL((zend_string*)ZCG(mem)) + info->str_size, str, len);
	info->str_size += len;
	return ret;
}
示例#4
0
/* {{{ */
zend_string* pthreads_globals_string(zend_string *str) {
	/*
	 This is sourcery of the darkest kind ...
	
	 We don't need all threads to have a copy of every string used as the name for a threaded objects property.
	 
	 In addition, Zend has troubles with persistent strings in non-persistent hashes and vice versa, to avoid these
	 we have a global table of strings that is used when writing to threaded objects properties, this table is detroyed
	 on shutdown of the process, so will show as leaked, but we don't care, we want stable !
	*/
	zend_string* p = NULL;
	if (pthreads_globals_lock()) {
		if (!(p = zend_hash_find_ptr(&PTHREADS_G(gstrings), str)) && 
			(p = (zend_string*) malloc(ZEND_MM_ALIGNED_SIZE(_ZSTR_STRUCT_SIZE(ZSTR_LEN(str)))))) {
			memset(p, 0, sizeof(zend_string));

			GC_REFCOUNT(p) = 2;
			GC_TYPE_INFO(p) = IS_STR_PERSISTENT;

			memcpy(ZSTR_VAL(p), ZSTR_VAL(str), ZSTR_LEN(str));
			p->len = ZSTR_LEN(str);
			ZSTR_VAL(p)[ZSTR_LEN(p)] = '\0';
			zend_string_forget_hash_val(p);
			zend_hash_update_ptr(
				&PTHREADS_G(gstrings), p, p);
		}

		pthreads_globals_unlock();
	}

	return p;
} /* }}} */
示例#5
0
/* {{{ mysqlnd_arena_create */
static zend_always_inline zend_arena* mysqlnd_arena_create(size_t size)
{
	zend_arena *arena = (zend_arena*)mnd_emalloc(size);

	arena->ptr = (char*) arena + ZEND_MM_ALIGNED_SIZE(sizeof(zend_arena));
	arena->end = (char*) arena + size;
	arena->prev = NULL;
	return arena;
}
示例#6
0
/* {{{ mysqlnd_mempool_resize_chunk */
static void *
mysqlnd_mempool_resize_chunk(MYSQLND_MEMORY_POOL * pool, void * ptr, size_t old_size, size_t size)
{
	DBG_ENTER("mysqlnd_mempool_resize_chunk");

	/* Try to back-off and guess if this is the last block allocated */
	if (ptr == pool->last
	  && (ZEND_MM_ALIGNED_SIZE(size) <= ((char*)pool->arena->end - (char*)ptr))) {
		/*
			This was the last allocation. Lucky us, we can free
			a bit of memory from the pool. Next time we will return from the same ptr.
		*/
		pool->arena->ptr = (char*)ptr + ZEND_MM_ALIGNED_SIZE(size);
	} else {
		void *new_ptr = mysqlnd_arena_alloc(&pool->arena, size);
		memcpy(new_ptr, ptr, MIN(old_size, size));
		pool->last = ptr = new_ptr;
	}
	DBG_RETURN(ptr);
}
示例#7
0
const char *apc_new_interned_string(const char *arKey, int nKeyLength TSRMLS_DC)
{
#ifndef ZTS
    ulong h;
    uint nIndex;
    Bucket *p;

    if (arKey >= APCSG(interned_strings_start) && arKey < APCSG(interned_strings_end)) {
        return arKey;
    }

    h = zend_inline_hash_func(arKey, nKeyLength);
    nIndex = h & APCSG(interned_strings).nTableMask;

    p = APCSG(interned_strings).arBuckets[nIndex];
    while (p != NULL) {
        if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
            if (!memcmp(p->arKey, arKey, nKeyLength)) {
                return p->arKey;
            }
        }
        p = p->pNext;
    }
   
    if (APCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength + 1) >=
        APCSG(interned_strings_end)) {
        /* no memory */
        return NULL;
    }

    p = (Bucket *) APCSG(interned_strings_top);
    APCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength + 1);

    p->arKey = (char*)(p+1);
    memcpy(p->arKey, arKey, nKeyLength);
    ((char *)p->arKey)[nKeyLength] = '\0';
    p->nKeyLength = nKeyLength;
    p->h = h;
    p->pData = &p->pDataPtr;
    p->pDataPtr = p;

    p->pNext = APCSG(interned_strings).arBuckets[nIndex];
    p->pLast = NULL;
    if (p->pNext) {
        p->pNext->pLast = p;
    }
    APCSG(interned_strings).arBuckets[nIndex] = p;

    p->pListLast = APCSG(interned_strings).pListTail;
    APCSG(interned_strings).pListTail = p;
    p->pListNext = NULL;
    if (p->pListLast != NULL) {
        p->pListLast->pListNext = p;
    }
    if (!APCSG(interned_strings).pListHead) {
        APCSG(interned_strings).pListHead = p;
    }

    APCSG(interned_strings).nNumOfElements++;

    return p->arKey;
#else
    return zend_new_interned_string(arKey, nKeyLength, 0 TSRMLS_CC);
#endif
}
示例#8
0
static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
{
#ifndef ZTS
	ulong h;
	uint nIndex;
	Bucket *p;

	if (IS_INTERNED(arKey)) {
		return arKey;
	}

	h = zend_inline_hash_func(arKey, nKeyLength);
	nIndex = h & CG(interned_strings).nTableMask;
	p = CG(interned_strings).arBuckets[nIndex];
	while (p != NULL) {
		if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
			if (!memcmp(p->arKey, arKey, nKeyLength)) {
				if (free_src) {
					efree((void *)arKey);
				}
				return p->arKey;
			}
		}
		p = p->pNext;
	}
	
	if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
	    CG(interned_strings_end)) {
	    /* no memory */
		return arKey;
	}

	p = (Bucket *) CG(interned_strings_top);
	CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);

#if ZEND_DEBUG_INTERNED_STRINGS
	mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
#endif
	
	p->arKey = (char*)(p+1);
	memcpy((char*)p->arKey, arKey, nKeyLength);
	if (free_src) {
		efree((void *)arKey);
	}
	p->nKeyLength = nKeyLength;
	p->h = h;
	p->pData = &p->pDataPtr;
	p->pDataPtr = p;
	
	p->pNext = CG(interned_strings).arBuckets[nIndex];
	p->pLast = NULL;
	if (p->pNext) {
		p->pNext->pLast = p;
	}

	HANDLE_BLOCK_INTERRUPTIONS();
	
	p->pListLast = CG(interned_strings).pListTail;
	CG(interned_strings).pListTail = p;
	p->pListNext = NULL;
	if (p->pListLast != NULL) {
		p->pListLast->pListNext = p;
	}
	if (!CG(interned_strings).pListHead) {
		CG(interned_strings).pListHead = p;
	}

	CG(interned_strings).arBuckets[nIndex] = p;

	HANDLE_UNBLOCK_INTERRUPTIONS();

	CG(interned_strings).nNumOfElements++;

	if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
		if ((CG(interned_strings).nTableSize << 1) > 0) {	/* Let's double the table size */
			Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);

			if (t) {
				HANDLE_BLOCK_INTERRUPTIONS();
				CG(interned_strings).arBuckets = t;
				CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
				CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
				zend_hash_rehash(&CG(interned_strings));
				HANDLE_UNBLOCK_INTERRUPTIONS();
			}
		}
	}

#if ZEND_DEBUG_INTERNED_STRINGS
	mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif

	return p->arKey;
#else
	return arKey;
#endif
}