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) {...@@ -1500,7 +1500,7 @@ bool type_is_invalid(ZigType *type_entry) {
15001500
15011501
1502ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],1502ZigType *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)
1504{1504{
1505 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);1505 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...@@ -1512,7 +1512,7 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
1512 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);1512 struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
1513 struct_type->data.structure.fields_by_name.init(field_count);1513 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;
1516 for (size_t i = 0; i < field_count; i += 1) {1516 for (size_t i = 0; i < field_count; i += 1) {
1517 TypeStructField *field = &struct_type->data.structure.fields[i];1517 TypeStructField *field = &struct_type->data.structure.fields[i];
1518 field->name = buf_create_from_str(field_names[i]);1518 field->name = buf_create_from_str(field_names[i]);
...@@ -5334,7 +5334,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5334,7 +5334,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
53345334
5335 assert(field_names.length == field_types.length);5335 assert(field_names.length == field_types.length);
5336 frame_type->data.frame.locals_struct = get_struct_type(g, buf_ptr(&frame_type->name),5336 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));
5338 frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;5338 frame_type->abi_size = frame_type->data.frame.locals_struct->abi_size;
5339 frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;5339 frame_type->abi_align = frame_type->data.frame.locals_struct->abi_align;
5340 frame_type->size_in_bits = frame_type->data.frame.locals_struct->size_in_bits;5340 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...@@ -7764,8 +7764,8 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
77647764
7765LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {7765LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type) {
7766 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));7766 assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
7767 assert(type->abi_size == 0 || type->abi_size == LLVMABISizeOfType(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));7768 assert(type->abi_align == 0 || type->abi_align >= LLVMABIAlignmentOfType(g->target_data_ref, type->llvm_type));
7769 return type->llvm_type;7769 return type->llvm_type;
7770}7770}
77717771
src/analyze.hpp+1-1
...@@ -39,7 +39,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa...@@ -39,7 +39,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
39ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);39ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
40ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);40ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
41ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],41ZigType *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);
43ZigType *get_test_fn_type(CodeGen *g);43ZigType *get_test_fn_type(CodeGen *g);
44ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);44ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
45bool handle_is_ptr(ZigType *type_entry);45bool handle_is_ptr(ZigType *type_entry);
src/target.cpp+4
...@@ -1759,3 +1759,7 @@ bool target_supports_libunwind(const ZigTarget *target) {...@@ -1759,3 +1759,7 @@ bool target_supports_libunwind(const ZigTarget *target) {
1759 return true;1759 return true;
1760}1760}
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);...@@ -197,4 +197,6 @@ uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);
197size_t target_libc_count(void);197size_t target_libc_count(void);
198void target_libc_enum(size_t index, ZigTarget *out_target);198void target_libc_enum(size_t index, ZigTarget *out_target);
199199
200unsigned target_fn_align(const ZigTarget *target);
201
200#endif202#endif
std/event/channel.zig+28-34
...@@ -2,8 +2,6 @@ const std = @import("../std.zig");...@@ -2,8 +2,6 @@ const std = @import("../std.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const assert = std.debug.assert;3const assert = std.debug.assert;
4const testing = std.testing;4const testing = std.testing;
5const AtomicRmwOp = builtin.AtomicRmwOp;
6const AtomicOrder = builtin.AtomicOrder;
7const Loop = std.event.Loop;5const Loop = std.event.Loop;
86
9/// many producer, many consumer, thread-safe, runtime configurable buffer size7/// many producer, many consumer, thread-safe, runtime configurable buffer size
...@@ -98,18 +96,18 @@ pub fn Channel(comptime T: type) type {...@@ -98,18 +96,18 @@ pub fn Channel(comptime T: type) type {
9896
99 // TODO test canceling a put()97 // TODO test canceling a put()
100 errdefer {98 errdefer {
101 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);99 _ = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
102 const need_dispatch = !self.putters.remove(&queue_node);100 const need_dispatch = !self.putters.remove(&queue_node);
103 self.loop.cancelOnNextTick(&my_tick_node);101 self.loop.cancelOnNextTick(&my_tick_node);
104 if (need_dispatch) {102 if (need_dispatch) {
105 // oops we made the put_count incorrect for a period of time. fix by dispatching.103 // 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);
107 self.dispatch();105 self.dispatch();
108 }106 }
109 }107 }
110 suspend {108 suspend {
111 self.putters.put(&queue_node);109 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
114 self.dispatch();112 self.dispatch();
115 }113 }
...@@ -118,8 +116,7 @@ pub fn Channel(comptime T: type) type {...@@ -118,8 +116,7 @@ pub fn Channel(comptime T: type) type {
118 /// await this function to get an item from the channel. If the buffer is empty, the frame will116 /// await this function to get an item from the channel. If the buffer is empty, the frame will
119 /// complete when the next item is put in the channel.117 /// complete when the next item is put in the channel.
120 pub async fn get(self: *SelfChannel) T {118 pub async fn get(self: *SelfChannel) T {
121 // TODO integrate this function with named return values119 // TODO https://github.com/ziglang/zig/issues/2765
122 // so we can get rid of this extra result copy
123 var result: T = undefined;120 var result: T = undefined;
124 var my_tick_node = Loop.NextTickNode.init(@frame());121 var my_tick_node = Loop.NextTickNode.init(@frame());
125 var queue_node = std.atomic.Queue(GetNode).Node.init(GetNode{122 var queue_node = std.atomic.Queue(GetNode).Node.init(GetNode{
...@@ -131,19 +128,19 @@ pub fn Channel(comptime T: type) type {...@@ -131,19 +128,19 @@ pub fn Channel(comptime T: type) type {
131128
132 // TODO test canceling a get()129 // TODO test canceling a get()
133 errdefer {130 errdefer {
134 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);131 _ = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
135 const need_dispatch = !self.getters.remove(&queue_node);132 const need_dispatch = !self.getters.remove(&queue_node);
136 self.loop.cancelOnNextTick(&my_tick_node);133 self.loop.cancelOnNextTick(&my_tick_node);
137 if (need_dispatch) {134 if (need_dispatch) {
138 // oops we made the get_count incorrect for a period of time. fix by dispatching.135 // 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);
140 self.dispatch();137 self.dispatch();
141 }138 }
142 }139 }
143140
144 suspend {141 suspend {
145 self.getters.put(&queue_node);142 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
148 self.dispatch();145 self.dispatch();
149 }146 }
...@@ -183,19 +180,19 @@ pub fn Channel(comptime T: type) type {...@@ -183,19 +180,19 @@ pub fn Channel(comptime T: type) type {
183 // TODO test canceling getOrNull180 // TODO test canceling getOrNull
184 errdefer {181 errdefer {
185 _ = self.or_null_queue.remove(&or_null_node);182 _ = 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);
187 const need_dispatch = !self.getters.remove(&queue_node);184 const need_dispatch = !self.getters.remove(&queue_node);
188 self.loop.cancelOnNextTick(&my_tick_node);185 self.loop.cancelOnNextTick(&my_tick_node);
189 if (need_dispatch) {186 if (need_dispatch) {
190 // oops we made the get_count incorrect for a period of time. fix by dispatching.187 // 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);
192 self.dispatch();189 self.dispatch();
193 }190 }
194 }191 }
195192
196 suspend {193 suspend {
197 self.getters.put(&queue_node);194 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);
199 self.or_null_queue.put(&or_null_node);196 self.or_null_queue.put(&or_null_node);
200197
201 self.dispatch();198 self.dispatch();
...@@ -205,21 +202,21 @@ pub fn Channel(comptime T: type) type {...@@ -205,21 +202,21 @@ pub fn Channel(comptime T: type) type {
205202
206 fn dispatch(self: *SelfChannel) void {203 fn dispatch(self: *SelfChannel) void {
207 // set the "need dispatch" flag204 // 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
210 lock: while (true) {207 lock: while (true) {
211 // set the lock flag208 // 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);
213 if (prev_lock != 0) return;210 if (prev_lock != 0) return;
214211
215 // clear the need_dispatch flag since we're about to do it212 // 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
218 while (true) {215 while (true) {
219 one_dispatch: {216 one_dispatch: {
220 // later we correct these extra subtractions217 // later we correct these extra subtractions
221 var get_count = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);218 var get_count = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
222 var put_count = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);219 var put_count = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
223220
224 // transfer self.buffer to self.getters221 // transfer self.buffer to self.getters
225 while (self.buffer_len != 0) {222 while (self.buffer_len != 0) {
...@@ -238,7 +235,7 @@ pub fn Channel(comptime T: type) type {...@@ -238,7 +235,7 @@ pub fn Channel(comptime T: type) type {
238 self.loop.onNextTick(get_node.tick_node);235 self.loop.onNextTick(get_node.tick_node);
239 self.buffer_len -= 1;236 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);
242 }239 }
243240
244 // direct transfer self.putters to self.getters241 // direct transfer self.putters to self.getters
...@@ -258,8 +255,8 @@ pub fn Channel(comptime T: type) type {...@@ -258,8 +255,8 @@ pub fn Channel(comptime T: type) type {
258 self.loop.onNextTick(get_node.tick_node);255 self.loop.onNextTick(get_node.tick_node);
259 self.loop.onNextTick(put_node.tick_node);256 self.loop.onNextTick(put_node.tick_node);
260257
261 get_count = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);258 get_count = @atomicRmw(usize, &self.get_count, .Sub, 1, .SeqCst);
262 put_count = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Sub, 1, AtomicOrder.SeqCst);259 put_count = @atomicRmw(usize, &self.put_count, .Sub, 1, .SeqCst);
263 }260 }
264261
265 // transfer self.putters to self.buffer262 // transfer self.putters to self.buffer
...@@ -271,13 +268,13 @@ pub fn Channel(comptime T: type) type {...@@ -271,13 +268,13 @@ pub fn Channel(comptime T: type) type {
271 self.buffer_index +%= 1;268 self.buffer_index +%= 1;
272 self.buffer_len += 1;269 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);
275 }272 }
276 }273 }
277274
278 // undo the extra subtractions275 // undo the extra subtractions
279 _ = @atomicRmw(usize, &self.get_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);276 _ = @atomicRmw(usize, &self.get_count, .Add, 1, .SeqCst);
280 _ = @atomicRmw(usize, &self.put_count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst);277 _ = @atomicRmw(usize, &self.put_count, .Add, 1, .SeqCst);
281278
282 // All the "get or null" functions should resume now.279 // All the "get or null" functions should resume now.
283 var remove_count: usize = 0;280 var remove_count: usize = 0;
...@@ -286,18 +283,18 @@ pub fn Channel(comptime T: type) type {...@@ -286,18 +283,18 @@ pub fn Channel(comptime T: type) type {
286 self.loop.onNextTick(or_null_node.data.data.tick_node);283 self.loop.onNextTick(or_null_node.data.data.tick_node);
287 }284 }
288 if (remove_count != 0) {285 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);
290 }287 }
291288
292 // clear need-dispatch flag289 // 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);
294 if (need_dispatch != 0) continue;291 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);
297 assert(my_lock != 0);294 assert(my_lock != 0);
298295
299 // we have to check again now that we unlocked296 // 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
302 return;299 return;
303 }300 }
...@@ -327,16 +324,13 @@ test "std.event.Channel" {...@@ -327,16 +324,13 @@ test "std.event.Channel" {
327}324}
328325
329async fn testChannelGetter(loop: *Loop, channel: *Channel(i32)) void {326async fn testChannelGetter(loop: *Loop, channel: *Channel(i32)) void {
330 const value1_promise = async channel.get();327 const value1 = channel.get();
331 const value1 = await value1_promise;
332 testing.expect(value1 == 1234);328 testing.expect(value1 == 1234);
333329
334 const value2_promise = async channel.get();330 const value2 = channel.get();
335 const value2 = await value2_promise;
336 testing.expect(value2 == 4567);331 testing.expect(value2 == 4567);
337332
338 const value3_promise = async channel.getOrNull();333 const value3 = channel.getOrNull();
339 const value3 = await value3_promise;
340 testing.expect(value3 == null);334 testing.expect(value3 == null);
341335
342 const last_put = async testPut(channel, 4444);336 const last_put = async testPut(channel, 4444);