Skip to content

Commit

Permalink
Quick and dirty stack allocation
Browse files Browse the repository at this point in the history
  • Loading branch information
byroot committed Oct 29, 2024
1 parent 5b4b24e commit b8db61b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
16 changes: 13 additions & 3 deletions ext/json/ext/fbuffer/fbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ typedef struct FBufferStruct {
char *ptr;
unsigned long len;
unsigned long capa;
char on_stack;
char spilled;
} FBuffer;

#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
Expand Down Expand Up @@ -43,13 +45,14 @@ static FBuffer *fbuffer_alloc(unsigned long initial_length)
fb = ALLOC(FBuffer);
memset((void *) fb, 0, sizeof(FBuffer));
fb->initial_length = initial_length;
fb->spilled = TRUE;
return fb;
}

static void fbuffer_free(FBuffer *fb)
{
if (fb->ptr) ruby_xfree(fb->ptr);
ruby_xfree(fb);
if (fb->ptr && fb->spilled) ruby_xfree(fb->ptr);
if (!fb->on_stack) ruby_xfree(fb);
}

#ifndef JSON_GENERATOR
Expand All @@ -72,7 +75,14 @@ static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
for (required = fb->capa; requested > required - fb->len; required <<= 1);

if (required > fb->capa) {
REALLOC_N(fb->ptr, char, required);
if (fb->spilled) {
REALLOC_N(fb->ptr, char, required);
} else {
const char *old_buffer = fb->ptr;
fb->ptr = ALLOC_N(char, required);
fb->spilled = true;
MEMCPY(fb->ptr, old_buffer, char, fb->len);
}
fb->capa = required;
}
}
Expand Down
17 changes: 16 additions & 1 deletion ext/json/ext/generator/generator.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,9 +946,24 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
return Qundef;
}

struct StackFBuffer {
FBuffer fbuffer;
char stack_buffer[FBUFFER_INITIAL_LENGTH_DEFAULT - sizeof(FBuffer)];
};

static VALUE cState_partial_generate(VALUE self, VALUE obj)
{
FBuffer *buffer = cState_prepare_buffer(self);
struct StackFBuffer stack_buffer;
FBuffer *buffer = &stack_buffer.fbuffer;
// FBuffer *buffer = alloca(FBUFFER_INITIAL_LENGTH_DEFAULT); // alloca cause crashes?
buffer->on_stack = TRUE;
buffer->spilled = FALSE;
buffer->initial_length = buffer->capa = (FBUFFER_INITIAL_LENGTH_DEFAULT - sizeof(FBuffer));
buffer->len = 0;
buffer->ptr = stack_buffer.stack_buffer;

// fprintf(stderr, "alloca(%ld)\n", FBUFFER_INITIAL_LENGTH_DEFAULT);
// FBuffer *buffer = cState_prepare_buffer(self);
GET_STATE(self);

struct generate_json_data data = {
Expand Down

0 comments on commit b8db61b

Please sign in to comment.