@@ -121,18 +121,53 @@ struct Callback {
121121class 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+
127155public:
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