Skip to content

add blazingly fast instance_cache implementation for K2 - #1683

Open
denisichh wants to merge 29 commits into
masterfrom
dzubarev/k2/add-instance-cache
Open

add blazingly fast instance_cache implementation for K2#1683
denisichh wants to merge 29 commits into
masterfrom
dzubarev/k2/add-instance-cache

Conversation

@denisichh

Copy link
Copy Markdown
Contributor

Rewrites instance_cache_store/fetch/update_ttl/delete in the K2 runtime: instead of msgpack-serializing and shipping instances to a separate cache process over RPC, instances are now deep-copied directly into shared memory via the platform's k2::alloc_shared_memory/publish_shared_memory/get_shared_memory.

Storage layout: class_name_hash(u64) | class_instance shell | inner data. On fetch, the block is reinterpreted in place rather than deserialized.

Key pieces

  • New "construct-in-place" API on core types (class_instance::clone_in/alloc, array::allocation/copy_in, string::copy_in) -- lets objects be constructed directly into a caller-provided memory span instead of the script memory pool.
  • New shared CRTP visitor base kphp::visitors::instance_deep_basic_visitor (runtime-common/stdlib/visitors/instance deep-basic-visitor.h), factored out of the legacy runtime's copy processor so both runtimes share the same traversal logic. Legacy's InstanceReferencesCountingVisitor/InstanceDeepCopyVisitor/InstanceDeepDestroyVisitor now build on it too.
  • Two new K2 visitors: instance_deep_copy_visitor (copies an instance graph into a caller-provided block, pinning copies with ExtraRefCnt::for_instance_cache) and instance_deep_estimate_size_visitor (computes the exact size needed upfront so the shared-memory block can be allocated once).
  • Alignment: added virtual_builtin_alignof() (dispatches to the dynamic type's alignment for polymorphic clones) plus alignment() helpers on class_instance/array/string, and a padding-aware align_for_chunk(size, align) used with std::align() when carving memory from a pool.
  • Removed is_serializable/@kphp-serializable compiler checks for instance-cache calls.

@denisichh denisichh self-assigned this Aug 27, 2026
@denisichh denisichh added runtime Feature related to runtime compiler Feature related to compiler k2 Affects compiler or runtime in K2 mode kphp Affects compiler or runtime in default mode (not K2) labels Aug 27, 2026
@denisichh
denisichh force-pushed the dzubarev/k2/add-instance-cache branch from 454d684 to 80eabdd Compare August 28, 2026 09:43
@denisichh
denisichh force-pushed the dzubarev/k2/add-instance-cache branch from 4ebc228 to 81cee3f Compare September 8, 2026 09:16
}

void ClassDeclaration::compile_class_name_hash(CodeGenerator& W, ClassPtr klass) {
// hash of the class name, computed once at compile time -- same for every instance,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that it would be better not to introduce a new field. We already have get_hash in class_instance, which can be helpful, but it has a specific corner case: class_instance<T>{}.get_hash() == nullptr, while class_instance<T>{}.alloc().get_hash() != nullptr. I think you have two possible options:

  • Adjust the existing get_hash to provide the required semantics.
  • Add a new method (e.g., get_type_hash or similar).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


compile_class_method(FunctionSignatureGenerator(W).set_const_this(), klass, "size_t virtual_builtin_sizeof()", "sizeof(*this)");

compile_class_method(FunctionSignatureGenerator(W).set_const_this(), klass, "size_t virtual_builtin_alignof()", "alignof(" + klass->src_name + ")");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this?

// memory must be aligned to alignof(T) and >= estimate_memory_usage() bytes
// caller must pin it with a special ExtraRefCnt (e.g. for_instance_cache), since the instance never frees it.
// Returns a null instance if memory is unfit.
inline class_instance clone_in(vk::span<std::byte> memory) const noexcept;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have an ability to return something like variant?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// constructs an instance in externally provided memory (no allocation/ownership)
// leaves it null if memory is smaller than sizeof(T) or misaligned
template<class... Args>
inline class_instance<T> alloc(vk::span<std::byte> memory, Args&&... args) noexcept __attribute__((always_inline));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would be better to rename into alloc_in based on 2 reasons:

  • More regular and coherent with clone_in
  • Do not produce a new overload

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread compiler/code-gen/declarations.cpp
std::enable_if_t<std::is_polymorphic<S>{}, class_instance> virtual_builtin_clone_in(vk::span<std::byte> memory) const noexcept {
class_instance res;
if (o) {
if (unlikely(memory.size() < o->virtual_builtin_sizeof() || reinterpret_cast<std::uintptr_t>(memory.data()) % o->virtual_builtin_alignof() != 0)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend to add nullptr check for memory.data()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler Feature related to compiler k2 Affects compiler or runtime in K2 mode kphp Affects compiler or runtime in default mode (not K2) runtime Feature related to runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants