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 |