Skip to content

Commit 838372b

Browse files
committed
avoid additional allocation
1 parent 60157e0 commit 838372b

1 file changed

Lines changed: 25 additions & 17 deletions

File tree

echion/stack_chunk.h

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
#define PY_SSIZE_T_CLEAN
88
#include <Python.h>
99

10-
// Python 3.13+ stack chunk minimum size (16KB)
11-
// This is the minimum size of a stack chunk from Python's implementation
12-
// https://github.com/python/cpython/blob/f6536d48cd294f3dea6a4ecfd8148aa505dbb581/Python/pystate.c#L1417
13-
#define _PY_DATA_STACK_CHUNK_SIZE (16 * 1024)
14-
1510
#include <exception>
1611
#include <memory>
1712
#include <vector>
@@ -33,15 +28,11 @@ class StackChunkError : public std::exception
3328
class StackChunk
3429
{
3530
public:
36-
StackChunk()
37-
{
38-
// Initialize with Python's minimum stack chunk size
39-
data_capacity = _PY_DATA_STACK_CHUNK_SIZE;
40-
data.resize(data_capacity);
41-
}
31+
StackChunk() {}
4232

4333
inline void update(_PyStackChunk* chunk_addr);
4434
inline void* resolve(void* frame_addr);
35+
inline bool is_valid() const;
4536

4637
private:
4738
void* origin = NULL;
@@ -58,12 +49,19 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
5849
if (copy_type(chunk_addr, chunk))
5950
throw StackChunkError();
6051

52+
// Validate chunk size before proceeding
53+
if (chunk.size == 0)
54+
{
55+
// Maybe the chunk is being created or freed
56+
return;
57+
}
58+
6159
origin = chunk_addr;
60+
6261
// if data_size is not enough, reallocate
63-
if (chunk.size > data_capacity || data.data() == nullptr)
62+
if (chunk.size > data_capacity)
6463
{
65-
data_capacity =
66-
std::max(chunk.size, data_capacity); // Use max to maintain minimum capacity
64+
data_capacity = std::max(chunk.size, data_capacity);
6765
data.resize(data_capacity);
6866
}
6967

@@ -89,13 +87,14 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
8987
// ----------------------------------------------------------------------------
9088
void* StackChunk::resolve(void* address)
9189
{
92-
_PyStackChunk* chunk = (_PyStackChunk*)data.data();
93-
94-
if (chunk == nullptr)
90+
// If data is not properly initialized, simply return the address
91+
if (!is_valid())
9592
{
9693
return address;
9794
}
9895

96+
_PyStackChunk* chunk = (_PyStackChunk*)data.data();
97+
9998
// Check if this chunk contains the address
10099
if (address >= origin && address < (char*)origin + chunk->size)
101100
return (char*)chunk + ((char*)address - (char*)origin);
@@ -106,6 +105,15 @@ void* StackChunk::resolve(void* address)
106105
return address;
107106
}
108107

108+
// ----------------------------------------------------------------------------
109+
bool StackChunk::is_valid() const
110+
{
111+
return data_capacity > 0 &&
112+
data.size() > 0 &&
113+
data.data() != nullptr &&
114+
origin != nullptr;
115+
}
116+
109117
// ----------------------------------------------------------------------------
110118

111119
inline std::unique_ptr<StackChunk> stack_chunk = nullptr;

0 commit comments

Comments
 (0)