Skip to content

Commit

Permalink
Use word instead of int. (#2266)
Browse files Browse the repository at this point in the history
Anything that relates to the size of an array, an offset to a pointer,
or the size of memory should be a word, not an int. This avoids 64+32
add operations.

Anything extracted from a Smi should be word because int will silently
overflow.

Many primitives changed from int (the smaller of int and Smi) to word
(which actually means the argument must be Smi).
  • Loading branch information
erikcorry committed May 1, 2024
1 parent 315e06a commit b214778
Show file tree
Hide file tree
Showing 76 changed files with 630 additions and 622 deletions.
34 changes: 17 additions & 17 deletions src/ar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ static const int FILE_MODE_SIZE = FILE_BYTE_SIZE_OFFSET - FILE_MODE_OFFSET;
static const int FILE_BYTE_SIZE_SIZE = FILE_ENDING_CHARS_OFFSET - FILE_BYTE_SIZE_OFFSET;
static const int FILE_ENDING_CHARS_SIZE = FILE_HEADER_SIZE - FILE_ENDING_CHARS_OFFSET;

static void write_string(uint8* buffer, const char* str, int length) {
static void write_string(uint8* buffer, const char* str, word length) {
// The string is truncated if it is too long.
for (int i = 0; i < length; i++) {
for (word i = 0; i < length; i++) {
char c = *str;
if (c == '\0') {
// Pad with spaces.
Expand All @@ -60,19 +60,19 @@ static void write_string(uint8* buffer, const char* str, int length) {
}
}

static void write_number(uint8* buffer, int number, int length, int base) {
static void write_number(uint8* buffer, int number, word length, int base) {
// The number is trimmed if it doesn't fit.
// For simplicity, we write the number right to left, and then shift the
// computed values.
int i = length - 1;
word i = length - 1;
for (; i >= 0; i--) {
buffer[i] = '0' + number % base;
number = number / base;
if (number == 0) break;
}
// 'i' is the last entry where we wrote a significant digit.
int nb_digits = length - i;
int offset = i;
word nb_digits = length - i;
word offset = i;
for (int j = 0; j < nb_digits; j++) {
buffer[j] = buffer[j + offset];
}
Expand All @@ -81,11 +81,11 @@ static void write_number(uint8* buffer, int number, int length, int base) {
}
}

static void write_decimal(uint8* buffer, int number, int length) {
static void write_decimal(uint8* buffer, int number, word length) {
write_number(buffer, number, length, 10);
}

static void write_octal(uint8* buffer, int number, int length) {
static void write_octal(uint8* buffer, int number, word length) {
write_number(buffer, number, length, 8);
}

Expand Down Expand Up @@ -121,7 +121,7 @@ static void write_ar_file_header(uint8* buffer, const File& file) {
FILE_ENDING_CHARS_SIZE);
}

static bool needs_padding(int content_size) {
static bool needs_padding(word content_size) {
return (content_size & 1) != 0;
}

Expand All @@ -134,12 +134,12 @@ int MemoryBuilder::open() {
}

int MemoryBuilder::add(File file) {
int needed_size = FILE_HEADER_SIZE + file.byte_size;
word needed_size = FILE_HEADER_SIZE + file.byte_size;
if (needs_padding(file.byte_size)) needed_size++;
int new_size = size_ + needed_size;
word new_size = size_ + needed_size;
buffer_ = unvoid_cast<uint8*>(realloc(buffer_, new_size));
if (buffer_ == null) return AR_OUT_OF_MEMORY;
int offset = size_;
word offset = size_;
write_ar_file_header(&buffer_[offset], file);
offset += FILE_HEADER_SIZE;
memcpy(&buffer_[offset], file.content(), file.byte_size);
Expand All @@ -154,7 +154,7 @@ int MemoryBuilder::add(File file) {
int FileBuilder::open(const char* archive_path) {
file_ = fopen(archive_path, "wb");
if (file_ == NULL) return AR_ERRNO_ERROR;
int written = fwrite(AR_HEADER, 1, AR_HEADER_SIZE, file_);
word written = fwrite(AR_HEADER, 1, AR_HEADER_SIZE, file_);
if (written != AR_HEADER_SIZE) return AR_ERRNO_ERROR;
return 0;
}
Expand All @@ -171,7 +171,7 @@ int FileBuilder::close() {
int FileBuilder::add(File file) {
uint8 buffer[FILE_HEADER_SIZE];
write_ar_file_header(buffer, file);
int written = fwrite(buffer, 1, FILE_HEADER_SIZE, file_);
word written = fwrite(buffer, 1, FILE_HEADER_SIZE, file_);
if (written != FILE_HEADER_SIZE) return AR_ERRNO_ERROR;
written = fwrite(file.content(), 1, file.byte_size, file_);
if (written != file.byte_size) return AR_ERRNO_ERROR;
Expand All @@ -196,8 +196,8 @@ static int parse_ar_file_header(const uint8* data, File* file) {

// We parse the size first, as parsing the name can't lead to errors, and we
// don't want to allocate memory if there is an error.
int byte_size = 0;
for (int i = 0; i < FILE_BYTE_SIZE_SIZE; i++) {
word byte_size = 0;
for (word i = 0; i < FILE_BYTE_SIZE_SIZE; i++) {
char c = data[FILE_BYTE_SIZE_OFFSET + i];
if ('0' <= c && c <= '9') {
byte_size = byte_size * 10 + c - '0';
Expand All @@ -213,7 +213,7 @@ static int parse_ar_file_header(const uint8* data, File* file) {
memcpy(name, &data[FILE_NAME_OFFSET], FILE_NAME_SIZE);
name[FILE_NAME_SIZE] = '\0';
// Remove the padding.
for (int i = FILE_NAME_SIZE - 1; i >= 0; i--) {
for (word i = FILE_NAME_SIZE - 1; i >= 0; i--) {
if (name[i] == ' ') {
name[i] = '\0';
} else if (name[i] == '/') {
Expand Down
4 changes: 2 additions & 2 deletions src/blake2s.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class Blake2s : public SimpleResource {
child->length_ = length_;
}

static const int BLOCK_SIZE = 64;
static const int MAX_HASH_SIZE = 32;
static const word BLOCK_SIZE = 64;
static const word MAX_HASH_SIZE = 32;

private:
static const uint32_t BLOCK_MASK = BLOCK_SIZE - 1;
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/backend.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Program* Backend::emit(ir::Program* ir_program) {

DispatchTable dispatch_table = DispatchTable::build(ir_program);

dispatch_table.for_each_selector_offset([&](DispatchSelector selector, int offset) {
dispatch_table.for_each_selector_offset([&](DispatchSelector selector, word offset) {
source_mapper()->register_selector_offset(offset, selector.name().c_str());
});

Expand Down
4 changes: 2 additions & 2 deletions src/compiler/dispatch_table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,12 @@ class DispatchTableBuilder : public TraversingVisitor {
selectors_.insert(selector);
}

Map<DispatchSelector, int>& selector_offsets() { return selector_offsets_; }
Map<DispatchSelector, word>& selector_offsets() { return selector_offsets_; }
List<Method*> dispatch_table() { return dispatch_table_; }

private:
Set<DispatchSelector> selectors_;
Map<DispatchSelector, int> selector_offsets_;
Map<DispatchSelector, word> selector_offsets_;
List<Method*> dispatch_table_;

void handle_methods(List<Method*> methods);
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/dispatch_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ class DispatchTable {
}
int id_for(const ir::Class* klass) const { return klass->start_id(); }

void for_each_selector_offset(std::function<void (DispatchSelector, int)> callback) {
void for_each_selector_offset(std::function<void (DispatchSelector, word)> callback) {
selector_offsets_.for_each(callback);
}

private:
DispatchTable(List<ir::Method*> table,
const Map<DispatchSelector, int>& selector_offsets)
const Map<DispatchSelector, word>& selector_offsets)
: table_(table), selector_offsets_(selector_offsets) {}

List<ir::Method*> table_;
Map<DispatchSelector, int> selector_offsets_;
Map<DispatchSelector, word> selector_offsets_;
};

} // namespace toit::compiler
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/program_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void ProgramBuilder::push_lazy_initializer_id(int id) {
push(lazy_initializer);
}

int ProgramBuilder::create_method(int selector_offset,
int ProgramBuilder::create_method(word selector_offset,
bool is_field_accessor,
int arity,
List<uint8> bytecodes,
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/program_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ProgramBuilder {

// Removes the top 'len' elements and replaces them with an array containing those elements.
void create_class(int id, const char* name, int instance_size, bool is_runtime);
int create_method(int selector_offset, bool is_field_stub, int arity, List<uint8> codes, int max_height);
int create_method(word selector_offset, bool is_field_stub, int arity, List<uint8> codes, int max_height);
int create_lambda(int captured_count, int arity, List<uint8> codes, int max_height);
int create_block(int arity, List<uint8> codes, int max_height);
int absolute_bci_for(int method_id);
Expand Down
16 changes: 8 additions & 8 deletions src/compiler/propagation/type_propagator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ void TypePropagator::call_static(MethodTemplate* caller, TypeScope* scope, uint8
std::vector<ConcreteType> arguments;
stack->push_empty();

int offset = target.selector_offset();
word offset = target.selector_offset();
bool handle_as_static = (offset == -1);
if (offset >= 0) {
ASSERT(arity > 0);
Expand Down Expand Up @@ -475,7 +475,7 @@ void TypePropagator::call_static(MethodTemplate* caller, TypeScope* scope, uint8
stack->drop_arguments(target.arity());
}

void TypePropagator::call_virtual(MethodTemplate* caller, TypeScope* scope, uint8* site, int arity, int offset) {
void TypePropagator::call_virtual(MethodTemplate* caller, TypeScope* scope, uint8* site, int arity, word offset) {
TypeStack* stack = scope->top();
TypeSet receiver = stack->local(arity - 1);
if (site) add_input(site, stack, arity);
Expand Down Expand Up @@ -1082,26 +1082,26 @@ static TypeScope* process(TypeScope* scope, uint8* bcp, std::vector<Worklist*>&
OPCODE_END();

OPCODE_BEGIN_WITH_WIDE(INVOKE_VIRTUAL, arity);
int offset = Utils::read_unaligned_uint16(bcp + 2);
word offset = Utils::read_unaligned_uint16(bcp + 2);
propagator->call_virtual(method, scope, bcp, arity + 1, offset);
if (stack->top_is_empty()) return scope;
OPCODE_END();

OPCODE_BEGIN(INVOKE_VIRTUAL_GET);
int offset = Utils::read_unaligned_uint16(bcp + 1);
word offset = Utils::read_unaligned_uint16(bcp + 1);
propagator->call_virtual(method, scope, bcp, 1, offset);
if (stack->top_is_empty()) return scope;
OPCODE_END();

OPCODE_BEGIN(INVOKE_VIRTUAL_SET);
int offset = Utils::read_unaligned_uint16(bcp + 1);
word offset = Utils::read_unaligned_uint16(bcp + 1);
propagator->call_virtual(method, scope, bcp, 2, offset);
if (stack->top_is_empty()) return scope;
OPCODE_END();

#define INVOKE_VIRTUAL_BINARY(opcode) \
OPCODE_BEGIN(opcode); \
int offset = program->invoke_bytecode_offset(opcode); \
word offset = program->invoke_bytecode_offset(opcode); \
propagator->call_virtual(method, scope, bcp, 2, offset); \
if (stack->top_is_empty()) return scope; \
OPCODE_END();
Expand Down Expand Up @@ -1129,13 +1129,13 @@ static TypeScope* process(TypeScope* scope, uint8* bcp, std::vector<Worklist*>&
#undef INVOKE_VIRTUAL_BINARY

OPCODE_BEGIN(INVOKE_AT_PUT);
int offset = program->invoke_bytecode_offset(INVOKE_AT_PUT);
word offset = program->invoke_bytecode_offset(INVOKE_AT_PUT);
propagator->call_virtual(method, scope, bcp, 3, offset);
if (stack->top_is_empty()) return scope;
OPCODE_END();

OPCODE_BEGIN(INVOKE_SIZE);
int offset = program->invoke_bytecode_offset(INVOKE_SIZE);
word offset = program->invoke_bytecode_offset(INVOKE_SIZE);
propagator->call_virtual(method, scope, bcp, 1, offset);
if (stack->top_is_empty()) return scope;
OPCODE_END();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/propagation/type_propagator.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class TypePropagator {
void propagate(TypeDatabase* types);

void call_static(MethodTemplate* caller, TypeScope* scope, uint8* site, Method target);
void call_virtual(MethodTemplate* caller, TypeScope* scope, uint8* site, int arity, int offset);
void call_virtual(MethodTemplate* caller, TypeScope* scope, uint8* site, int arity, word offset);
void call_block(TypeScope* scope, uint8* site, int arity);

void load_block(MethodTemplate* loader, TypeScope* scope, Method method, bool linked, std::vector<Worklist*>& worklists);
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/propagation/type_set.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ int TypeSet::remove_typecheck_interface(Program* program, int index, bool is_nul
int words_per_type = TypeSet::words_per_type(program);
bool contains_null_before = contains_null(program);
int size_before = size(words_per_type);
int selector_offset = program->interface_check_offsets[index];
word selector_offset = program->interface_check_offsets[index];
Iterator it(*this, words_per_type);
while (it.has_next()) {
unsigned id = it.next();
int entry_index = id + selector_offset;
word entry_index = id + selector_offset;
int entry_id = program->dispatch_table[entry_index];
if (entry_id != -1) {
Method target(program->bytecodes, entry_id);
Expand Down
18 changes: 12 additions & 6 deletions src/compiler/tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -639,17 +639,21 @@ static void shake(Program* program,
}
}
if (Flags::report_tree_shaking) {
int remaining_classes_length = remaining_classes.length();
int program_classes_length = program->classes().length();
printf("Kept %d out of %d classes\n",
remaining_classes.length(),
program->classes().length());
remaining_classes_length,
program_classes_length);
}
program->replace_classes(remaining_classes.build());

auto remaining_methods = shake_methods(program->methods(), grown_methods);
if (Flags::report_tree_shaking) {
int remaining_methods_length = remaining_methods.length();
int program_methods_length = program->methods().length();
printf("Kept %d out of %d global functions\n",
remaining_methods.length(),
program->methods().length());
remaining_methods_length,
program_methods_length);
}
program->replace_methods(remaining_methods);

Expand All @@ -660,9 +664,11 @@ static void shake(Program* program,
}
}
if (Flags::report_tree_shaking) {
int remaining_globals_length = remaining_globals.length();
int program_globals_length = program->globals().length();
printf("Kept %d out of %d globals\n",
remaining_globals.length(),
program->globals().length());
remaining_globals_length,
program_globals_length);
}
program->replace_globals(remaining_globals.build());

Expand Down
20 changes: 10 additions & 10 deletions src/encoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ class EncodeVisitor : public Visitor {
public:
explicit EncodeVisitor(ProgramOrientedEncoder* encoder) : encoder_(encoder), level_(0) {};

void visit_byte_array(const uint8* bytes, int length) {
void visit_byte_array(const uint8* bytes, word length) {
encoder_->write_byte_array_header(length);
for (int i = 0; i < length; i++) {
for (word i = 0; i < length; i++) {
encoder_->write_byte(bytes[i]);
}
}
Expand All @@ -39,9 +39,9 @@ class EncodeVisitor : public Visitor {
EncodeVisitor(ProgramOrientedEncoder* encoder, int level) : encoder_(encoder), level_(level) {};

// Restrictions when encoding collections.
const int MAX_NOF_STRING_ELEMENTS = 255;
const int MAX_NOF_BYTEARRAY_ELEMENTS = 40;
const int MAX_NOF_ARRAY_ELEMENTS = 10;
const word MAX_NOF_STRING_ELEMENTS = 255;
const word MAX_NOF_BYTEARRAY_ELEMENTS = 40;
const word MAX_NOF_ARRAY_ELEMENTS = 10;

void visit_smi(Smi* smi) {
encoder_->write_int(Smi::value(smi));
Expand Down Expand Up @@ -76,7 +76,7 @@ class EncodeVisitor : public Visitor {
encoder_->write_int(array->length());
encoder_->write_byte('[');
encoder_->write_byte('#');
const int limit = Utils::min(array->length(), MAX_NOF_ARRAY_ELEMENTS);
const word limit = Utils::min(array->length(), MAX_NOF_ARRAY_ELEMENTS);
encoder_->write_int(limit);
EncodeVisitor sub(encoder_, level_ + 1);
for (int i = 0; i < limit; i++) {
Expand All @@ -99,12 +99,12 @@ class EncodeVisitor : public Visitor {

void visit_stack(Stack* stack);

void visit_list(Instance* instance, Array* backing_array, int size) {
void visit_list(Instance* instance, Array* backing_array, word size) {
encoder_->write_header(2, 'L');
encoder_->write_int(size);
encoder_->write_byte('[');
encoder_->write_byte('#');
const int limit = Utils::min(size, MAX_NOF_ARRAY_ELEMENTS);
const word limit = Utils::min(size, MAX_NOF_ARRAY_ELEMENTS);
encoder_->write_int(limit);
EncodeVisitor sub(encoder_, level_ + 1);
for (int i = 0; i < limit; i++) {
Expand Down Expand Up @@ -283,7 +283,7 @@ void Encoder::write_byte(uint8 c) {
buffer_->put_byte(c);
}

void Encoder::write_header(int size, uint8 tag) {
void Encoder::write_header(word size, uint8 tag) {
write_byte('[');
write_byte('#');
write_int32(size + 1);
Expand Down Expand Up @@ -329,7 +329,7 @@ void Encoder::write_double(double value) {
buffer_->put_int64(raw);
}

void Encoder::write_byte_array_header(int length) {
void Encoder::write_byte_array_header(word length) {
write_byte('[');
write_byte('$');
write_byte('U');
Expand Down

0 comments on commit b214778

Please sign in to comment.