Skip to content

Commit 46d481b

Browse files
authored
[k2] add AllocatorState and libc_alloc_guard (#1316)
1 parent b3c0352 commit 46d481b

File tree

9 files changed

+121
-42
lines changed

9 files changed

+121
-42
lines changed

runtime-light/allocator-wrapper/libc-alloc-wrapper.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,34 @@
44

55
#include <cstddef>
66

7+
#include "runtime-common/core/allocator/script-malloc-interface.h"
8+
#include "runtime-light/allocator/allocator-state.h"
79
#include "runtime-light/utils/logs.h"
810

9-
extern "C" void* __wrap_malloc([[maybe_unused]] size_t size) noexcept {
10-
kphp::log::error("unexpected use of malloc");
11+
extern "C" void* __wrap_malloc(size_t size) noexcept {
12+
if (!AllocatorState::get().libc_alloc_allowed()) [[unlikely]] {
13+
kphp::log::error("unexpected use of malloc");
14+
}
15+
return kphp::memory::script::alloc(size);
1116
}
1217

13-
extern "C" void __wrap_free([[maybe_unused]] void* ptr) noexcept {
14-
kphp::log::error("unexpected use of free");
18+
extern "C" void __wrap_free(void* ptr) noexcept {
19+
if (!AllocatorState::get().libc_alloc_allowed()) [[unlikely]] {
20+
kphp::log::error("unexpected use of free");
21+
}
22+
kphp::memory::script::free(ptr);
1523
}
1624

17-
extern "C" void* __wrap_calloc([[maybe_unused]] size_t nmemb, [[maybe_unused]] size_t size) noexcept {
18-
kphp::log::error("unexpected use of calloc");
25+
extern "C" void* __wrap_calloc(size_t nmemb, size_t size) noexcept {
26+
if (!AllocatorState::get().libc_alloc_allowed()) [[unlikely]] {
27+
kphp::log::error("unexpected use of calloc");
28+
}
29+
return kphp::memory::script::calloc(nmemb, size);
1930
}
2031

2132
extern "C" void* __wrap_realloc([[maybe_unused]] void* ptr, [[maybe_unused]] size_t size) noexcept {
22-
kphp::log::error("unexpected use of realloc");
33+
if (!AllocatorState::get().libc_alloc_allowed()) [[unlikely]] {
34+
kphp::log::error("unexpected use of realloc");
35+
}
36+
return kphp::memory::script::realloc(ptr, size);
2337
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Compiler for PHP (aka KPHP)
2+
// Copyright (c) 2025 LLC «V Kontakte»
3+
// Distributed under the GPL v3 License, see LICENSE.notice.txt
4+
5+
#include "runtime-light/allocator/allocator-state.h"
6+
7+
#include "runtime-light/k2-platform/k2-api.h"
8+
#include "runtime-light/state/component-state.h"
9+
#include "runtime-light/state/image-state.h"
10+
#include "runtime-light/state/instance-state.h"
11+
#include "runtime-light/utils/logs.h"
12+
13+
const AllocatorState& AllocatorState::get() noexcept {
14+
if (const auto* instance_state_ptr{k2::instance_state()}; instance_state_ptr != nullptr) [[likely]] {
15+
return instance_state_ptr->instance_allocator_state;
16+
} else if (const auto* component_state_ptr{k2::component_state()}; component_state_ptr != nullptr) {
17+
return component_state_ptr->component_allocator_state;
18+
} else if (const auto* image_state_ptr{k2::image_state()}; image_state_ptr != nullptr) {
19+
return image_state_ptr->image_allocator_state;
20+
}
21+
kphp::log::error("can't find allocator state");
22+
}
23+
24+
AllocatorState& AllocatorState::get_mutable() noexcept {
25+
return const_cast<AllocatorState&>(AllocatorState::get());
26+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Compiler for PHP (aka KPHP)
2+
// Copyright (c) 2025 LLC «V Kontakte»
3+
// Distributed under the GPL v3 License, see LICENSE.notice.txt
4+
5+
#pragma once
6+
7+
#include <cstddef>
8+
#include <cstdint>
9+
10+
#include "common/mixin/not_copyable.h"
11+
#include "runtime-common/core/allocator/runtime-allocator.h"
12+
#include "runtime-light/utils/logs.h"
13+
14+
class AllocatorState final : private vk::not_copyable {
15+
uint32_t m_libc_alloc_allowed{};
16+
17+
public:
18+
RuntimeAllocator allocator;
19+
20+
void enable_libc_alloc() noexcept {
21+
++m_libc_alloc_allowed;
22+
}
23+
void disable_libc_alloc() noexcept {
24+
kphp::log::assertion(m_libc_alloc_allowed-- != 0);
25+
}
26+
bool libc_alloc_allowed() const noexcept {
27+
return m_libc_alloc_allowed != 0;
28+
}
29+
30+
AllocatorState(size_t script_mem_size, size_t oom_handling_mem_size) noexcept
31+
: allocator(script_mem_size, oom_handling_mem_size) {}
32+
33+
static const AllocatorState& get() noexcept;
34+
static AllocatorState& get_mutable() noexcept;
35+
};
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
set(RUNTIME_LIGHT_ALLOCATOR_SRC allocator/runtime-light-allocator.cpp)
1+
set(RUNTIME_LIGHT_ALLOCATOR_SRC allocator/allocator-state.cpp
2+
allocator/runtime-light-allocator.cpp)

runtime-light/allocator/allocator.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,29 @@
88
#include <cstddef>
99

1010
#include "runtime-common/core/allocator/script-allocator-managed.h"
11+
#include "runtime-light/allocator/allocator-state.h"
1112

1213
template<std::derived_from<ScriptAllocatorManaged> T, typename... Args>
1314
requires std::constructible_from<T, Args...>
1415
auto make_unique_on_script_memory(Args&&... args) noexcept {
1516
return std::make_unique<T>(std::forward<Args>(args)...);
1617
}
18+
19+
namespace kphp::memory {
20+
21+
struct libc_alloc_guard final {
22+
libc_alloc_guard() noexcept {
23+
AllocatorState::get_mutable().enable_libc_alloc();
24+
}
25+
26+
~libc_alloc_guard() {
27+
AllocatorState::get_mutable().disable_libc_alloc();
28+
}
29+
30+
libc_alloc_guard(const libc_alloc_guard&) = delete;
31+
libc_alloc_guard(libc_alloc_guard&&) = delete;
32+
libc_alloc_guard& operator=(const libc_alloc_guard&) = delete;
33+
libc_alloc_guard& operator=(libc_alloc_guard&&) = delete;
34+
};
35+
36+
} // namespace kphp::memory

runtime-light/allocator/runtime-light-allocator.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
#include <cstddef>
77
#include <cstring>
88

9+
#include "runtime-light/allocator/allocator-state.h"
910
#include "runtime-light/k2-platform/k2-api.h"
10-
#include "runtime-light/state/component-state.h"
11-
#include "runtime-light/state/image-state.h"
12-
#include "runtime-light/state/instance-state.h"
1311
#include "runtime-light/utils/logs.h"
1412

1513
namespace {
@@ -27,14 +25,7 @@ void request_extra_memory(size_t requested_size) noexcept {
2725
} // namespace
2826

2927
RuntimeAllocator& RuntimeAllocator::get() noexcept {
30-
if (k2::instance_state() != nullptr) [[likely]] {
31-
return InstanceState::get().allocator;
32-
} else if (k2::component_state() != nullptr) {
33-
return ComponentState::get_mutable().allocator;
34-
} else if (k2::image_state() != nullptr) {
35-
return ImageState::get_mutable().allocator;
36-
}
37-
kphp::log::error("no available allocators");
28+
return AllocatorState::get_mutable().allocator;
3829
}
3930

4031
RuntimeAllocator::RuntimeAllocator(size_t script_mem_size, size_t oom_handling_mem_size) {

runtime-light/state/component-state.h

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,20 @@
99
#include <string_view>
1010

1111
#include "common/mixin/not_copyable.h"
12-
#include "runtime-common/core/allocator/runtime-allocator.h"
1312
#include "runtime-common/core/runtime-core.h"
13+
#include "runtime-light/allocator/allocator-state.h"
1414
#include "runtime-light/k2-platform/k2-api.h"
1515

1616
struct ComponentState final : private vk::not_copyable {
17-
RuntimeAllocator allocator;
17+
AllocatorState component_allocator_state{INIT_COMPONENT_ALLOCATOR_SIZE, 0};
1818

19-
const uint32_t argc;
20-
const uint32_t envc;
19+
const uint32_t argc{k2::args_count()};
20+
const uint32_t envc{k2::env_count()};
21+
array<string> ini_opts{array_size{argc, false}};
22+
array<mixed> env{array_size{envc, false}};
2123
mixed runtime_config;
22-
array<string> ini_opts;
23-
array<mixed> env;
24-
25-
ComponentState() noexcept
26-
: allocator(INIT_COMPONENT_ALLOCATOR_SIZE, 0),
27-
argc(k2::args_count()),
28-
envc(k2::env_count()),
29-
ini_opts(array_size{argc, false}) /* overapproximation */
30-
,
31-
env(array_size{envc, false}) {
24+
25+
ComponentState() noexcept {
3226
parse_env();
3327
parse_args();
3428
}

runtime-light/state/image-state.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
#include "common/mixin/not_copyable.h"
1313
#include "common/php-functions.h"
14-
#include "runtime-common/core/allocator/runtime-allocator.h"
1514
#include "runtime-common/core/runtime-core.h"
15+
#include "runtime-light/allocator/allocator-state.h"
1616
#include "runtime-light/k2-platform/k2-api.h"
1717
#include "runtime-light/stdlib/math/math-state.h"
1818
#include "runtime-light/stdlib/rpc/rpc-client-state.h"
@@ -21,10 +21,10 @@
2121
#include "runtime-light/utils/logs.h"
2222

2323
struct ImageState final : private vk::not_copyable {
24-
RuntimeAllocator allocator;
24+
AllocatorState image_allocator_state{INIT_IMAGE_ALLOCATOR_SIZE, 0};
2525

2626
char* c_linear_mem{nullptr};
27-
uint32_t pid{};
27+
uint32_t pid{k2::getpid()};
2828
string uname_info_s;
2929
string uname_info_n;
3030
string uname_info_r;
@@ -38,9 +38,7 @@ struct ImageState final : private vk::not_copyable {
3838
StringImageState string_image_state;
3939
MathImageState math_image_state;
4040

41-
ImageState() noexcept
42-
: allocator(INIT_IMAGE_ALLOCATOR_SIZE, 0),
43-
pid(k2::getpid()) {
41+
ImageState() noexcept {
4442
utsname uname_info{};
4543
if (const auto errc{k2::uname(std::addressof(uname_info))}; errc != k2::errno_ok) [[unlikely]] {
4644
kphp::log::error("can't get uname, error code: {}", errc);

runtime-light/state/instance-state.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#include <utility>
1212

1313
#include "common/mixin/not_copyable.h"
14-
#include "runtime-common/core/allocator/runtime-allocator.h"
1514
#include "runtime-common/core/runtime-core.h"
1615
#include "runtime-common/core/std/containers.h"
16+
#include "runtime-light/allocator/allocator-state.h"
1717
#include "runtime-light/core/globals/php-script-globals.h"
1818
#include "runtime-light/coroutine/task.h"
1919
#include "runtime-light/k2-platform/k2-api.h"
@@ -62,7 +62,7 @@ struct InstanceState final : vk::not_copyable {
6262
using list = kphp::stl::list<T, kphp::memory::script_allocator>;
6363

6464
InstanceState() noexcept
65-
: allocator(INIT_INSTANCE_ALLOCATOR_SIZE, 0) {}
65+
: instance_allocator_state(INIT_INSTANCE_ALLOCATOR_SIZE, 0) {}
6666

6767
~InstanceState() = default;
6868

@@ -106,7 +106,7 @@ struct InstanceState final : vk::not_copyable {
106106
void release_stream(uint64_t) noexcept;
107107
void release_all_streams() noexcept;
108108

109-
RuntimeAllocator allocator;
109+
AllocatorState instance_allocator_state;
110110

111111
CoroutineScheduler scheduler;
112112
ForkInstanceState fork_instance_state;

0 commit comments

Comments
 (0)