Skip to content

Commit 48e22da

Browse files
authored
Merge pull request #657 from casperisfine/fbuffer-stack
Allocate the FBuffer struct on the stack
2 parents 5b4b24e + 72110f7 commit 48e22da

File tree

6 files changed

+39
-54
lines changed

6 files changed

+39
-54
lines changed

ext/json/ext/fbuffer/fbuffer.h

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@ typedef struct FBufferStruct {
1313

1414
#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
1515

16-
#define FBUFFER_PTR(fb) (fb->ptr)
17-
#define FBUFFER_LEN(fb) (fb->len)
18-
#define FBUFFER_CAPA(fb) (fb->capa)
16+
#define FBUFFER_PTR(fb) ((fb)->ptr)
17+
#define FBUFFER_LEN(fb) ((fb)->len)
18+
#define FBUFFER_CAPA(fb) ((fb)->capa)
1919
#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
2020

21-
static FBuffer *fbuffer_alloc(unsigned long initial_length);
2221
static void fbuffer_free(FBuffer *fb);
2322
#ifndef JSON_GENERATOR
2423
static void fbuffer_clear(FBuffer *fb);
@@ -36,20 +35,14 @@ static VALUE fbuffer_to_s(FBuffer *fb);
3635
#define RB_UNLIKELY(expr) expr
3736
#endif
3837

39-
static FBuffer *fbuffer_alloc(unsigned long initial_length)
38+
static void fbuffer_init(FBuffer *fb, unsigned long initial_length)
4039
{
41-
FBuffer *fb;
42-
if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
43-
fb = ALLOC(FBuffer);
44-
memset((void *) fb, 0, sizeof(FBuffer));
45-
fb->initial_length = initial_length;
46-
return fb;
40+
fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
4741
}
4842

4943
static void fbuffer_free(FBuffer *fb)
5044
{
5145
if (fb->ptr) ruby_xfree(fb->ptr);
52-
ruby_xfree(fb);
5346
}
5447

5548
#ifndef JSON_GENERATOR

ext/json/ext/generator/generator.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -911,15 +911,6 @@ static void generate_json(FBuffer *buffer, VALUE Vstate, JSON_Generator_State *s
911911
}
912912
}
913913

914-
static FBuffer *cState_prepare_buffer(VALUE self)
915-
{
916-
FBuffer *buffer;
917-
GET_STATE(self);
918-
buffer = fbuffer_alloc(state->buffer_initial_length);
919-
920-
return buffer;
921-
}
922-
923914
struct generate_json_data {
924915
FBuffer *buffer;
925916
VALUE vstate;
@@ -948,18 +939,20 @@ static VALUE generate_json_rescue(VALUE d, VALUE exc)
948939

949940
static VALUE cState_partial_generate(VALUE self, VALUE obj)
950941
{
951-
FBuffer *buffer = cState_prepare_buffer(self);
952942
GET_STATE(self);
953943

944+
FBuffer buffer = {0};
945+
fbuffer_init(&buffer, state->buffer_initial_length);
946+
954947
struct generate_json_data data = {
955-
.buffer = buffer,
948+
.buffer = &buffer,
956949
.vstate = self,
957950
.state = state,
958951
.obj = obj
959952
};
960953
rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data);
961954

962-
return fbuffer_to_s(buffer);
955+
return fbuffer_to_s(&buffer);
963956
}
964957

965958
/*

ext/json/ext/generator/generator.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,16 @@ typedef struct JSON_Generator_StateStruct {
5555
GET_STATE_TO(self, state)
5656

5757
#define GENERATE_JSON(type) \
58-
FBuffer *buffer; \
5958
VALUE Vstate; \
6059
JSON_Generator_State *state; \
6160
\
6261
rb_scan_args(argc, argv, "01", &Vstate); \
6362
Vstate = cState_from_state_s(cState, Vstate); \
6463
TypedData_Get_Struct(Vstate, JSON_Generator_State, &JSON_Generator_State_type, state); \
65-
buffer = cState_prepare_buffer(Vstate); \
66-
generate_json_##type(buffer, Vstate, state, self); \
67-
return fbuffer_to_s(buffer)
64+
FBuffer buffer = {0}; \
65+
fbuffer_init(&buffer, state->buffer_initial_length); \
66+
generate_json_##type(&buffer, Vstate, state, self); \
67+
return fbuffer_to_s(&buffer)
6868

6969
static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self);
7070
static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self);
@@ -122,7 +122,6 @@ static VALUE cState_script_safe(VALUE self);
122122
static VALUE cState_script_safe_set(VALUE self, VALUE depth);
123123
static VALUE cState_strict(VALUE self);
124124
static VALUE cState_strict_set(VALUE self, VALUE strict);
125-
static FBuffer *cState_prepare_buffer(VALUE self);
126125

127126
static const rb_data_type_t JSON_Generator_State_type;
128127

ext/json/ext/parser/parser.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,10 @@ case 5:
972972

973973
if (cs >= JSON_integer_first_final) {
974974
long len = p - json->memo;
975-
fbuffer_clear(json->fbuffer);
976-
fbuffer_append(json->fbuffer, json->memo, len);
977-
fbuffer_append_char(json->fbuffer, '\0');
978-
*result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
975+
fbuffer_clear(&json->fbuffer);
976+
fbuffer_append(&json->fbuffer, json->memo, len);
977+
fbuffer_append_char(&json->fbuffer, '\0');
978+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
979979
return p + 1;
980980
} else {
981981
return NULL;
@@ -1167,15 +1167,15 @@ case 7:
11671167
}
11681168

11691169
long len = p - json->memo;
1170-
fbuffer_clear(json->fbuffer);
1171-
fbuffer_append(json->fbuffer, json->memo, len);
1172-
fbuffer_append_char(json->fbuffer, '\0');
1170+
fbuffer_clear(&json->fbuffer);
1171+
fbuffer_append(&json->fbuffer, json->memo, len);
1172+
fbuffer_append_char(&json->fbuffer, '\0');
11731173

11741174
if (method_id) {
1175-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
1175+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
11761176
*result = rb_funcallv(mod, method_id, 1, &text);
11771177
} else {
1178-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
1178+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
11791179
}
11801180

11811181
return p + 1;
@@ -2138,14 +2138,14 @@ static void JSON_mark(void *ptr)
21382138
static void JSON_free(void *ptr)
21392139
{
21402140
JSON_Parser *json = ptr;
2141-
fbuffer_free(json->fbuffer);
2141+
fbuffer_free(&json->fbuffer);
21422142
ruby_xfree(json);
21432143
}
21442144

21452145
static size_t JSON_memsize(const void *ptr)
21462146
{
21472147
const JSON_Parser *json = ptr;
2148-
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
2148+
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
21492149
}
21502150

21512151
static const rb_data_type_t JSON_Parser_type = {
@@ -2159,7 +2159,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
21592159
{
21602160
JSON_Parser *json;
21612161
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
2162-
json->fbuffer = fbuffer_alloc(0);
2162+
fbuffer_init(&json->fbuffer, 0);
21632163
return obj;
21642164
}
21652165

ext/json/ext/parser/parser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ typedef struct JSON_ParserStruct {
1919
VALUE array_class;
2020
VALUE decimal_class;
2121
VALUE match_string;
22-
FBuffer *fbuffer;
22+
FBuffer fbuffer;
2323
int max_nesting;
2424
char allow_nan;
2525
char parsing_name;

ext/json/ext/parser/parser.rl

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res
324324

325325
if (cs >= JSON_integer_first_final) {
326326
long len = p - json->memo;
327-
fbuffer_clear(json->fbuffer);
328-
fbuffer_append(json->fbuffer, json->memo, len);
329-
fbuffer_append_char(json->fbuffer, '\0');
330-
*result = rb_cstr2inum(FBUFFER_PTR(json->fbuffer), 10);
327+
fbuffer_clear(&json->fbuffer);
328+
fbuffer_append(&json->fbuffer, json->memo, len);
329+
fbuffer_append_char(&json->fbuffer, '\0');
330+
*result = rb_cstr2inum(FBUFFER_PTR(&json->fbuffer), 10);
331331
return p + 1;
332332
} else {
333333
return NULL;
@@ -388,15 +388,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
388388
}
389389

390390
long len = p - json->memo;
391-
fbuffer_clear(json->fbuffer);
392-
fbuffer_append(json->fbuffer, json->memo, len);
393-
fbuffer_append_char(json->fbuffer, '\0');
391+
fbuffer_clear(&json->fbuffer);
392+
fbuffer_append(&json->fbuffer, json->memo, len);
393+
fbuffer_append_char(&json->fbuffer, '\0');
394394

395395
if (method_id) {
396-
VALUE text = rb_str_new2(FBUFFER_PTR(json->fbuffer));
396+
VALUE text = rb_str_new2(FBUFFER_PTR(&json->fbuffer));
397397
*result = rb_funcallv(mod, method_id, 1, &text);
398398
} else {
399-
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(json->fbuffer), 1));
399+
*result = DBL2NUM(rb_cstr_to_dbl(FBUFFER_PTR(&json->fbuffer), 1));
400400
}
401401

402402
return p + 1;
@@ -898,14 +898,14 @@ static void JSON_mark(void *ptr)
898898
static void JSON_free(void *ptr)
899899
{
900900
JSON_Parser *json = ptr;
901-
fbuffer_free(json->fbuffer);
901+
fbuffer_free(&json->fbuffer);
902902
ruby_xfree(json);
903903
}
904904

905905
static size_t JSON_memsize(const void *ptr)
906906
{
907907
const JSON_Parser *json = ptr;
908-
return sizeof(*json) + FBUFFER_CAPA(json->fbuffer);
908+
return sizeof(*json) + FBUFFER_CAPA(&json->fbuffer);
909909
}
910910

911911
static const rb_data_type_t JSON_Parser_type = {
@@ -919,7 +919,7 @@ static VALUE cJSON_parser_s_allocate(VALUE klass)
919919
{
920920
JSON_Parser *json;
921921
VALUE obj = TypedData_Make_Struct(klass, JSON_Parser, &JSON_Parser_type, json);
922-
json->fbuffer = fbuffer_alloc(0);
922+
fbuffer_init(&json->fbuffer, 0);
923923
return obj;
924924
}
925925

0 commit comments

Comments
 (0)