[Mono-dev] [PATCH] more support for Google Native Client
Elijah Taylor
elijahtaylor at google.com
Tue Dec 21 15:12:53 EST 2010
Greetings Mono developers!
*[tl;dr very large patch for Native
Client<http://www.chromium.org/nativeclient> support
hosted here <https://github.com/elijahtaylor/mono>, would love feedback and
many eyes to look at it]
*
I'm back with another round of changes for supporting Google's Native Client
(NaCl), including support for amd64, JIT compilation, and Garbage
Collection. It's a large set of changes, forked on Dec 14 in github @
https://github.com/elijahtaylor/mono. I would appreciate feedback on these
changes... to facilitate this, I'll try to explain the largest changes by
feature (please email if clarification is needed):
*1) amd64 codegen*
- Rules located here:
http://www.chromium.org/nativeclient/design-documents/nacl-sfi-model-on-x86-64-systems
- Removed %r15 from register allocation, LMF save/restore, etc. (r15
is special and not modifiable by untrusted code)
- Sandbox all data access through membase address mode. If not %rsp
or %rbp relative, re-write as clearing upper 32-bits + memindex
addressing
- align functions, call sites
- Sandbox returns and all indirect jumps (need to be 32-byte aligned,
cleared upper 32-bits)
- Never omit frame pointer as general operations to rbp aren't allowed
*2) NaCl x86-64 is ILP32 (this is the largest set of changes and may make
some mono devs unhappy)*
- Set SIZEOF_REGISTER == 8 while sizeof(gpointer) == 4 for NaCl amd64 (we
can use 8-byte instructions, but pointers are 4-bytes)
- Re-write large portions of mini-amd64.c, tramp-amd64.c,
exceptions-amd64.c, mini.c, method-to-ir.c to use appropriate sizes
(SIZEOF_REGISTER, sizeof(gpointer), literal '8'). *These changes are
disruptive, but ultimately they should be more correct than what was there
before. *It's our opinion that these changes actually improve Mono
despite their impact.
- We only generate NaCl amd64 code from an ILP32 machine (either a 32-bit
application for AOT code, or NaCl runtime JIT), so we may not have caught
all of the [8 <--> SIZEOF_REGISTER] conversions, but we likely caught most
of the [sizeof(gpointer) <--> SIZEOF_REGISTER] and [8 <--> sizeof(gpointer)]
changes that are necessary.
- Change atomic operations and default pointer directives to use 32-bit
instructions (long instead of quad)
- Change default operations to use 32-bit integers/pointers (eg,
OP_LOAD_MEMBASE uses 4-bytes instead of 8)
*3) JIT support for NaCl*
- Since we're unable to emit code directly in its final executable
location, we instead:
- reserve a buffer on the heap
- create a hash table entry mapping the temp location and final
location
- modify all non-local patches relative to the final location
- request the NaCl runtime to install the created code in the final
location
- See mono/utils/mono-codeman.c changes for more detail.
- For every codeman *reserve*, we must add a codeman *validate* call in
order to install the method/trampoline/blob in the final location (as well
as validate it for NaCl, pad it out, etc)
- We don't delete or reuse code (we can, but it's icky and the benefits
don't outweigh the cost)
- Backpatching changed to use NaCl syscalls to modify existing dynamic
code
*4) GC support for NaCl (boehm only)*
- NaCl compiler and Mono code generator both emit instrumentation at GC
"safe points" (back branches and function prologs), for cooperative thread
parking (we're not allowed to send and receive signals)
- Added new opcode OP_NACL_GC_SAFE_POINT to handle mono instrumentation
- modified pthread_stop_world.c and pthread_support.c somewhat
extensively to support this new way of stopping the world
- wrapped pthread_exit because NaCl doesn't support pthread cleanup
functions
- added machine type NACL to libgc with machine specific defines
*5) Misc bug fixes (not NaCl-specific)*
- fix *x86_memindex_emit* when disp is 32-bit
- properly exclude code in libgc/gc_dlopen.c when DYNAMIC_LOADING not
defined
- properly exclude code based on DISABLE_SOCKETS by including config.h
before checking define
- clean up calculation of offset for amd64 AOT specific trampoline args
- fix bug in *mono_bblock_insert_before_ins* when trying to insert an
instruction to the beginning of an existing basic block.
- fix small typo bug in genmdesc.pl which kept amd64 from being able to
be a target of cross compiling
- fix struct passing in amd64 with sizeof(struct) == 16 when fields
aren't 8-byte aligned (eg, first field is 12 bytes, second field is 4
bytes), pass on stack instead of in registers (mini-amd64.c:*
add_valuetype*)
- add extra checks to mini-amd64.c:*mono_arch_emit_exceptions* to keep
exception/R4/R8 emitting from overflowing a buffer silently
- fix bugs in *new_codechunk* and *mono_code_manager_reserve_align* which
allowed unaligned code to be allocated.
I know we're close to holidays so I don't have any delusions that these
changes will get in by the end of the year :) Please feel free to pick
apart these changes and let me know if there are things that should be
changed.
-Elijah
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20101221/6daa2505/attachment.html
More information about the Mono-devel-list
mailing list