MutableSlice StringData::reserve(int cap) { assert(!isImmutable() && m_count <= 1 && cap >= 0); if (cap + 1 <= capacity()) return mutableSlice(); switch (mode()) { default: assert(false); case Mode::Small: m_data = (char*) smart_malloc(cap + 1); memcpy(m_data, m_small, m_len + 1); // includes \0 setModeAndCap(Mode::Smart, cap + 1); break; case Mode::Smart: // We only use geometric growth when we're heading to the smart // allocator. This is mostly because it was what was tested as // a perf win, but it might make sense to do it for Mode::Malloc // as well. Will be revisited soon. cap += cap >> 2; m_data = (char*) smart_realloc(m_data, cap + 1); setModeAndCap(Mode::Smart, cap + 1); break; case Mode::Malloc: m_data = (char*) realloc(m_data, cap + 1); setModeAndCap(Mode::Malloc, cap + 1); break; } return MutableSlice(m_data, cap); }
void XDebugProfiler::ensureBufferSpace() { if (m_nextFrameIdx < m_frameBufferSize) { return; } // The initial buffer size is 0 int64_t new_buf_size = (m_frameBufferSize == 0)? XDEBUG_GLOBAL(FramebufSize) : m_frameBufferSize * XDEBUG_GLOBAL(FramebufExpansion); try { int64_t new_buf_bytes = new_buf_size * sizeof(FrameData); m_frameBuffer = (FrameData*) smart_realloc((void*) m_frameBuffer, new_buf_bytes); m_frameBufferSize = new_buf_size; } catch (const OutOfMemoryException& e) { raise_error("Cannot allocate more memory for the xdebug profiler. Consider " "turning off profiling or tracing. Note that certain ini " "settings such as hhvm.xdebug.collect_memory and " "hhvm.xdebug.collect_time implicitly " "turn on tracing, so turn those off if this is unexpected.\n" "Current frame buffer length: %zu\n" "Failed to expand to length: %zu\n", m_frameBufferSize, new_buf_size); } }
void BaseVector::grow() { if (m_capacity) { m_capacity += m_capacity; } else { m_capacity = 8; } m_data = (TypedValue*)smart_realloc(m_data, m_capacity * sizeof(TypedValue)); }
void BaseVector::reserve(int64_t sz) { if (sz <= 0) return; if (m_capacity < sz) { ++m_version; m_capacity = sz; m_data = (TypedValue*)smart_realloc(m_data, m_capacity * sizeof(TypedValue)); } }
StringData* StringData::shrink(int len) { setSize(len); switch (mode()) { case Mode::Smart: m_data = (char*) smart_realloc(m_data, len + 1); setModeAndCap(Mode::Smart, len + 1); break; case Mode::Malloc: m_data = (char*) realloc(m_data, len + 1); setModeAndCap(Mode::Malloc, len + 1); break; default: // don't shrink break; } return this; }
void XDebugServer::readInput() { size_t bytes_read = 0; do { size_t bytes_left = m_bufferSize - bytes_read; // Expand if we need to if (bytes_left == 0) { m_bufferSize = (m_bufferSize == 0) ? INPUT_BUFFER_INIT_SIZE : m_bufferSize * INPUT_BUFFER_EXPANSION; bytes_left = m_bufferSize - bytes_read; m_buffer = (char*) smart_realloc(m_buffer, m_bufferSize); } // Read into the buffer size_t res = recv(m_socket, (void*) &m_buffer[bytes_read], bytes_left, 0); if (res < 0) { return; } bytes_read += res; } while (m_buffer[bytes_read - 1] != '\0'); }
void VectorArray::grow(uint newSize) { assert(newSize > FixedSize); m_capacity = Util::nextPower2(newSize); if (!m_nonsmart) { assert(m_allocMode == kInline || m_allocMode == kSmart); if (m_allocMode == kInline) { m_elems = (TypedValue*)smart_malloc(m_capacity * sizeof(TypedValue)); memcpy(m_elems, m_fixed, m_size * sizeof(TypedValue)); m_allocMode = kSmart; } else { m_elems = (TypedValue*)smart_realloc(m_elems, m_capacity * sizeof(TypedValue)); } } else if (m_allocMode == kInline) { m_elems = (TypedValue*)malloc(m_capacity * sizeof(TypedValue)); memcpy(m_elems, m_fixed, m_size * sizeof(TypedValue)); m_allocMode = kMalloc; } else { assert(m_allocMode == kMalloc); m_elems = (TypedValue*)realloc(m_elems, m_capacity * sizeof(TypedValue)); } }
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; }
static void *php_xml_realloc_wrapper(void *ptr, size_t sz) { return smart_realloc(ptr, sz); }
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; }