| 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 |