Skip to content

Instantly share code, notes, and snippets.

@breakin
Created September 11, 2015 21:05
Show Gist options
  • Save breakin/b33645209aefe0bee4dd to your computer and use it in GitHub Desktop.
Save breakin/b33645209aefe0bee4dd to your computer and use it in GitHub Desktop.
Description of "sandboxed" runtime environment
Think of a program as being put together from small "shaders". Each shader would correspond to a pure "function", or a task in a task-based system.
Each shader is compiled as a separate LLVM IR unit.
It could use clang for a subset of C/C++ with special requirements on the entry function.
In order to have big blocks and not too many pointers I think it would lend itself best towards data-oriented design ("batching") or something with memory arenas :)
When a shader is running in safe mode (debug, development etc) checks for all reads/writes are inserted into the LLVM IR so that each read/write is verified against bounds.
Once a shader it considered complete the extra bounds checks can be removed.
For example each shader can be given X input blocks with bounds (start, size).
Each write makes sure that no writes go into them, and no reads goes outside of those.
This would kinda enforce the same thing as locked page tables but quite likely with _lower_ performance.
When a shader is run in un-safe mode this extra information about bounds for all inputs can be removed.
A system outside of this would delegate to threads etc. That would be part of the runtime of the system.
It would know what blocks are safe/unsafe and do the right thing.
I haven't thought the outside system through at all. Basically we are executing a (possibly dynamic graph). But what does it amount to?
I realize that we need to have some thread primitives to store results safely in some instances when we want multiple tasks that say update a result atomically.
I'm envisioning this with runtime JIT of shaders and reload.
Hard part as always is when data structures change; a lot of data has to be purged.
Most things can be re-run while some can stay in memory (mesh X of format Y that didn't change is still the same so let it stay in memory).
I'm thinking that a datastructure (say struct) is also a "shader".
Whenever a data-format-shader changes all instances needst o be updated or re-generated.
For that to work each data format change needs to have a convertor function being written from previous version to new current version.
One version is ok, old convertors can be remembered for offline content. Or all data is in memory at all time anyway.
The scary thing is that 90% of the appeal of doing something like this is to get the runtime-ness and the build-system-less-ness that C++ lacks :)
@breakin
Copy link
Author

breakin commented Sep 11, 2015

Of course adding the bounds check IR might change optimization levels in a way such that the bounds check detects nothing, but the shader still perform something bad once optimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment