Skip to content
Merged
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
26 changes: 25 additions & 1 deletion bin/benchmark-parse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,37 @@
require "benchmark/ips"
require "csv"

require "optparse"

label = nil #: String?

OptionParser.new do |opts|
opts.banner = "Usage: benchmark-parse.rb [options] [file|directory]..."

opts.on("--label=LABEL", "Set the benchmark label") do |v|
label = v
end
end.parse!(ARGV)

file_names = []
files = {}
ARGV.each do |file|
path = Pathname(file)
if path.directory?
Pathname.glob(path.join("**", "*.rbs")).each do |p|
file_names << p.to_s
end
else
file_names << path.to_s
end
end

file_names.uniq.each do |file|
content = File.read(file)
files[file] = RBS::Buffer.new(content: content, name: Pathname(file))
end

puts "Benchmarking parsing #{files.size} files..."
puts "Benchmarking RBS(#{RBS::VERSION} in #{Bundler.default_gemfile.basename}#{label ? " (#{label})" : ""}) parsing with #{files.size} files..."

result = Benchmark.ips do |x|
x.report("parsing") do
Expand Down
6 changes: 5 additions & 1 deletion ext/rbs_extension/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
'-Wc++-compat',
]

append_cflags ['-O0', '-pg'] if ENV['DEBUG']
if ENV['DEBUG']
append_cflags ['-O0', '-pg']
else
append_cflags ['-DNDEBUG']
end
if ENV["TEST_NO_C23"]
puts "Adding -Wc2x-extensions to CFLAGS"
$CFLAGS << " -Werror -Wc2x-extensions"
Expand Down
2 changes: 1 addition & 1 deletion ext/rbs_extension/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* ```
* */
static NORETURN(void) raise_error(rbs_error_t *error, VALUE buffer) {
rbs_assert(error != NULL, "raise_error() called with NULL error");
RBS_ASSERT(error != NULL, "raise_error() called with NULL error");

if (!error->syntax_error) {
rb_raise(rb_eRuntimeError, "Unexpected error");
Expand Down
9 changes: 9 additions & 0 deletions include/rbs/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,13 @@
#define NODISCARD __attribute__((warn_unused_result))
#endif

/**
* Mark a function or variable as potentially unused to suppress compiler warnings.
*/
#if defined(__GNUC__) || defined(__clang__)
#define RBS_ATTRIBUTE_UNUSED __attribute__((unused))
#else
#define RBS_ATTRIBUTE_UNUSED
#endif

#endif
13 changes: 12 additions & 1 deletion include/rbs/util/rbs_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
#include "rbs/defines.h"
#include <stdbool.h>

void rbs_assert(bool condition, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(2, 3);
/**
* RBS_ASSERT macro that calls rbs_assert in debug builds and is removed in release builds.
* In debug mode, it forwards all arguments to the rbs_assert function.
* In release mode, it expands to nothing.
*/
#ifdef NDEBUG
#define RBS_ASSERT(condition, ...) ((void) 0)
#else
#define RBS_ASSERT(condition, ...) rbs_assert_impl(condition, __VA_ARGS__)
#endif

void rbs_assert_impl(bool condition, const char *fmt, ...) RBS_ATTRIBUTE_FORMAT(2, 3);

#endif
2 changes: 2 additions & 0 deletions include/rbs/util/rbs_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef RBS_RBS_ENCODING_H
#define RBS_RBS_ENCODING_H

#include "rbs/defines.h"

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
Expand Down
2 changes: 1 addition & 1 deletion src/lexstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ bool rbs_next_char(rbs_lexer_t *lexer, unsigned int *codepoint, size_t *byte_len
}

void rbs_skip(rbs_lexer_t *lexer) {
rbs_assert(lexer->current_character_bytes > 0, "rbs_skip called with current_character_bytes == 0");
RBS_ASSERT(lexer->current_character_bytes > 0, "rbs_skip called with current_character_bytes == 0");

if (RBS_UNLIKELY(lexer->current_code_point == '\0')) {
return;
Expand Down
6 changes: 3 additions & 3 deletions src/location.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#define RBS_LOC_CHILDREN_SIZE(cap) (sizeof(rbs_loc_children) + sizeof(rbs_loc_entry) * ((cap) - 1))

void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, size_t capacity) {
rbs_assert(capacity <= sizeof(rbs_loc_entry_bitmap) * 8, "Capacity %zu is too large. Max is %zu", capacity, sizeof(rbs_loc_entry_bitmap) * 8);
RBS_ASSERT(capacity <= sizeof(rbs_loc_entry_bitmap) * 8, "Capacity %zu is too large. Max is %zu", capacity, sizeof(rbs_loc_entry_bitmap) * 8);

loc->children = rbs_allocator_malloc_impl(allocator, RBS_LOC_CHILDREN_SIZE(capacity), rbs_alignof(rbs_loc_children));

Expand All @@ -16,8 +16,8 @@ void rbs_loc_alloc_children(rbs_allocator_t *allocator, rbs_location_t *loc, siz
}

void rbs_loc_add_optional_child(rbs_location_t *loc, rbs_constant_id_t name, rbs_range_t r) {
rbs_assert(loc->children != NULL, "All children should have been pre-allocated with rbs_loc_alloc_children()");
rbs_assert((loc->children->len + 1 <= loc->children->cap), "Not enough space was pre-allocated for the children. Children: %hu, Capacity: %hu", loc->children->len, loc->children->cap);
RBS_ASSERT(loc->children != NULL, "All children should have been pre-allocated with rbs_loc_alloc_children()");
RBS_ASSERT((loc->children->len + 1 <= loc->children->cap), "Not enough space was pre-allocated for the children. Children: %hu, Capacity: %hu", loc->children->len, loc->children->cap);

unsigned short i = loc->children->len++;
loc->children->entries[i].name = name;
Expand Down
2 changes: 1 addition & 1 deletion src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ error_handling: {
ids = "class/module/constant name";
}

rbs_assert(ids != NULL, "Unknown kind of type: %i", kind);
RBS_ASSERT(ids != NULL, "Unknown kind of type: %i", kind);

rbs_parser_set_error(parser, parser->current_token, true, "expected one of %s", ids);
return false;
Expand Down
4 changes: 2 additions & 2 deletions src/util/rbs_allocator.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static rbs_allocator_page_t *rbs_allocator_page_new(size_t payload_size) {
return page;
}

rbs_allocator_t *rbs_allocator_init() {
rbs_allocator_t *rbs_allocator_init(void) {
rbs_allocator_t *allocator = malloc(sizeof(rbs_allocator_t));

const size_t system_page_size = get_system_page_size();
Expand Down Expand Up @@ -98,7 +98,7 @@ void *rbs_allocator_realloc_impl(rbs_allocator_t *allocator, void *ptr, size_t o

// Allocates `size` bytes from `allocator`, aligned to an `alignment`-byte boundary.
void *rbs_allocator_malloc_impl(rbs_allocator_t *allocator, size_t size, size_t alignment) {
rbs_assert(size % alignment == 0, "size must be a multiple of the alignment. size: %zu, alignment: %zu", size, alignment);
RBS_ASSERT(size % alignment == 0, "size must be a multiple of the alignment. size: %zu, alignment: %zu", size, alignment);

if (allocator->default_page_payload_size < size) { // Big allocation, give it its own page.
rbs_allocator_page_t *new_page = rbs_allocator_page_new(size);
Expand Down
4 changes: 3 additions & 1 deletion src/util/rbs_assert.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include <stdlib.h>
#include <stdbool.h>

void rbs_assert(bool condition, const char *fmt, ...) {
void rbs_assert_impl(bool condition, const char *fmt, ...) {
printf("RBS_ASSERT called\n");

if (condition) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/util/rbs_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
if (next_length > buffer->capacity) {
size_t old_capacity = buffer->capacity;

rbs_assert(old_capacity != 0, "Precondition: capacity must be at least 1. Got %zu", old_capacity);
RBS_ASSERT(old_capacity != 0, "Precondition: capacity must be at least 1. Got %zu", old_capacity);

size_t new_capacity = buffer->capacity * 2;

Expand All @@ -34,7 +34,7 @@ void rbs_buffer_append_string(rbs_allocator_t *allocator, rbs_buffer_t *buffer,
}

char *new_value = rbs_allocator_realloc(allocator, buffer->value, old_capacity, new_capacity, char);
rbs_assert(new_value != NULL, "Failed to append to buffer. Old capacity: %zu, new capacity: %zu", old_capacity, new_capacity);
RBS_ASSERT(new_value != NULL, "Failed to append to buffer. Old capacity: %zu, new capacity: %zu", old_capacity, new_capacity);

buffer->value = new_value;
buffer->capacity = new_capacity;
Expand Down
12 changes: 6 additions & 6 deletions src/util/rbs_constant_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ next_power_of_two(uint32_t v) {
return v;
}

static bool is_power_of_two(uint32_t size) {
RBS_ATTRIBUTE_UNUSED static bool is_power_of_two(uint32_t size) {
return (size & (size - 1)) == 0;
}

Expand All @@ -46,7 +46,7 @@ static bool is_power_of_two(uint32_t size) {
*/
static inline bool
rbs_constant_pool_resize(rbs_constant_pool_t *pool) {
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
RBS_ASSERT(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);

uint32_t next_capacity = pool->capacity * 2;
if (next_capacity < pool->capacity) return false;
Expand Down Expand Up @@ -123,7 +123,7 @@ bool rbs_constant_pool_init(rbs_constant_pool_t *pool, uint32_t capacity) {
*/
rbs_constant_t *
rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_id_t constant_id) {
rbs_assert(constant_id != RBS_CONSTANT_ID_UNSET && constant_id <= pool->size, "constant_id is not valid. Got %i, pool->size: %i", constant_id, pool->size);
RBS_ASSERT(constant_id != RBS_CONSTANT_ID_UNSET && constant_id <= pool->size, "constant_id is not valid. Got %i, pool->size: %i", constant_id, pool->size);
return &pool->constants[constant_id - 1];
}

Expand All @@ -133,7 +133,7 @@ rbs_constant_pool_id_to_constant(const rbs_constant_pool_t *pool, rbs_constant_i
*/
rbs_constant_id_t
rbs_constant_pool_find(const rbs_constant_pool_t *pool, const uint8_t *start, size_t length) {
rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
RBS_ASSERT(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
const uint32_t mask = pool->capacity - 1;

uint32_t hash = rbs_constant_pool_hash(start, length);
Expand Down Expand Up @@ -161,7 +161,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
if (!rbs_constant_pool_resize(pool)) return RBS_CONSTANT_ID_UNSET;
}

rbs_assert(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
RBS_ASSERT(is_power_of_two(pool->capacity), "pool->capacity is not a power of two. Got %i", pool->capacity);
const uint32_t mask = pool->capacity - 1;

uint32_t hash = rbs_constant_pool_hash(start, length);
Expand Down Expand Up @@ -202,7 +202,7 @@ rbs_constant_pool_insert(rbs_constant_pool_t *pool, const uint8_t *start, size_t
// IDs are allocated starting at 1, since the value 0 denotes a non-existent
// constant.
uint32_t id = ++pool->size;
rbs_assert(pool->size < ((uint32_t) (1 << 30)), "pool->size is too large. Got %i", pool->size);
RBS_ASSERT(pool->size < ((uint32_t) (1 << 30)), "pool->size is too large. Got %i", pool->size);

*bucket = (rbs_constant_pool_bucket_t) {
.id = (unsigned int) (id & 0x3fffffff),
Expand Down
10 changes: 2 additions & 8 deletions src/util/rbs_encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@

#include <ctype.h>

#if defined(__GNUC__)
#define RBS_ATTRIBUTE_UNUSED __attribute__((unused))
#else
#define RBS_ATTRIBUTE_UNUSED
#endif

typedef uint32_t rbs_unicode_codepoint_t;

#define UNICODE_ALPHA_CODEPOINTS_LENGTH 1450
Expand Down Expand Up @@ -5001,7 +4995,7 @@ static const uint8_t rbs_utf_8_dfa[] = {
*/
static rbs_unicode_codepoint_t
rbs_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
rbs_assert(n >= 0, "[rbs_unicode_codepoint_t] n must be greater than or equal to 0. Got %ti", n);
RBS_ASSERT(n >= 0, "[rbs_unicode_codepoint_t] n must be greater than or equal to 0. Got %ti", n);

size_t maximum = (n > 4) ? 4 : ((size_t) n);
uint32_t codepoint;
Expand Down Expand Up @@ -5031,7 +5025,7 @@ rbs_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) {
*/
size_t
rbs_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) {
rbs_assert(n >= 0, "[rbs_encoding_utf_8_char_width] n must be greater than or equal to 0. Got %ti", n);
RBS_ASSERT(n >= 0, "[rbs_encoding_utf_8_char_width] n must be greater than or equal to 0. Got %ti", n);

size_t maximum = (n > 4) ? 4 : ((size_t) n);
uint32_t state = 0;
Expand Down