Skip to content

Commit

Permalink
fix: Avoid systematic hashmap lookup in shouldCompileHotspot|Function
Browse files Browse the repository at this point in the history
Removed `@hot` lookup
  • Loading branch information
giann committed Jul 8, 2024
1 parent 33061c5 commit f524082
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 38 deletions.
3 changes: 3 additions & 0 deletions src/Ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ pub const Node = struct {
/// How many time it was visited at runtime (used to decide wether its a hotspot that needs to be compiled)
count: usize = 0,

/// Wether its blacklisted or already compiled
compilable: bool = true,

pub const Index = u32;

pub const Tag = enum(u8) {
Expand Down
9 changes: 6 additions & 3 deletions src/Parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4266,7 +4266,7 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind
}
},
.Object => {
const obj_def: obj.ObjObject.ObjectDef = callee_type_def.?.resolved_type.?.Object;
const obj_def = callee_type_def.?.resolved_type.?.Object;
const property_field = obj_def.fields.get(member_name);
var property_type = if (property_field) |field| field.type_def else null;

Expand All @@ -4286,12 +4286,15 @@ fn dot(self: *Self, can_assign: bool, callee: Ast.Node.Index) Error!Ast.Node.Ind
self.current_object.?.name.lexeme,
obj_def.name.string,
)) {
const placeholder: *obj.ObjTypeDef = try self.gc.type_registry.getTypeDef(
const placeholder = try self.gc.type_registry.getTypeDef(
.{
.optional = false,
.def_type = .Placeholder,
.resolved_type = .{
.Placeholder = obj.PlaceholderDef.init(self.gc.allocator, member_name_token),
.Placeholder = obj.PlaceholderDef.init(
self.gc.allocator,
member_name_token,
),
},
},
);
Expand Down
3 changes: 1 addition & 2 deletions src/lib/buffer.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export object Buffer {

|| Writes a string
|| @param bytes Bytes to write
|| @hot
fun write(str bytes) > void !> WriteWhileReadingError {
BufferWrite(this.buffer, bytes: bytes);
}
Expand Down Expand Up @@ -230,4 +229,4 @@ export object Buffer {

throw OutOfBoundError{};
}
}
}
81 changes: 50 additions & 31 deletions src/vm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub const Fiber = struct {

parent_fiber: ?*Fiber,

// Instruction(s) that triggered the fiber
/// Instruction(s) that triggered the fiber
instruction: u32,
extra_instruction: ?u32,

Expand All @@ -129,10 +129,10 @@ pub const Fiber = struct {
open_upvalues: ?*ObjUpValue,

status: Status = .Instanciated,
// true: we did `resolve fiber`, false: we did `resume fiber`
/// true: we did `resolve fiber`, false: we did `resume fiber`
resolved: bool = false,

// When within a try catch in a JIT compiled function
/// When within a try catch in a JIT compiled function
try_context: ?*TryCtx = null,

type_def: *ObjTypeDef,
Expand Down Expand Up @@ -4903,11 +4903,14 @@ pub const VM = struct {
}

fn bindMethod(self: *Self, method: ?*ObjClosure, native: ?*ObjNative) !void {
var bound: *ObjBoundMethod = try self.gc.allocateObject(ObjBoundMethod, .{
.receiver = self.peek(0),
.closure = method,
.native = native,
});
var bound: *ObjBoundMethod = try self.gc.allocateObject(
ObjBoundMethod,
.{
.receiver = self.peek(0),
.closure = method,
.native = native,
},
);

_ = self.pop(); // Pop instane
self.push(Value.fromObj(bound.toObj()));
Expand Down Expand Up @@ -5143,38 +5146,54 @@ pub const VM = struct {
else => {},
}

if (self.jit != null and
(self.jit.?.compiled_nodes.get(closure.function.node) != null or
self.jit.?.blacklisted_nodes.get(closure.function.node) != null))
{
return false;
}
// zig fmt: off
if (
// Marked as compilable
self.current_ast.nodes.items(.compilable)[closure.function.node] and
self.jit != null and
(
// Always on
BuildOptions.jit_always_on or
// Threshold reached
(closure.function.call_count > 10 and (@as(f128, @floatFromInt(closure.function.call_count)) / @as(f128, @floatFromInt(self.jit.?.call_count))) > BuildOptions.jit_prof_threshold)
)
) {
// Not blacklisted or already compiled
self.current_ast.nodes.items(.compilable)[closure.function.node] =
self.jit.?.compiled_nodes.get(closure.function.node) == null and
self.jit.?.blacklisted_nodes.get(closure.function.node) == null;

const user_hot = if (self.current_ast.nodes.items(.components)[closure.function.node].Function.docblock) |docblock|
std.mem.indexOf(u8, self.current_ast.tokens.items(.lexeme)[docblock], "@hot") != null
else
false;
return self.current_ast.nodes.items(.compilable)[closure.function.node];
}
// zig fmt: on

return BuildOptions.jit_always_on or
user_hot or
(closure.function.call_count > 10 and
(@as(f128, @floatFromInt(closure.function.call_count)) / @as(f128, @floatFromInt(self.jit.?.call_count))) > BuildOptions.jit_prof_threshold);
return false;
}

fn shouldCompileHotspot(self: *Self, node: Ast.Node.Index) bool {
const count = self.current_ast.nodes.items(.count)[node];

// JIT is on?
return self.jit != null and
// zig fmt: off
if (
// Marked as compilable
self.current_ast.nodes.items(.compilable)[node] and
self.jit != null and
// JIT compile all the thing?
(BuildOptions.jit_always_on or BuildOptions.jit_hotspot_always_on or
// Threshold reached
(count > 10 and
(@as(f128, @floatFromInt(count)) / @as(f128, @floatFromInt(self.hotspots_count))) > BuildOptions.jit_prof_threshold)) and
// It qualifies has a hotspot
self.current_ast.nodes.items(.tag)[node].isHotspot() and
(
// Always compile
BuildOptions.jit_always_on or BuildOptions.jit_hotspot_always_on or
// Threshold reached
(count > 10 and (@as(f128, @floatFromInt(count)) / @as(f128, @floatFromInt(self.hotspots_count))) > BuildOptions.jit_prof_threshold)
)
) {
// It's not already done or blacklisted
(self.jit.?.compiled_nodes.get(node) == null and self.jit.?.blacklisted_nodes.get(node) == null);
self.current_ast.nodes.items(.compilable)[node] = (self.jit.?.compiled_nodes.get(node) == null and self.jit.?.blacklisted_nodes.get(node) == null);

return self.current_ast.nodes.items(.compilable)[node];
}
// zig fmt: on

return false;
}

fn patchHotspot(
Expand Down
3 changes: 1 addition & 2 deletions tests/bench/001-btree.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ fun itemCheck(Node tree) > int {
return 0;
}

|| @hot
fun btree(int N) > void {
int mindepth = 4;
int maxdepth = mindepth + 2;
Expand Down Expand Up @@ -57,4 +56,4 @@ fun main([str] args) > void !> any {
int N = if (args.len() > 0) std.parseInt(args[0]) ?? 3 else 3;

btree(N);
}
}

0 comments on commit f524082

Please sign in to comment.