Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Makefile
# rspec failure tracking
.rspec_status
yajl/
.vscode/
30 changes: 0 additions & 30 deletions .vscode/c_cpp_properties.json

This file was deleted.

2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pry_version, pry_byebug_version = if RUBY_VERSION < "2.7"
gem "pry", pry_version
gem "pry-byebug", pry_byebug_version

# spec.add_development_dependency 'bump'

# benchmarks
if RUBY_VERSION >= "2.7"
gem "benchmark", "~> 0.4.1"
Expand Down
33 changes: 20 additions & 13 deletions ext/json_scanner/json_scanner.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ void scan_ctx_debug(scan_ctx *ctx)
fprintf(stderr, "}\n\n\n");
}

// FIXME: This will cause memory leak if ruby_xmalloc raises
// path_ary must be RB_GC_GUARD-ed by the caller
static VALUE scan_ctx_init(scan_ctx *ctx, VALUE path_ary, VALUE string_keys)
{
Expand Down Expand Up @@ -290,15 +289,27 @@ static VALUE scan_ctx_init(scan_ctx *ctx, VALUE path_ary, VALUE string_keys)

ctx->max_path_len = 0;

paths = ruby_xmalloc(sizeof(paths_t) * path_ary_len);
size_t total_size = sizeof(paths_t) * path_ary_len;
for (int i = 0; i < path_ary_len; i++)
{
int path_len = rb_long2int(rb_array_len(rb_ary_entry(path_ary, i)));
if (path_len > ctx->max_path_len)
ctx->max_path_len = path_len;
total_size += sizeof(path_matcher_elem_t) * path_len;
}
total_size += sizeof(size_t) * (ctx->max_path_len + 1);
total_size += sizeof(path_elem_t) * ctx->max_path_len;
void * arena = ruby_xmalloc(total_size);

paths = arena;
arena += sizeof(paths_t) * path_ary_len;
for (int i = 0; i < path_ary_len; i++)
{
int path_len;
VALUE path = rb_ary_entry(path_ary, i);
path_len = rb_long2int(rb_array_len(path));
if (path_len > ctx->max_path_len)
ctx->max_path_len = path_len;
paths[i].elems = ruby_xmalloc2(sizeof(path_matcher_elem_t), path_len);
paths[i].elems = arena;
arena += sizeof(path_matcher_elem_t) * path_len;
for (int j = 0; j < path_len; j++)
{
VALUE entry = rb_ary_entry(path, j);
Expand Down Expand Up @@ -363,9 +374,11 @@ static VALUE scan_ctx_init(scan_ctx *ctx, VALUE path_ary, VALUE string_keys)

ctx->paths = paths;
ctx->paths_len = path_ary_len;
ctx->current_path = ruby_xmalloc2(sizeof(path_elem_t), ctx->max_path_len);
ctx->current_path = arena;
arena += sizeof(path_elem_t) * ctx->max_path_len;

ctx->starts = ruby_xmalloc2(sizeof(size_t), ctx->max_path_len + 1);
ctx->starts = arena;
arena += sizeof(size_t) * ctx->max_path_len + 1;
return Qundef; // no error
}

Expand All @@ -388,14 +401,8 @@ static void scan_ctx_free(scan_ctx *ctx)
// fprintf(stderr, "scan_ctx_free\n");
if (!ctx)
return;
ruby_xfree(ctx->starts);
ruby_xfree(ctx->current_path);
if (!ctx->paths)
return;
for (int i = 0; i < ctx->paths_len; i++)
{
ruby_xfree(ctx->paths[i].elems);
}
ruby_xfree(ctx->paths);
}

Expand Down