// Create either a static or an uncounted string. // Diffrence between static and uncounted is in the lifetime // of the string. Static are alive for the lifetime of the process. // Uncounted are not ref counted but will be deleted at some point. ALWAYS_INLINE StringData* StringData::MakeShared(folly::StringPiece sl, bool trueStatic) { if (UNLIKELY(sl.size() > StringData::MaxSize)) { throw_string_too_large(sl.size()); } auto const cc = CapCode::ceil(sl.size()); auto const need = cc.decode() + kCapOverhead; auto const sd = static_cast<StringData*>( trueStatic ? low_malloc_data(need) : malloc(need) ); auto const data = reinterpret_cast<char*>(sd + 1); #ifndef NO_M_DATA sd->m_data = data; #endif auto const count = trueStatic ? StaticValue : UncountedValue; sd->m_hdr.init(cc, HeaderKind::String, count); sd->m_len = sl.size(); // m_hash is computed soon. data[sl.size()] = 0; auto const mcret = memcpy(data, sl.data(), sl.size()); auto const ret = reinterpret_cast<StringData*>(mcret) - 1; // Recalculating ret from mcret avoids a spill. ret->preCompute(); // get m_hash right assert(ret == sd); assert(ret->isFlat()); assert(trueStatic ? ret->isStatic() : ret->isUncounted()); assert(ret->checkSane()); return ret; }
void processInit() { auto codeLock = lockCode(); auto metaLock = lockMetadata(); g_code = new(low_malloc_data(sizeof(CodeCache))) CodeCache(); g_ustubs.emitAll(*g_code, *Debug::DebugInfo::Get()); // Write an .eh_frame section that covers the whole TC. initUnwinder(g_code->base(), g_code->codeSize()); Disasm::ExcludedAddressRange(g_code->base(), g_code->codeSize()); }