Skip to content

Commit b933030

Browse files
elinorbgrvberger
authored andcommitted
commons: use smallvec to store message arguments
Any message with 4 argument or less will have these arguments stored inline rather than in an heap-allocated vec. The number 4 was chose because almost all messages have 4 arguments or less, and some potentially very spammy messages (wl_touch.move) have exactly 4 arguments. Avoiding allocations in these cases should generally be a gain. Moreother, to avoid bloating the size of Message due to this, String and Array arguments are further boxed, reducing the size of Argument from 4*usize to 2*usize. These kind of arguments are generally pretty rare, so the double allocation should overall not counter the size gain. Closes #268, #249
1 parent b1d5ec2 commit b933030

File tree

19 files changed

+106
-68
lines changed

19 files changed

+106
-68
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
- [client] the `cursor` and `egl` features are split into their own crates: `wayland-egl` and `wayland-cursor`
1515
- [server] All dependencies on `calloop` are now removed, `wayland-server` now only exposes a `dispatch(..)`
1616
and `get_poll_fd()` method, that you are responsible for integrating into your event loop.
17+
- [commons] Use `smallvec` to store the arguments of messages having 4 or less, drastically reducing the
18+
number of allocations when using the rust implementation of the protocol.
1719

1820
## 0.23.6 -- 2019-09-06
1921

tests/protocol_errors.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use helpers::{roundtrip, wayc, ways, TestClient, TestServer};
55
extern crate nix;
66
extern crate wayland_commons as wc;
77

8+
use wc::smallvec;
89
use wc::socket::{BufferedSocket, Socket};
910
use wc::wire::{Argument, Message};
1011

@@ -28,7 +29,7 @@ fn client_wrong_id() {
2829
.write_message(&Message {
2930
sender_id: 1, // wl_display
3031
opcode: 1, // wl_registry
31-
args: vec![
32+
args: smallvec![
3233
Argument::NewId(3), // should be 2
3334
],
3435
})
@@ -54,7 +55,7 @@ fn client_wrong_opcode() {
5455
.write_message(&Message {
5556
sender_id: 1, // wl_display
5657
opcode: 42, // inexistant
57-
args: vec![],
58+
args: smallvec![],
5859
})
5960
.unwrap();
6061
socket.flush().unwrap();
@@ -78,7 +79,7 @@ fn client_wrong_sender() {
7879
.write_message(&Message {
7980
sender_id: 54, // wl_display
8081
opcode: 0, // inexistant
81-
args: vec![],
82+
args: smallvec![],
8283
})
8384
.unwrap();
8485
socket.flush().unwrap();

tests/scanner_assets/client_code.rs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub mod wl_foo {
1515
use super::sys::client::*;
1616
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
1717
use super::{
18-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
18+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
1919
MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR,
2020
};
2121
use std::os::raw::c_char;
@@ -134,18 +134,20 @@ pub mod wl_foo {
134134
} => Message {
135135
sender_id: sender_id,
136136
opcode: 0,
137-
args: vec![
137+
args: smallvec![
138138
Argument::Int(number),
139139
Argument::Uint(unumber),
140-
Argument::Str(unsafe { ::std::ffi::CString::from_vec_unchecked(text.into()) }),
140+
Argument::Str(Box::new(unsafe {
141+
::std::ffi::CString::from_vec_unchecked(text.into())
142+
})),
141143
Argument::Fixed((float * 256.) as i32),
142144
Argument::Fd(file),
143145
],
144146
},
145147
Request::CreateBar {} => Message {
146148
sender_id: sender_id,
147149
opcode: 1,
148-
args: vec![Argument::NewId(0)],
150+
args: smallvec![Argument::NewId(0),],
149151
},
150152
}
151153
}
@@ -369,7 +371,7 @@ pub mod wl_bar {
369371
use super::sys::client::*;
370372
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
371373
use super::{
372-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
374+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
373375
MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR,
374376
};
375377
use std::os::raw::c_char;
@@ -475,17 +477,17 @@ pub mod wl_bar {
475477
} => Message {
476478
sender_id: sender_id,
477479
opcode: 0,
478-
args: vec![
480+
args: smallvec![
479481
Argument::Uint(kind.to_raw()),
480482
Argument::Object(target.as_ref().id()),
481-
Argument::Array(metadata),
482-
Argument::Array(metametadata.unwrap_or_else(Vec::new)),
483+
Argument::Array(Box::new(metadata)),
484+
Argument::Array(Box::new(metametadata.unwrap_or_else(Vec::new))),
483485
],
484486
},
485487
Request::Release => Message {
486488
sender_id: sender_id,
487489
opcode: 1,
488-
args: vec![],
490+
args: smallvec![],
489491
},
490492
Request::_Self {
491493
_self,
@@ -499,7 +501,7 @@ pub mod wl_bar {
499501
} => Message {
500502
sender_id: sender_id,
501503
opcode: 2,
502-
args: vec![
504+
args: smallvec![
503505
Argument::Uint(_self),
504506
Argument::Uint(_mut),
505507
Argument::Uint(object),
@@ -861,7 +863,7 @@ pub mod wl_display {
861863
use super::sys::client::*;
862864
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
863865
use super::{
864-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
866+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
865867
MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR,
866868
};
867869
use std::os::raw::c_char;
@@ -1012,7 +1014,7 @@ pub mod wl_registry {
10121014
use super::sys::client::*;
10131015
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
10141016
use super::{
1015-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
1017+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
10161018
MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR,
10171019
};
10181020
use std::os::raw::c_char;
@@ -1062,9 +1064,11 @@ pub mod wl_registry {
10621064
Request::Bind { name, id } => Message {
10631065
sender_id: sender_id,
10641066
opcode: 0,
1065-
args: vec![
1067+
args: smallvec![
10661068
Argument::Uint(name),
1067-
Argument::Str(unsafe { ::std::ffi::CString::from_vec_unchecked(id.0.into()) }),
1069+
Argument::Str(Box::new(unsafe {
1070+
::std::ffi::CString::from_vec_unchecked(id.0.into())
1071+
})),
10681072
Argument::Uint(id.1),
10691073
Argument::NewId(0),
10701074
],
@@ -1213,7 +1217,7 @@ pub mod wl_callback {
12131217
use super::sys::client::*;
12141218
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
12151219
use super::{
1216-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
1220+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
12171221
MessageGroup, Object, ObjectMetadata, Proxy, NULLPTR,
12181222
};
12191223
use std::os::raw::c_char;

tests/scanner_assets/server_code.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub mod wl_foo {
1515
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
1616
use super::sys::server::*;
1717
use super::{
18-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
18+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
1919
MessageGroup, Object, ObjectMetadata, Resource, NULLPTR,
2020
};
2121
use std::os::raw::c_char;
@@ -264,7 +264,7 @@ pub mod wl_foo {
264264
Event::Cake { kind, amount } => Message {
265265
sender_id: sender_id,
266266
opcode: 0,
267-
args: vec![Argument::Uint(kind.to_raw()), Argument::Uint(amount)],
267+
args: smallvec![Argument::Uint(kind.to_raw()), Argument::Uint(amount),],
268268
},
269269
}
270270
}
@@ -371,7 +371,7 @@ pub mod wl_bar {
371371
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
372372
use super::sys::server::*;
373373
use super::{
374-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
374+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
375375
MessageGroup, Object, ObjectMetadata, Resource, NULLPTR,
376376
};
377377
use std::os::raw::c_char;
@@ -484,7 +484,7 @@ pub mod wl_bar {
484484
},
485485
metadata: {
486486
if let Some(Argument::Array(val)) = args.next() {
487-
val
487+
*val
488488
} else {
489489
return Err(());
490490
}
@@ -494,7 +494,7 @@ pub mod wl_bar {
494494
if val.len() == 0 {
495495
None
496496
} else {
497-
Some(val)
497+
Some(*val)
498498
}
499499
} else {
500500
return Err(());
@@ -692,7 +692,7 @@ pub mod wl_bar {
692692
} => Message {
693693
sender_id: sender_id,
694694
opcode: 0,
695-
args: vec![
695+
args: smallvec![
696696
Argument::Uint(_self),
697697
Argument::Uint(_mut),
698698
Argument::Uint(object),
@@ -850,7 +850,7 @@ pub mod wl_callback {
850850
use super::sys::common::{wl_argument, wl_array, wl_interface, wl_message};
851851
use super::sys::server::*;
852852
use super::{
853-
types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
853+
smallvec, types_null, AnonymousObject, Argument, ArgumentType, Interface, Main, Message, MessageDesc,
854854
MessageGroup, Object, ObjectMetadata, Resource, NULLPTR,
855855
};
856856
use std::os::raw::c_char;
@@ -951,7 +951,7 @@ pub mod wl_callback {
951951
Event::Done { callback_data } => Message {
952952
sender_id: sender_id,
953953
opcode: 0,
954-
args: vec![Argument::Uint(callback_data)],
954+
args: smallvec![Argument::Uint(callback_data),],
955955
},
956956
}
957957
}

wayland-client/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pub mod protocol {
135135

136136
pub(crate) use crate::{AnonymousObject, Attached, Main, Proxy, ProxyMap};
137137
pub(crate) use wayland_commons::map::{Object, ObjectMetadata};
138+
pub(crate) use wayland_commons::smallvec;
138139
pub(crate) use wayland_commons::wire::{Argument, ArgumentType, Message, MessageDesc};
139140
pub(crate) use wayland_commons::{Interface, MessageGroup};
140141
pub(crate) use wayland_sys as sys;

wayland-client/src/rust_imp/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl ProxyMap {
6060
/*
6161
* Dispatching logic
6262
*/
63+
#[allow(clippy::large_enum_variant)]
6364
pub(crate) enum Dispatched {
6465
Yes,
6566
NoDispatch(Message, ProxyInner),

wayland-client/src/rust_imp/queues.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ fn message_to_rawevent(msg: Message, proxy: &ProxyInner, map: &mut super::ProxyM
264264
.map(|a| match a {
265265
Argument::Int(i) => crate::Argument::Int(i),
266266
Argument::Uint(u) => crate::Argument::Uint(u),
267-
Argument::Array(v) => crate::Argument::Array(if v.is_empty() { None } else { Some(v) }),
267+
Argument::Array(v) => crate::Argument::Array(if v.is_empty() { None } else { Some(*v) }),
268268
Argument::Fixed(f) => crate::Argument::Float((f as f32) / 256.),
269269
Argument::Fd(f) => crate::Argument::Fd(f),
270270
Argument::Str(cs) => crate::Argument::Str({

wayland-commons/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ travis-ci = { repository = "Smithay/wayland-rs" }
1717
wayland-sys = { version = "0.24.0-pre", path = "../wayland-sys" }
1818
nix = "0.15"
1919
spin = "0.5"
20+
smallvec = "0.6"

wayland-commons/examples/manual_global_list.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::os::unix::io::{FromRawFd, IntoRawFd};
55
use std::os::unix::net::UnixStream;
66
use std::path::PathBuf;
77

8+
use wc::smallvec;
89
use wc::socket::{BufferedSocket, Socket};
910
use wc::wire::{Argument, ArgumentType, Message, MessageDesc};
1011

@@ -20,7 +21,7 @@ fn main() {
2021
.write_message(&Message {
2122
sender_id: 1, // wl_display
2223
opcode: 1, // get registry
23-
args: vec![
24+
args: smallvec![
2425
Argument::NewId(2), // id of the created registry
2526
],
2627
})

wayland-commons/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub mod socket;
2727
pub mod user_data;
2828
pub mod wire;
2929

30+
pub use smallvec::smallvec;
31+
3032
/// A group of messages
3133
///
3234
/// This represents a group of message that can be serialized on the protocol wire.

0 commit comments

Comments
 (0)