authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-11 22:35:12-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-11 22:35:12-04:00
log24d5ec078355d68e3f1002220fd284b1ff02a465
tree9523d44e581873a65287cb334def05aec9301277
parent911b1a0428d106923a13aa28933957a88bb1bfb5
signaturelock-open Commit is signed but in an unrecognized format.

fix async function frames not aligned enough


5 files changed, 40 insertions(+), 40 deletions(-)

src/analyze.cpp+5-5
......@@ -1500,7 +1500,7 @@ bool type_is_invalid(ZigType *type_entry) {
15001500
15011501
15021502ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1503 ZigType *field_types[], size_t field_count)
1503 ZigType *field_types[], size_t field_count, unsigned min_abi_align)
15041504{
15051505 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
15061506
......@@ -1512,7 +1512,7 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
15121512 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
15131513 struct_type->data.structure.fields_by_name.init(field_count);
15141514
1515 size_t abi_align = 0;
1515 size_t abi_align = min_abi_align;
15161516 for (size_t i = 0; i < field_count; i += 1) {
15171517 TypeStructField *field = &struct_type->data.structure.fields[i];
15181518 field->name = buf_create_from_str(field_names[i]);
......@@ -5334,7 +5334,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
53345334
53355335 assert(field_names.length == field_types.length);
53365336 frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),
5337 field_names.items, field_types.items, field_names.length);
5337 field_names.items, field_types.items, field_names.length, target_fn_align(g->zig_target));
53385338 frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
53395339 frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
53405340 frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;
......@@ -7764,8 +7764,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
77647764
77657765LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {
77667766 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
7767 assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(g->target_data_ref, type->llvm_type));
7768 assert(type->abi_align == 0 || type->abi_align == LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
7767 assert(type->abi_size == 0 || type->abi_size >= LLVMABISizeOfType(g->target_data_ref, type->llvm_type));
7768 assert(type->abi_align == 0 || type->abi_align >= LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
77697769 return type->llvm_type;
77707770}
77717771
src/analyze.hpp+1-1
......@@ -39,7 +39,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
3939ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
4040ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
4141ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
42 ZigType *field_types[], size_t field_count);
42 ZigType *field_types[], size_t field_count, unsigned min_abi_align);
4343ZigType *get_test_fn_type(CodeGen *g);
4444ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
4545bool handle_is_ptr(ZigType *type_entry);
src/target.cpp+4
......@@ -1759,3 +1759,7 @@ bool target_supports_libunwind(const ZigTarget *target) {
17591759 return true;
17601760}
17611761
1762
1763unsigned target_fn_align(const ZigTarget *target) {
1764 return 16;
1765}
src/target.hpp+2
......@@ -197,4 +197,6 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);
197197size_t target_libc_count(void);
198198void target_libc_enum(size_t index, ZigTarget *out_target);
199199
200unsigned target_fn_align(const ZigTarget *target);
201
200202#endif
std/event/channel.zig+28-34
......@@ -2,8 +2,6 @@ const std = @import("../std.zig");
22const builtin = @import("builtin");
33const assert = std.debug.assert;
44const testing = std.testing;
5const AtomicRmwOp = builtin.AtomicRmwOp;
6const AtomicOrder = builtin.AtomicOrder;
75const Loop = std.event.Loop;
86
97/// many producer, many consumer, thread-safe, runtime configurable buffer size
......@@ -98,18 +96,18 @@ pub fn Channel(comptime T: type) type {
9896
9997 // TODO test canceling a put()
10098 errdefer {
101 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
99 _ = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
102100 const need_dispatch = !self.putters.remove(&queue_node);
103101 self.loop.cancelOnNextTick(&my_tick_node);
104102 if (need_dispatch) {
105103 // oops we made the put_count incorrect for a period of time. fix by dispatching.
106 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
104 _ = @atomicRmw(usize, &self.put_count, .Add, 1, .SeqCst);
107105 self.dispatch();
108106 }
109107 }
110108 suspend {
111109 self.putters.put(&queue_node);
112 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
110 _ = @atomicRmw(usize, &self.put_count, .Add, 1, .SeqCst);
113111
114112 self.dispatch();
115113 }
......@@ -118,8 +116,7 @@ pub fn Channel(comptime T: type) type {
118116 /// await this function to get an item from the channel. If the buffer is empty, the frame will
119117 /// complete when the next item is put in the channel.
120118 pub async fn get(self: *SelfChannel) T {
121 // TODO integrate this function with named return values
122 // so we can get rid of this extra result copy
119 // TODO https://github.com/ziglang/zig/issues/2765
123120 var result: T = undefined;
124121 var my_tick_node = Loop.NextTickNode.init(@frame());
125122 var queue_node = std.atomic.Queue(GetNode).Node.init(GetNode{
......@@ -131,19 +128,19 @@ pub fn Channel(comptime T: type) type {
131128
132129 // TODO test canceling a get()
133130 errdefer {
134 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
131 _ = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
135132 const need_dispatch = !self.getters.remove(&queue_node);
136133 self.loop.cancelOnNextTick(&my_tick_node);
137134 if (need_dispatch) {
138135 // oops we made the get_count incorrect for a period of time. fix by dispatching.
139 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
136 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
140137 self.dispatch();
141138 }
142139 }
143140
144141 suspend {
145142 self.getters.put(&queue_node);
146 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
143 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
147144
148145 self.dispatch();
149146 }
......@@ -183,19 +180,19 @@ pub fn Channel(comptime T: type) type {
183180 // TODO test canceling getOrNull
184181 errdefer {
185182 _ = self.or_null_queue.remove(&or_null_node);
186 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
183 _ = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
187184 const need_dispatch = !self.getters.remove(&queue_node);
188185 self.loop.cancelOnNextTick(&my_tick_node);
189186 if (need_dispatch) {
190187 // oops we made the get_count incorrect for a period of time. fix by dispatching.
191 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
188 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
192189 self.dispatch();
193190 }
194191 }
195192
196193 suspend {
197194 self.getters.put(&queue_node);
198 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
195 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
199196 self.or_null_queue.put(&or_null_node);
200197
201198 self.dispatch();
......@@ -205,21 +202,21 @@ pub fn Channel(comptime T: type) type {
205202
206203 fn dispatch(self: *SelfChannel) void {
207204 // set the "need dispatch" flag
208 _ = @atomicRmw(u8, &self.need_dispatch, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
205 _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 1, .SeqCst);
209206
210207 lock: while (true) {
211208 // set the lock flag
212 const prev_lock = @atomicRmw(u8, &self.dispatch_lock, AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
209 const prev_lock = @atomicRmw(u8, &self.dispatch_lock, .Xchg, 1, .SeqCst);
213210 if (prev_lock != 0) return;
214211
215212 // clear the need_dispatch flag since we're about to do it
216 _ = @atomicRmw(u8, &self.need_dispatch, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
213 _ = @atomicRmw(u8, &self.need_dispatch, .Xchg, 0, .SeqCst);
217214
218215 while (true) {
219216 one_dispatch: {
220217 // later we correct these extra subtractions
221 var get_count = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
222 var put_count = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
218 var get_count = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
219 var put_count = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
223220
224221 // transfer self.buffer to self.getters
225222 while (self.buffer_len != 0) {
......@@ -238,7 +235,7 @@ pub fn Channel(comptime T: type) type {
238235 self.loop.onNextTick(get_node.tick_node);
239236 self.buffer_len -= 1;
240237
241 get_count = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
238 get_count = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
242239 }
243240
244241 // direct transfer self.putters to self.getters
......@@ -258,8 +255,8 @@ pub fn Channel(comptime T: type) type {
258255 self.loop.onNextTick(get_node.tick_node);
259256 self.loop.onNextTick(put_node.tick_node);
260257
261 get_count = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
262 put_count = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
258 get_count = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
259 put_count = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
263260 }
264261
265262 // transfer self.putters to self.buffer
......@@ -271,13 +268,13 @@ pub fn Channel(comptime T: type) type {
271268 self.buffer_index +%= 1;
272269 self.buffer_len += 1;
273270
274 put_count = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);
271 put_count = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
275272 }
276273 }
277274
278275 // undo the extra subtractions
279 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
280 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);
276 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
277 _ = @atomicRmw(usize, &self.put_count, .Add, 1, .SeqCst);
281278
282279 // All the "get or null" functions should resume now.
283280 var remove_count: usize = 0;
......@@ -286,18 +283,18 @@ pub fn Channel(comptime T: type) type {
286283 self.loop.onNextTick(or_null_node.data.data.tick_node);
287284 }
288285 if (remove_count != 0) {
289 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, remove_count, AtomicOrder.SeqCst);
286 _ = @atomicRmw(usize, &self.get_count, .Sub, remove_count, .SeqCst);
290287 }
291288
292289 // clear need-dispatch flag
293 const need_dispatch = @atomicRmw(u8, &self.need_dispatch, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
290 const need_dispatch = @atomicRmw(u8, &self.need_dispatch, .Xchg, 0, .SeqCst);
294291 if (need_dispatch != 0) continue;
295292
296 const my_lock = @atomicRmw(u8, &self.dispatch_lock, AtomicRmwOp.Xchg, 0, AtomicOrder.SeqCst);
293 const my_lock = @atomicRmw(u8, &self.dispatch_lock, .Xchg, 0, .SeqCst);
297294 assert(my_lock != 0);
298295
299296 // we have to check again now that we unlocked
300 if (@atomicLoad(u8, &self.need_dispatch, AtomicOrder.SeqCst) != 0) continue :lock;
297 if (@atomicLoad(u8, &self.need_dispatch, .SeqCst) != 0) continue :lock;
301298
302299 return;
303300 }
......@@ -327,16 +324,13 @@ test "std.event.Channel" {
327324}
328325
329326async fn testChannelGetter(loop: *Loop, channel: *Channel(i32)) void {
330 const value1_promise = async channel.get();
331 const value1 = await value1_promise;
327 const value1 = channel.get();
332328 testing.expect(value1 == 1234);
333329
334 const value2_promise = async channel.get();
335 const value2 = await value2_promise;
330 const value2 = channel.get();
336331 testing.expect(value2 == 4567);
337332
338 const value3_promise = async channel.getOrNull();
339 const value3 = await value3_promise;
333 const value3 = channel.getOrNull();
340334 testing.expect(value3 == null);
341335
342336 const last_put = async testPut(channel, 4444);