OLD | NEW |
| (Empty) |
1 This document describes some of the internals of the C bindings, along with some | |
2 numbers. | |
3 | |
4 # Generated code | |
5 | |
6 One of the goals of the C bindings is to generate minimal code and use little | |
7 memory. The C bindings achieve this by generating type descriptors for each | |
8 mojom type that contain information required for encoding, decoding and | |
9 validation. For instance, type descriptions for mojom structs describe where the | |
10 pointer and handle fields in a struct are located, which of them are nullable, | |
11 the sizes of different versions of the struct, etc. Using this information, we | |
12 can avoid generating separate encoding, decoding and validation code for each | |
13 struct, and instead rely on a common encoding function shared amongst all mojom | |
14 structs which consume these generated type descriptions. Simiarly, type | |
15 descriptions are generated for every instance of arrays, maps, and unions. These | |
16 type descriptions live in the `.rodata` (or similar) section of a binary. | |
17 | |
18 # Sizes of type descriptors | |
19 | |
20 The following subsections describe the space cost of type descriptors generated | |
21 for different mojom types on a 64-bit system. The C data types for type | |
22 descriptors are located in `bindings/type_descriptor.h`, which is the | |
23 canonical place for up-to-date documentation of type description tables, how | |
24 they are structured and used. | |
25 | |
26 ## Structs | |
27 A type descriptor for a mojom struct contains: | |
28 - A version table (pointer, 8 bytes): | |
29 - Each version is described by a `version` <=> `size of struct` (8 bytes) | |
30 - Number of elements in the version table (4 bytes) | |
31 - Pointer/handle location table (pointer, 8 bytes): | |
32 - Array of `struct MojomTypeDescriptorStructEntry` (roughly 20 bytes per | |
33 field), each entry describing a pointer or handle field. | |
34 - Number of entries in the table (4 bytes) | |
35 | |
36 Example: | |
37 ```mojom | |
38 struct Rect { | |
39 int32 x; | |
40 int32 y; | |
41 int32 w; | |
42 int32 h; | |
43 }; | |
44 ``` | |
45 | |
46 This struct has just 1 version, and no pointer or handle fields. It takes up `8 | |
47 bytes + 8 bytes + 4 bytes` for the version table, another `8 bytes + 4 bytes` | |
48 for the location table, for a total of **32 bytes**. Adding any additional | |
49 non-handle/pointer fields will not grow the generated type descriptior for this | |
50 mojom struct. | |
51 | |
52 Another example: | |
53 ```mojom | |
54 struct RectPair { | |
55 Rect a; | |
56 Rect b; | |
57 }; | |
58 ``` | |
59 | |
60 RectPair similarly has 1 version (accounting for `8 + 8 + 4 bytes`), but has 2 | |
61 pointer types, which puts its location table to `8 + 4 + 20*2 bytes`, bringing | |
62 its type descriptor to **72 bytes** in size. | |
63 | |
64 ## Arrays and Strings | |
65 | |
66 A type descriptor for a mojom array contains: | |
67 - The type of its entries, and a pointer to its type descriptor (roughly 1 + 8 | |
68 bytes) | |
69 - Number of elements in the array, only applicable if defined in the mojom IDL | |
70 (4 bytes) | |
71 - Size (in number of bits) of a single element. (4 bytes) | |
72 - If its elements can be nullable (1 byte). | |
73 | |
74 A single array of any type (e.g., `array<int8>`) will therefore take roughly **1
8 | |
75 bytes**. However, an array of other composite types can end up forming a chain o
f | |
76 type descriptors. For example, consider `array<array<int8>>`: 18 bytes for the | |
77 outer-array, and another 18 bytes for `array<int8>`, totalling **36 bytes**. | |
78 | |
79 Strings are arrays of UTF-8 encoded characters; A type descriptor for a string | |
80 is always the same (it is composed of a variable number of characters). For this | |
81 reason, the bindings library comes with a single type descriptor for an array of | |
82 characters, so a new type descriptor is not generated for every instance of a | |
83 string. | |
84 | |
85 ## Maps | |
86 | |
87 A map is just a mojom struct with 2 mojom arrays, so a type descriptor for a sim
ple map (mapping a POD | |
88 to a POD) could take `32 bytes + 2 * (18 bytes)` = **68 bytes**. A new type | |
89 descriptor is generated for every occurance of a mojom map. A possible optimizat
ion in | |
90 the future is to deduplicate identical type descriptors and share them. | |
91 | |
92 ## Unions | |
93 | |
94 TODO(vardhan) | |
95 | |
96 ## Interfaces | |
97 | |
98 Interfaces are composed of messages, each of which is composed of a request | |
99 parameters, and possibly response parameters. For example: | |
100 | |
101 ```mojom | |
102 struct Person { ... }; | |
103 | |
104 interface Population { | |
105 GetPerson(string name) => (Person p); | |
106 }; | |
107 ``` | |
108 | |
109 Consits of two mojom structs, equivalent to: | |
110 ```mojom | |
111 struct Population_GetPerson_Request { | |
112 string name; | |
113 } | |
114 struct Population_GetPerson_Response { | |
115 Person p; | |
116 }; | |
117 ``` | |
118 | |
119 The request struct takes up **32 bytes** (taken from the example in the | |
120 **Structs** section above) **+ 8 bytes** (for the string entry). Similarly, the | |
121 response struct takes up another **32+8 bytes** bytes (this is not accounting | |
122 for the space taken up by the `struct Person` type descriptor). | |
123 | |
124 ## Other types | |
125 | |
126 TODO(vardhan) | |
127 | |
128 # Compiled code size | |
129 | |
130 A lot of these generated type descriptors can be compacted further, if required. | |
131 This kind of optimization could be done later when things are more stable. There | |
132 are also opportunities to de-duplicate generated type descriptors, notable for | |
133 arrays and maps (e.g., we only need one type descriptor for array<int8> that | |
134 could be shared across all mojom structs). | |
135 | |
136 Comparing the sizes of an example mojo echo client in C and C++ (which can be | |
137 found in the domokit/mojo github repo), built for Linux: | |
138 | |
139 C++ echo client: | |
140 ```bash | |
141 $ size out/Release/echo_client.mojo | |
142 text data bss dec hex filename | |
143 134194 4528 436 139158 21f96 out/Release/echo_client.mojo | |
144 ``` | |
145 | |
146 C echo client: | |
147 ```bash | |
148 $ size out/Release/c_echo_client.mojo | |
149 text data bss dec hex filename | |
150 9834 1328 264 11426 2ca2 out/Release/c_echo_client.mojo | |
151 ``` | |
OLD | NEW |