Skip to content

Commit 6554a6d

Browse files
committed
Reimplement NativeString optimizations
1 parent 7694d17 commit 6554a6d

1 file changed

Lines changed: 43 additions & 7 deletions

File tree

src/Utilities.h

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,18 +121,53 @@ struct Callback {
121121
class NativeString {
122122
char *data;
123123
size_t length;
124-
char utf8ValueMemory[sizeof(String::Utf8Value)];
125-
String::Utf8Value *utf8Value = nullptr;
124+
bool allocated = false;
126125
bool invalid = false;
126+
127+
// Static thread-local state shared by all NativeString instances on this thread
128+
inline static thread_local std::vector<char> pool = std::vector<char>(8 * 1024 * 1024);
129+
inline static thread_local size_t pool_offset = 0;
130+
inline static thread_local int ref_count = 0;
131+
132+
static char* alloc(size_t size) {
133+
// Ensure size is a multiple of 8
134+
size = (size + 7) & ~7;
135+
136+
// Fallback for allocations larger than the remaining pool space
137+
if (pool_offset + size > pool.size()) {
138+
// Mark for external cleanup if using instance-based logic
139+
// (Note: In a pure static alloc, you'd need a way to track this)
140+
return (char*)std::malloc(size);
141+
}
142+
143+
char* ptr = pool.data() + pool_offset;
144+
pool_offset += size;
145+
return ptr;
146+
}
147+
148+
// Provided for completeness, though the "pool" doesn't actually free individual slices
149+
static void free(char* ptr) {
150+
if (ptr < pool.data() || ptr >= pool.data() + pool.size()) {
151+
::free(ptr);
152+
}
153+
}
154+
127155
public:
128156
NativeString(Isolate *isolate, const Local<Value> &value) {
157+
if (ref_count == 0) {
158+
pool_offset = 0; // Reset the "stack" when entering the first scope
159+
}
160+
ref_count++;
161+
129162
if (value->IsUndefined()) {
130163
data = nullptr;
131164
length = 0;
132165
} else if (value->IsString()) {
133-
utf8Value = new (utf8ValueMemory) String::Utf8Value(isolate, value);
134-
data = (**utf8Value);
135-
length = utf8Value->length();
166+
Local<String> string = Local<String>::Cast(value);
167+
length = string->Utf8Length(isolate);
168+
data = alloc(length);
169+
allocated = true;
170+
string->WriteUtf8(isolate, data, length, nullptr, String::WriteOptions::NO_NULL_TERMINATION);
136171
} else if (value->IsTypedArray()) {
137172
Local<ArrayBufferView> arrayBufferView = Local<ArrayBufferView>::Cast(value);
138173
auto contents = arrayBufferView->Buffer()->GetBackingStore();
@@ -165,8 +200,9 @@ class NativeString {
165200
}
166201

167202
~NativeString() {
168-
if (utf8Value) {
169-
utf8Value->~Utf8Value();
203+
ref_count--;
204+
if (allocated) {
205+
free(data);
170206
}
171207
}
172208
};

0 commit comments

Comments
 (0)