void checkered_alloc(struct smart_alloc *sa) { int i = 0; int j; char *pointers[10]; for(i = 0; i < 10; i++) { pointers[i] = smart_alloc(sa, 100); assert(pointers[i]); for(j = 0; j < 100; j++) { pointers[i][j] = 1; } } for(i = 1; i < 10; i += 2) { smart_free(sa, pointers[i]); } for(i = 1; i < 10; i += 2) { pointers[i] = smart_alloc(sa, 90); assert(pointers[i]); for(j = 0; j < 90; j++) { pointers[i][j] = 1; } } for(i = 0; i < 10; i++) { smart_free(sa, pointers[i]); } }
MySQLStmtVariables::~MySQLStmtVariables() { for (int i = 0; i < m_arr.size(); i++) { auto buf = &m_vars[i]; if (buf->buffer_length > 0) { smart_free(buf->buffer); } } smart_free(m_vars); smart_free(m_null); smart_free(m_length); }
void two_alloc(struct smart_alloc *sa) { char *message1; char *message2; message1 = smart_dup(sa, "Hello"); message2 = smart_dup(sa, "World"); printf("%s, %s!\n", message1, message2); smart_free(sa, message1); smart_free(sa, message2); }
void basic_free(struct smart_alloc *sa) { char *mem = smart_alloc(sa, BIG_ALLOC); smart_free(sa, mem); mem = smart_alloc(sa, BIG_ALLOC); if(mem) { printf("%d: OK\n", __LINE__); } else { printf("%d: NOT OK\n", __LINE__); } smart_free(sa, mem); }
void oom(struct smart_alloc *sa) { char *mem1 = smart_alloc(sa, BIG_ALLOC); char *mem2 = smart_alloc(sa, BIG_ALLOC); if(! mem2) { printf("%d: OK\n", __LINE__); } else { printf("%d: NOT OK\n", __LINE__); } smart_free(sa, mem1); smart_free(sa, mem2); }
inline void* MemoryManager::smartRealloc(void* inputPtr, size_t nbytes) { FTRACE(1, "smartRealloc: {} to {}\n", inputPtr, nbytes); assert(nbytes > 0); void* ptr = debug ? static_cast<DebugHeader*>(inputPtr) - 1 : inputPtr; auto const n = static_cast<SweepNode*>(ptr) - 1; if (LIKELY(n->padbytes <= kMaxSmartSize)) { void* newmem = smart_malloc(nbytes); auto const copySize = std::min( n->padbytes - sizeof(SmallNode) - (debug ? sizeof(DebugHeader) : 0), nbytes ); newmem = memcpy(newmem, inputPtr, copySize); smart_free(inputPtr); return newmem; } // Ok, it's a big allocation. Since we don't know how big it is // (i.e. how much data we should memcpy), we have no choice but to // ask malloc to realloc for us. auto const oldNext = n->next; auto const oldPrev = n->prev; auto const newNode = static_cast<SweepNode*>( realloc(n, debugAddExtra(nbytes + sizeof(SweepNode))) ); refreshStatsHelper(); if (newNode != n) { oldNext->prev = oldPrev->next = newNode; } return debugPostAllocate(newNode + 1, 0, 0); }
inline void* MemoryManager::smartRealloc(void* ptr, size_t nbytes) { FTRACE(3, "smartRealloc: {} to {}\n", ptr, nbytes); assert(nbytes > 0); auto const n = static_cast<MallocNode*>(ptr) - 1; if (LIKELY(n->small.padbytes <= kMaxSmartSize)) { void* newmem = smart_malloc(nbytes); auto const copySize = std::min( n->small.padbytes - sizeof(SmallNode), nbytes ); newmem = memcpy(newmem, ptr, copySize); smart_free(ptr); return newmem; } // Ok, it's a big allocation. Since we don't know how big it is // (i.e. how much data we should memcpy), we have no choice but to // ask malloc to realloc for us. auto const oldNext = n->big.next; auto const oldPrev = n->big.prev; auto const newNode = static_cast<BigNode*>( safe_realloc(n, nbytes + sizeof(BigNode)) ); refreshStats(); if (newNode != &n->big) { oldNext->prev = oldPrev->next = newNode; } return newNode + 1; }
static String HHVM_FUNCTION(get_current_user) { int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); if (pwbuflen < 1) { return ""; } char *pwbuf = (char*)smart_malloc(pwbuflen); struct passwd pw; struct passwd *retpwptr = NULL; if (getpwuid_r(getuid(), &pw, pwbuf, pwbuflen, &retpwptr) != 0) { smart_free(pwbuf); return ""; } String ret(pw.pw_name, CopyString); smart_free(pwbuf); return ret; }
MIterCtx::~MIterCtx() { m_mArray->~MutableArrayIter(); smart_free(m_mArray); tvRefcountedDecRef(&m_key); tvRefcountedDecRef(&m_val); if (m_ref) decRefRef(const_cast<RefData*>(m_ref)); }
MIterCtx::~MIterCtx() { m_mArray->~MutableArrayIter(); smart_free(m_mArray); tvRefcountedDecRef(&m_key); tvRefcountedDecRef(&m_val); if (m_ref && m_ref->decRefCount() == 0) { const_cast<RefData*>(m_ref)->release(); } }
void* smart_realloc(void* ptr, size_t nbytes) { auto& mm = MM(); if (!ptr) return smart_malloc(nbytes); if (!nbytes) { smart_free(ptr); return nullptr; } return mm.smartRealloc(ptr, nbytes); }
void basic_test(struct smart_alloc *sa) { char *message = smart_dup(sa, "Hello, World!"); printf("%s\n", message); smart_free(sa, message); }
/** * Delegate the responsibility for freeing the buffer to the * frozen copy, if it exists. */ BaseVector::~BaseVector() { if (m_frozenCopy.isNull() && m_data) { for (uint i = 0; i < m_size; ++i) { tvRefcountedDecRef(&m_data[i]); } smart_free(m_data); m_data = nullptr; } }
ALWAYS_INLINE SharedMap::~SharedMap() { if (m_localCache) { for (TypedValue* tv = m_localCache, *end = tv + m_arr->arrCap(); tv < end; ++tv) { tvRefcountedDecRef(tv); } smart_free(m_localCache); } m_arr->decRef(); }
HOT_FUNC SharedMap::~SharedMap() { if (m_localCache) { for (TypedValue* tv = m_localCache, *end = tv + size(); tv < end; ++tv) { tvRefcountedDecRef(tv); } smart_free(m_localCache); } }
ALWAYS_INLINE APCLocalArray::~APCLocalArray() { if (m_localCache) { for (TypedValue* tv = m_localCache, *end = tv + m_arr->capacity(); tv < end; ++tv) { tvRefcountedDecRef(tv); } smart_free(m_localCache); } m_arr->getHandle()->unreference(); }
HOT_FUNC_HPHP VectorArray::~VectorArray() { uint size = m_size; for (uint i = 0; i < size; i++) { tvAsVariant(&m_elems[i]).~Variant(); } if (m_allocMode == kSmart) { smart_free(m_elems); } else if (m_allocMode == kMalloc) { free(m_elems); } }
static Variant HHVM_FUNCTION(gmp_strval, const Variant& data, const int64_t base /* = 10 */) { mpz_t gmpData; if (base < GMP_MIN_BASE || (base > -2 && base < 2) || base > GMP_MAX_BASE) { raise_warning(cs_GMP_INVALID_BASE_VALUE, cs_GMP_FUNC_NAME_GMP_STRVAL, base, GMP_MAX_BASE); return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_STRVAL, gmpData, data, base)) { return false; } int charLength = mpz_sizeinbase(gmpData, abs(base)) + 1; if (mpz_sgn(gmpData) < 0) { ++charLength; } char *charStr = (char*) smart_malloc(charLength); if (!mpz_get_str(charStr, base, gmpData)) { smart_free(charStr); mpz_clear(gmpData); return false; } String returnValue(charStr); smart_free(charStr); mpz_clear(gmpData); return returnValue; }
void XDebugServer::deinitDbgp() { setStatus(Status::STOPPING, Reason::OK); // Send the xml shutdown response xdebug_xml_node* response = xdebug_xml_node_init("response"); addXmnls(*response); addCmdAndTrans(*response); sendMessage(*response); xdebug_xml_node_dtor(response); // Wait for a response from the client doCommandLoop(); // Free the input buffer smart_free(m_buffer); }
inline void* MemoryManager::smartRealloc(void* ptr, size_t nbytes) { FTRACE(3, "smartRealloc: {} to {}\n", ptr, nbytes); assert(nbytes > 0); auto const n = static_cast<MallocNode*>(ptr) - 1; if (LIKELY(n->small.padbytes <= kMaxSmartSize)) { void* newmem = smart_malloc(nbytes); auto const copySize = std::min( n->small.padbytes - sizeof(SmallNode), nbytes ); newmem = memcpy(newmem, ptr, copySize); smart_free(ptr); return newmem; } // Ok, it's a big allocation. auto block = m_heap.resizeBig(ptr, nbytes); refreshStats(); return block.ptr; }
String StringUtil::Implode(const Variant& items, const String& delim) { if (!isContainer(items)) { throw_param_is_not_container(); } int size = getContainerSize(items); if (size == 0) return ""; String* sitems = (String*)smart_malloc(size * sizeof(String)); int len = 0; int lenDelim = delim.size(); int i = 0; for (ArrayIter iter(items); iter; ++iter) { new (&sitems[i]) String(iter.second().toString()); len += sitems[i].size() + lenDelim; i++; } len -= lenDelim; // always one delimiter less than count of items assert(i == size); String s = String(len, ReserveString); char *buffer = s.bufferSlice().ptr; const char *sdelim = delim.data(); char *p = buffer; for (int i = 0; i < size; i++) { String &item = sitems[i]; if (i && lenDelim) { memcpy(p, sdelim, lenDelim); p += lenDelim; } int lenItem = item.size(); if (lenItem) { memcpy(p, item.data(), lenItem); p += lenItem; } sitems[i].~String(); } smart_free(sitems); assert(p - buffer == len); s.setSize(len); return s; }
void StringBuffer::printf(const char *format, ...) { va_list ap; va_start(ap, format); bool printed = false; for (int len = 1024; !printed; len <<= 1) { va_list v; va_copy(v, ap); char *buf = (char*)smart_malloc(len); if (vsnprintf(buf, len, format, v) < len) { append(buf); printed = true; } smart_free(buf); va_end(v); } va_end(ap); }
HOT_FUNC void StringData::releaseDataSlowPath() { assert(!isSmall()); assert(checkSane()); auto const loadedMode = mode(); if (LIKELY(loadedMode == Mode::Smart)) { smart_free(m_data); return; } if (loadedMode == Mode::Shared) { assert(checkSane()); m_big.shared->decRef(); delist(); return; } assert(loadedMode == Mode::Malloc); assert(checkSane()); free(m_data); }
/* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */ char * php_conv_fp(register char format, register double num, bool add_dp, int precision, char dec_point, int *is_negative, char *buf, int *len) { register char *s = buf; register char *p, *p_orig; int decimal_point; if (precision >= NDIG - 1) { precision = NDIG - 2; } if (format == 'F') { p_orig = p = php_fcvt(num, precision, &decimal_point, is_negative); } else { // either e or E format p_orig = p = php_ecvt(num, precision + 1, &decimal_point, is_negative); } // Check for Infinity and NaN if (isalpha((int)*p)) { *len = strlen(p); memcpy(buf, p, *len + 1); *is_negative = 0; smart_free(p_orig); return (buf); } if (format == 'F') { if (decimal_point <= 0) { if (num != 0 || precision > 0) { *s++ = '0'; if (precision > 0) { *s++ = dec_point; while (decimal_point++ < 0) { *s++ = '0'; } } else if (add_dp) { *s++ = dec_point; } } } else { int addz = decimal_point >= NDIG ? decimal_point - NDIG + 1 : 0; decimal_point -= addz; while (decimal_point-- > 0) { *s++ = *p++; } while (addz-- > 0) { *s++ = '0'; } if (precision > 0 || add_dp) { *s++ = dec_point; } } } else { *s++ = *p++; if (precision > 0 || add_dp) { *s++ = '.'; } } // copy the rest of p, the NUL is NOT copied while (*p) { *s++ = *p++; } if (format != 'F') { char temp[EXPONENT_LENGTH]; // for exponent conversion int t_len; int exponent_is_negative; *s++ = format; // either e or E decimal_point--; if (decimal_point != 0) { p = ap_php_conv_10((int64_t) decimal_point, false, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; // Make sure the exponent has at least 2 digits while (t_len--) { *s++ = *p++; } } else { *s++ = '+'; *s++ = '0'; } } *len = s - buf; smart_free(p_orig); return (buf); }
static Array HHVM_FUNCTION(getopt, const String& options, const Variant& longopts /*=null */) { opt_struct *opts, *orig_opts; int len = parse_opts(options.data(), options.size(), &opts); if (!longopts.isNull()) { Array arropts = longopts.toArray(); int count = arropts.size(); /* the first <len> slots are filled by the one short ops * we now extend our array and jump to the new added structs */ opts = (opt_struct *)smart_realloc( opts, sizeof(opt_struct) * (len + count + 1)); orig_opts = opts; opts += len; memset(opts, 0, count * sizeof(opt_struct)); for (ArrayIter iter(arropts); iter; ++iter) { String entry = iter.second().toString(); opts->need_param = 0; opts->opt_name = strdup(entry.data()); len = strlen(opts->opt_name); if ((len > 0) && (opts->opt_name[len - 1] == ':')) { opts->need_param++; opts->opt_name[len - 1] = '\0'; if ((len > 1) && (opts->opt_name[len - 2] == ':')) { opts->need_param++; opts->opt_name[len - 2] = '\0'; } } opts->opt_char = 0; opts++; } } else { opts = (opt_struct*) smart_realloc(opts, sizeof(opt_struct) * (len + 1)); orig_opts = opts; opts += len; } /* php_getopt want to identify the last param */ opts->opt_char = '-'; opts->need_param = 0; opts->opt_name = NULL; static const StaticString s_argv("argv"); Array vargv = php_global(s_argv).toArray(); int argc = vargv.size(); char **argv = (char **)smart_malloc((argc+1) * sizeof(char*)); std::vector<String> holders; int index = 0; for (ArrayIter iter(vargv); iter; ++iter) { String arg = iter.second().toString(); holders.push_back(arg); argv[index++] = (char*)arg.data(); } argv[index] = NULL; /* after our pointer arithmetic jump back to the first element */ opts = orig_opts; int o; char *php_optarg = NULL; int php_optind = 1; SCOPE_EXIT { free_longopts(orig_opts); smart_free(orig_opts); smart_free(argv); }; Array ret = Array::Create(); Variant val; int optchr = 0; int dash = 0; /* have already seen the - */ char opt[2] = { '\0' }; char *optname; int optname_len = 0; int php_optidx; while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1, optchr, dash, php_optidx)) != -1) { /* Skip unknown arguments. */ if (o == '?') { continue; } /* Prepare the option character and the argument string. */ if (o == 0) { optname = opts[php_optidx].opt_name; } else { if (o == 1) { o = '-'; } opt[0] = o; optname = opt; } if (php_optarg != NULL) { /* keep the arg as binary, since the encoding is not known */ val = String(php_optarg, CopyString); } else { val = false; } /* Add this option / argument pair to the result hash. */ optname_len = strlen(optname); if (!(optname_len > 1 && optname[0] == '0') && is_numeric_string(optname, optname_len, NULL, NULL, 0) == KindOfInt64) { /* numeric string */ int optname_int = atoi(optname); if (ret.exists(optname_int)) { Variant &e = ret.lvalAt(optname_int); if (!e.isArray()) { ret.set(optname_int, make_packed_array(e, val)); } else { e.toArrRef().append(val); } } else { ret.set(optname_int, val); } } else { /* other strings */ String key(optname, strlen(optname), CopyString); if (ret.exists(key)) { Variant &e = ret.lvalAt(key); if (!e.isArray()) { ret.set(key, make_packed_array(e, val)); } else { e.toArrRef().append(val); } } else { ret.set(key, val); } } php_optarg = NULL; } return ret; }
void free_null(struct smart_alloc *sa) { smart_free(sa, NULL); }
ZendCustomElement::~ZendCustomElement() { if (m_destructor) m_destructor(m_data); smart_free(m_data); }
static double collator_u_strtod(const UChar *nptr, UChar **endptr) { const UChar *u = nptr, *nstart; UChar c = *u; int any = 0; while (u_isspace(c)) { c = *++u; } nstart = u; if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { c = *++u; } while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { any = 1; c = *++u; } if (c == 0x2E /*'.'*/) { c = *++u; while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { any = 1; c = *++u; } } if ((c == 0x65 /*'e'*/ || c == 0x45 /*'E'*/) && any) { const UChar *e = u; int any_exp = 0; c = *++u; if (c == 0x2D /*'-'*/ || c == 0x2B /*'+'*/) { c = *++u; } while (c >= 0x30 /*'0'*/ && c <= 0x39 /*'9'*/) { any_exp = 1; c = *++u; } if (!any_exp) { u = e; } } if (any) { char buf[64], *numbuf, *bufpos; int length = u - nstart; double value; if (length < (int)sizeof(buf)) { numbuf = buf; } else { numbuf = (char *) smart_malloc(length + 1); } bufpos = numbuf; while (nstart < u) { *bufpos++ = (char) *nstart++; } *bufpos = '\0'; value = zend_strtod(numbuf, nullptr); if (numbuf != buf) { smart_free(numbuf); } if (endptr != nullptr) { *endptr = (UChar *)u; } return value; } if (endptr != nullptr) { *endptr = (UChar *)nptr; } return 0; }
static void php_xml_free_wrapper(void *ptr) { if (ptr) { smart_free(ptr); } }
static bool HHVM_METHOD(Collator, sortWithSortKeys, VRefParam arr) { FETCH_COL(data, this_, false); data->clearError(); if (!arr.isArray()) { return true; } Array hash = arr.toArray(); if (hash.size() == 0) { return true; } // Preallocate sort keys buffer size_t sortKeysOffset = 0; size_t sortKeysLength = DEF_SORT_KEYS_BUF_SIZE; char* sortKeys = (char*)smart_malloc(sortKeysLength); if (!sortKeys) { throw Exception("Out of memory"); } SCOPE_EXIT{ smart_free(sortKeys); }; // Preallocate index buffer size_t sortIndexPos = 0; size_t sortIndexLength = DEF_SORT_KEYS_INDX_BUF_SIZE; auto sortIndex = (collator_sort_key_index_t*)smart_malloc( sortIndexLength * sizeof(collator_sort_key_index_t)); if (!sortIndex) { throw Exception("Out of memory"); } SCOPE_EXIT{ smart_free(sortIndex); }; // Translate input hash to sortable index auto pos_limit = hash->iter_end(); for (ssize_t pos = hash->iter_begin(); pos != pos_limit; pos = hash->iter_advance(pos)) { Variant val(hash->getValue(pos)); // Convert to UTF16 icu::UnicodeString strval; if (val.isString()) { UErrorCode error = U_ZERO_ERROR; strval = u16(val.toString(), error); if (U_FAILURE(error)) { return false; } } // Generate sort key int sortkey_len = ucol_getSortKey(data->collator(), strval.getBuffer(), strval.length(), (uint8_t*)(sortKeys + sortKeysOffset), sortKeysLength - sortKeysOffset); // Check for key buffer overflow if (sortkey_len > (sortKeysLength - sortKeysOffset)) { int32_t inc = (sortkey_len > DEF_SORT_KEYS_BUF_INCREMENT) ? sortkey_len : DEF_SORT_KEYS_BUF_INCREMENT; sortKeysLength += inc; sortKeys = (char*)smart_realloc(sortKeys, sortKeysLength); if (!sortKeys) { throw Exception("Out of memory"); } sortkey_len = ucol_getSortKey(data->collator(), strval.getBuffer(), strval.length(), (uint8_t*)(sortKeys + sortKeysOffset), sortKeysLength - sortKeysOffset); assert(sortkey_len <= (sortKeysLength - sortKeysOffset)); } // Check for index buffer overflow if ((sortIndexPos + 1) > sortIndexLength) { sortIndexLength += DEF_SORT_KEYS_INDX_BUF_INCREMENT; sortIndex = (collator_sort_key_index_t*)smart_realloc(sortIndex, sortIndexLength * sizeof(collator_sort_key_index_t)); if (!sortIndex) { throw Exception("Out of memory"); } } // Initially store offset into buffer, update later to deal with reallocs sortIndex[sortIndexPos].key = (char*)sortKeysOffset; sortKeysOffset += sortkey_len; sortIndex[sortIndexPos].valPos = pos; ++sortIndexPos; } // Update keys to location in realloc'd buffer for (int i = 0; i < sortIndexPos; ++i) { sortIndex[i].key = sortKeys + (ptrdiff_t)sortIndex[i].key; } zend_qsort(sortIndex, sortIndexPos, sizeof(collator_sort_key_index_t), collator_cmp_sort_keys, nullptr); Array ret = Array::Create(); for (int i = 0; i < sortIndexPos; ++i) { ret.append(hash->getValue(sortIndex[i].valPos)); } arr = ret; return true; }