Skip to content

Commit

Permalink
make linter happy
Browse files Browse the repository at this point in the history
  • Loading branch information
VSadov authored Sep 20, 2024
1 parent 91a2406 commit 05cf73a
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions docs/design/features/InlineArrayAttribute.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Background and motivation

There were multiple proposals and ideas in the past asking for a no-indirection primitive for inline data. [Example1(inline strings)](https://github.com/dotnet/csharplang/issues/2099), [Example2(inline arrays)](https://github.com/dotnet/runtime/issues/12320), [Example3(generalized fixed-buffers)](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md#safe-fixed-size-buffers)
Our existing offering in this area – [unsafe fixed-sized buffers](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code#fixed-size-buffers) has multiple constraints, in particular it works only with blittable value types and provides no overrun/type safety, which considerably limits its use.
Our existing offering in this area – [unsafe fixed-sized buffers](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/unsafe-code#fixed-size-buffers) has multiple constraints, in particular it works only with blittable value types and provides no overrun/type safety, which considerably limits its use.

The InlineArrayAttribute is a building block to allow efficient, type-safe, overrun-safe indexable/sliceable inline data.

Expand All @@ -21,8 +21,8 @@ namespace System.Runtime.CompilerServices
public int Length { get; }
}
}
```
```

When `InlineArray` attribute is applied to a struct with one instance field, it is interpreted by the runtime as a directive to replicate the layout of the struct `Length` times. That includes replicating GC tracking information if the struct happens to contain managed pointers.

Unlike "filed0; field1; field2;..." approach, the resulting layout would be guaranteed to have the same order and packing details as elements of an array with element `[0]` matching the location of the single specified field.

Check failure on line 28 in docs/design/features/InlineArrayAttribute.md

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces [Expected: 0; Actual: 1]
Expand All @@ -33,7 +33,7 @@ That will allow the whole aggregate to be safely indexable/sliceable.
struct must not have explicit layout.

In cases when the attribute cannot have effect, it is an error case handled in the same way as the given platform handles cases when a type layout cannot be constructed.
Generally, it would be a `TypeLoadException` thrown at the time of layout construction.
Generally, it would be a `TypeLoadException` thrown at the time of layout construction.

### API Usage

Expand All @@ -53,19 +53,26 @@ struct MyArray<T>

The memory layout of a struct instance decorated with `InlineArray` attribute closely matches the layout of the element sequence of an array `T[]` with length == `Length`.
In particular (using the `MyArray<T>` example defined above):
* In unboxed form there is no object header or any other data before the first element.
* In unboxed form there is no object header or any other data before the first element.

Example: assuming the instance is not GC-movable, the following holds: `(byte*)*inst == (byte*)inst._element0`
* There is no additional padding between elements.

* There is no additional padding between elements.

Check failure on line 61 in docs/design/features/InlineArrayAttribute.md

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces [Expected: 0; Actual: 2]
Example: assuming the instance is not GC-movable and `Length > 1`, the following will yield a pointer to the second element: `(byte*)inst._element0 + sizeof(T)`
* The size of the entire instance is the size of its element type multiplied by the `Length`

* The size of the entire instance is the size of its element type multiplied by the `Length`

Example: the following holds: `sizeof(MyArray<T>) == Length * sizeof(T)`
* Just like with any other struct, the boxed form will contain the regular object header followed by an entire unboxed instance.

* Just like with any other struct, the boxed form will contain the regular object header followed by an entire unboxed instance.

Check failure on line 69 in docs/design/features/InlineArrayAttribute.md

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces [Expected: 0; Actual: 2]
Example: boxing/unboxing will result in exact copy on an entire instance: `object o = inst; MyArray<T> inst1copy = (MyArray<T>)o`

Type T can be a reference type and can contain managed references. The runtime will ensure that objects reachable through elements of an inline array instance can be accessed in a type-safe manner.

### Size limits for inline array instances.
The size limits for inline array instances will match the size limits of structs on a given runtime implementation.
The size limits for inline array instances will match the size limits of structs on a given runtime implementation.
Generally this is a very large size imposed by the type system implementation and is rarely reachable in actual applications due to other limitations such as max stack size, max size of an object, and similar.

Check failure on line 77 in docs/design/features/InlineArrayAttribute.md

View workflow job for this annotation

GitHub Actions / lint

Trailing spaces [Expected: 0; Actual: 5]
### Special note on scenario when the element is readonly.
Expand Down

0 comments on commit 05cf73a

Please sign in to comment.