| Index: mojo/public/c/docs/bindings/INTERNALS.md
|
| diff --git a/mojo/public/c/docs/bindings/INTERNALS.md b/mojo/public/c/docs/bindings/INTERNALS.md
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d44d20f83c4ada7c6172bbd1c170c5fe38c7b537
|
| --- /dev/null
|
| +++ b/mojo/public/c/docs/bindings/INTERNALS.md
|
| @@ -0,0 +1,151 @@
|
| +This document describes some of the internals of the C bindings, along with some
|
| +numbers.
|
| +
|
| +# Generated code
|
| +
|
| +One of the goals of the C bindings is to generate minimal code and use little
|
| +memory. The C bindings achieve this by generating type descriptors for each
|
| +mojom type that contain information required for encoding, decoding and
|
| +validation. For instance, type descriptions for mojom structs describe where the
|
| +pointer and handle fields in a struct are located, which of them are nullable,
|
| +the sizes of different versions of the struct, etc. Using this information, we
|
| +can avoid generating separate encoding, decoding and validation code for each
|
| +struct, and instead rely on a common encoding function shared amongst all mojom
|
| +structs which consume these generated type descriptions. Simiarly, type
|
| +descriptions are generated for every instance of arrays, maps, and unions. These
|
| +type descriptions live in the `.rodata` (or similar) section of a binary.
|
| +
|
| +# Sizes of type descriptors
|
| +
|
| +The following subsections describe the space cost of type descriptors generated
|
| +for different mojom types on a 64-bit system. The C data types for type
|
| +descriptors are located in `bindings/type_descriptor.h`, which is the
|
| +canonical place for up-to-date documentation of type description tables, how
|
| +they are structured and used.
|
| +
|
| +## Structs
|
| +A type descriptor for a mojom struct contains:
|
| +- A version table (pointer, 8 bytes):
|
| + - Each version is described by a `version` <=> `size of struct` (8 bytes)
|
| + - Number of elements in the version table (4 bytes)
|
| +- Pointer/handle location table (pointer, 8 bytes):
|
| + - Array of `struct MojomTypeDescriptorStructEntry` (roughly 20 bytes per
|
| + field), each entry describing a pointer or handle field.
|
| + - Number of entries in the table (4 bytes)
|
| +
|
| +Example:
|
| +```mojom
|
| +struct Rect {
|
| + int32 x;
|
| + int32 y;
|
| + int32 w;
|
| + int32 h;
|
| +};
|
| +```
|
| +
|
| +This struct has just 1 version, and no pointer or handle fields. It takes up `8
|
| +bytes + 8 bytes + 4 bytes` for the version table, another `8 bytes + 4 bytes`
|
| +for the location table, for a total of **32 bytes**. Adding any additional
|
| +non-handle/pointer fields will not grow the generated type descriptior for this
|
| +mojom struct.
|
| +
|
| +Another example:
|
| +```mojom
|
| +struct RectPair {
|
| + Rect a;
|
| + Rect b;
|
| +};
|
| +```
|
| +
|
| +RectPair similarly has 1 version (accounting for `8 + 8 + 4 bytes`), but has 2
|
| +pointer types, which puts its location table to `8 + 4 + 20*2 bytes`, bringing
|
| +its type descriptor to **72 bytes** in size.
|
| +
|
| +## Arrays and Strings
|
| +
|
| +A type descriptor for a mojom array contains:
|
| +- The type of its entries, and a pointer to its type descriptor (roughly 1 + 8
|
| + bytes)
|
| +- Number of elements in the array, only applicable if defined in the mojom IDL
|
| + (4 bytes)
|
| +- Size (in number of bits) of a single element. (4 bytes)
|
| +- If its elements can be nullable (1 byte).
|
| +
|
| +A single array of any type (e.g., `array<int8>`) will therefore take roughly **18
|
| +bytes**. However, an array of other composite types can end up forming a chain of
|
| +type descriptors. For example, consider `array<array<int8>>`: 18 bytes for the
|
| +outer-array, and another 18 bytes for `array<int8>`, totalling **36 bytes**.
|
| +
|
| +Strings are arrays of UTF-8 encoded characters; A type descriptor for a string
|
| +is always the same (it is composed of a variable number of characters). For this
|
| +reason, the bindings library comes with a single type descriptor for an array of
|
| +characters, so a new type descriptor is not generated for every instance of a
|
| +string.
|
| +
|
| +## Maps
|
| +
|
| +A map is just a mojom struct with 2 mojom arrays, so a type descriptor for a simple map (mapping a POD
|
| +to a POD) could take `32 bytes + 2 * (18 bytes)` = **68 bytes**. A new type
|
| +descriptor is generated for every occurance of a mojom map. A possible optimization in
|
| +the future is to deduplicate identical type descriptors and share them.
|
| +
|
| +## Unions
|
| +
|
| +TODO(vardhan)
|
| +
|
| +## Interfaces
|
| +
|
| +Interfaces are composed of messages, each of which is composed of a request
|
| +parameters, and possibly response parameters. For example:
|
| +
|
| +```mojom
|
| +struct Person { ... };
|
| +
|
| +interface Population {
|
| + GetPerson(string name) => (Person p);
|
| +};
|
| +```
|
| +
|
| +Consits of two mojom structs, equivalent to:
|
| +```mojom
|
| +struct Population_GetPerson_Request {
|
| + string name;
|
| +}
|
| +struct Population_GetPerson_Response {
|
| + Person p;
|
| +};
|
| +```
|
| +
|
| +The request struct takes up **32 bytes** (taken from the example in the
|
| +**Structs** section above) **+ 8 bytes** (for the string entry). Similarly, the
|
| +response struct takes up another **32+8 bytes** bytes (this is not accounting
|
| +for the space taken up by the `struct Person` type descriptor).
|
| +
|
| +## Other types
|
| +
|
| +TODO(vardhan)
|
| +
|
| +# Compiled code size
|
| +
|
| +A lot of these generated type descriptors can be compacted further, if required.
|
| +This kind of optimization could be done later when things are more stable. There
|
| +are also opportunities to de-duplicate generated type descriptors, notable for
|
| +arrays and maps (e.g., we only need one type descriptor for array<int8> that
|
| +could be shared across all mojom structs).
|
| +
|
| +Comparing the sizes of an example mojo echo client in C and C++ (which can be
|
| +found in the domokit/mojo github repo), built for Linux:
|
| +
|
| +C++ echo client:
|
| +```bash
|
| +$ size out/Release/echo_client.mojo
|
| + text data bss dec hex filename
|
| +134194 4528 436 139158 21f96 out/Release/echo_client.mojo
|
| +```
|
| +
|
| +C echo client:
|
| +```bash
|
| +$ size out/Release/c_echo_client.mojo
|
| +text data bss dec hex filename
|
| +9834 1328 264 11426 2ca2 out/Release/c_echo_client.mojo
|
| +```
|
|
|