[llvm-commits] Enable exceptions in JIT for Darwin

Evan Cheng evan.cheng at apple.com
Wed Aug 20 15:57:48 PDT 2008


Hi Nicolas,

Comments in line.

On Aug 19, 2008, at 8:04 AM, Nicolas Geoffray wrote:

> Dear all,
>
> Here's a patch that enables exception handling on Darwin with the  
> JIT. It's really ugly, it's a workaround to work with libgcc which  
> is doing crazy stuff when unwinding the stack. The __register_frame  
> function was sufficient enough for Linux, but unfortunately, the  
> code for darwin erases by default the registered frames. In a  
> perfect world, I think libgcc should be modified....
>
>
> I'd be totally OK if you don't want this patch in, as it's an ugly  
> workaround. I can move the patch to vmkit, and that would be fine by  
> me. However, this makes lli work out of the box with exceptions and  
> darwin, so it's still an improvement.
>
> Nicolas
> Index: lib/ExecutionEngine/JIT/JIT.cpp
> ===================================================================
> --- lib/ExecutionEngine/JIT/JIT.cpp	(revision 54920)
> +++ lib/ExecutionEngine/JIT/JIT.cpp	(working copy)
> @@ -64,10 +64,73 @@
>   }
> }
>
> +
> #if defined (__GNUC__)
> extern "C" void __register_frame(void*);
> -#endif
>
> +#if defined (__APPLE__)
> +struct object {
> +  void *pc_begin;
> +  void *tbase;
> +  void *dbase;
> +  void* real_begin;
> +
> +    union {
> +    struct {
> +      unsigned long sorted : 1;
> +      unsigned long from_array : 1;
> +      unsigned long mixed_encoding : 1;
> +      unsigned long encoding : 8;
> +      unsigned long count : 21;
> +    } b;
> +    size_t i;
> +  } s;

Please pick more descriptive names than object, etc. Also, please try  
to match the naming convention used in the file. Some documentation is  
definitely welcome. :-)
>
> +
> +  // Be pessimistic, include this field even if GCC
> +  // may not have it.
> +  char *fde_end;
> +
> +  struct object *next;
> +};
> +
> +extern "C" void _keymgr_set_and_unlock_processwide_ptr (int, void *);
> +extern "C" void *_keymgr_get_and_lock_processwide_ptr (int);
> +#define KEYMGR_GCC3_DW2_OBJ_LIST        302     /* Dwarf2 object  
> list  */
> +
> +struct km_object_info {
> +  struct object* seen_objects;
> +  struct object* unseen_objects;
> +  unsigned spare[2];
> +};
> +
> +extern "C" void darwin_register_frame(void* begin) {
> +  struct km_object_info* the_obj_info = (struct km_object_info*)
> +    _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
> +
> +  struct object* ob = (struct object*)malloc(sizeof(struct object));

Who frees this?

>
> +  ob->pc_begin = (void *)-1;
> +  ob->tbase = 0;
> +  ob->dbase = 0;
> +  ob->real_begin = begin;
> +  ob->s.i = 0;
> +  //ob->s.b.encoding = DW_EH_PE_omit;

Why is this commented out?

>
> +  ob->s.b.encoding = 0xff;
> +
> +  // Put the info on both places, as libgcc uses the first or the
> +  // the second field.
> +  ob->fde_end = (char*)the_obj_info->unseen_objects;
> +  ob->next = (struct object*)the_obj_info->unseen_objects;

Are the casting necessary? Why not just define the types correctly.

>
> +
> +  the_obj_info->unseen_objects = ob;
> +
> +  _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
> +                                          the_obj_info);
> +
> +}

Function level documentation please.

Thanks!

Evan

>
> +
> +#endif // __APPLE__
> +#endif // __GNUC__
> +
> /// createJIT - This is the factory method for creating a JIT for  
> the current
> /// machine, it does not fall back to the interpreter.  This takes  
> ownership
> /// of the module provider.
> @@ -108,8 +171,20 @@
>
>   // Register routine for informing unwinding runtime about new EH  
> frames
> #if defined(__GNUC__)
> +#if defined(__APPLE__)
> +  struct km_object_info* the_obj_info = (struct km_object_info*)
> +    _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
> +
> +  if (!the_obj_info) {
> +    the_obj_info = (km_object_info*)malloc(sizeof(struct  
> km_object_info));
> +    _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
> +                                            the_obj_info);
> +  }
> +  InstallExceptionTableRegister(darwin_register_frame);
> +#else
>   InstallExceptionTableRegister(__register_frame);
> -#endif
> +#endif // __APPLE__
> +#endif // __GNUC__
>
>
>   // Initialize passes.
>   PM.doInitialization();
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list