Back to index

plt-scheme  4.2.1
Classes | Defines | Typedefs | Functions | Variables
vm_osx.c File Reference
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <pthread.h>
#include "alloc_cache.c"

Go to the source code of this file.

Classes

struct  rep_msg
struct  exc_msg

Defines

#define TEST   0
#define ARCH_thread_state_t   i386_thread_state_t
#define ARCH_THREAD_STATE   i386_THREAD_STATE
#define ARCH_THREAD_STATE_COUNT   i386_THREAD_STATE_COUNT
#define page_size   vm_page_size

Typedefs

typedef struct rep_msg mach_reply_msg_t
typedef struct exc_msg mach_exc_msg_t

Functions

boolean_t exc_server (mach_msg_header_t *in, mach_msg_header_t *out)
static voidos_vm_alloc_pages (size_t len)
static void os_vm_free_pages (void *p, size_t len)
static void vm_protect_pages (void *p, size_t len, int writeable)
static unsigned long determine_max_heap_size ()
kern_return_t GC_catch_exception_raise_state (mach_port_t port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_cnt, thread_state_flavor_t *flavor, thread_state_t in_state, mach_msg_type_number_t is_cnt, thread_state_t out_state, mach_msg_type_number_t os_cnt)
kern_return_t catch_exception_raise_state (mach_port_t port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_cnt, thread_state_flavor_t *flavor, thread_state_t in_state, mach_msg_type_number_t is_cnt, thread_state_t out_state, mach_msg_type_number_t os_cnt)
kern_return_t GC_catch_exception_raise_state_identitity (mach_port_t port, mach_port_t thread_port, mach_port_t task_port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_count, thread_state_flavor_t *state_flavor, thread_state_t in_state, mach_msg_type_number_t in_state_count, thread_state_t out_state, mach_msg_type_number_t out_state_count)
kern_return_t catch_exception_raise_state_identitity (mach_port_t port, mach_port_t thread_port, mach_port_t task_port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_count, thread_state_flavor_t *state_flavor, thread_state_t in_state, mach_msg_type_number_t in_state_count, thread_state_t out_state, mach_msg_type_number_t out_state_count)
kern_return_t GC_catch_exception_raise (mach_port_t port, mach_port_t thread_port, mach_port_t task_port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_count)
kern_return_t catch_exception_raise (mach_port_t port, mach_port_t thread_port, mach_port_t task_port, exception_type_t exception_type, exception_data_t exception_data, mach_msg_type_number_t data_count)
void exception_thread (void)
static void macosx_init_exception_handler ()

Variables

static mach_port_t task_self = 0
static mach_port_t exc_port = 0

Class Documentation

struct rep_msg

Definition at line 49 of file vm_osx.c.

Class Members
mach_msg_header_t head
NDR_record_t NDR
kern_return_t ret_code
struct exc_msg

Definition at line 55 of file vm_osx.c.

Class Members
exception_data_t code
mach_msg_type_number_t code_cnt
exception_type_t exception
mach_msg_header_t head
mach_msg_body_t msgh_body
NDR_record_t NDR
char pad
mach_msg_port_descriptor_t task
mach_msg_port_descriptor_t thread

Define Documentation

#define ARCH_THREAD_STATE   i386_THREAD_STATE

Definition at line 44 of file vm_osx.c.

#define ARCH_THREAD_STATE_COUNT   i386_THREAD_STATE_COUNT

Definition at line 45 of file vm_osx.c.

#define ARCH_thread_state_t   i386_thread_state_t

Definition at line 43 of file vm_osx.c.

#define page_size   vm_page_size

Definition at line 74 of file vm_osx.c.

#define TEST   0

Definition at line 32 of file vm_osx.c.


Typedef Documentation


Function Documentation

kern_return_t catch_exception_raise ( mach_port_t  port,
mach_port_t  thread_port,
mach_port_t  task_port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_count 
)

Definition at line 221 of file vm_osx.c.

{
  return GC_catch_exception_raise(port, thread_port, task_port,
                                  exception_type, exception_data, data_count);
}

Here is the call graph for this function:

kern_return_t catch_exception_raise_state ( mach_port_t  port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_cnt,
thread_state_flavor_t *  flavor,
thread_state_t  in_state,
mach_msg_type_number_t  is_cnt,
thread_state_t  out_state,
mach_msg_type_number_t  os_cnt 
)

Definition at line 161 of file vm_osx.c.

{
  return GC_catch_exception_raise_state(port, exception_type, exception_data,
                                        data_cnt, flavor,
                                        in_state, is_cnt,
                                        out_state, os_cnt);
}

Here is the call graph for this function:

kern_return_t catch_exception_raise_state_identitity ( mach_port_t  port,
mach_port_t  thread_port,
mach_port_t  task_port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_count,
thread_state_flavor_t *  state_flavor,
thread_state_t  in_state,
mach_msg_type_number_t  in_state_count,
thread_state_t  out_state,
mach_msg_type_number_t  out_state_count 
)

Definition at line 188 of file vm_osx.c.

{
  return GC_catch_exception_raise_state_identitity(port, thread_port, task_port,
                                                   exception_type, exception_data,
                                                   data_count, state_flavor,
                                                   in_state, in_state_count,
                                                   out_state, out_state_count);
}

Here is the call graph for this function:

static unsigned long determine_max_heap_size ( void  ) [static]

Definition at line 131 of file vm_osx.c.

{
  struct rlimit rlim;

  getrlimit(RLIMIT_RSS, &rlim);
  return (rlim.rlim_cur == RLIM_INFINITY) ? (unsigned long)-1 : rlim.rlim_cur;
}
boolean_t exc_server ( mach_msg_header_t *  in,
mach_msg_header_t *  out 
)

Here is the caller graph for this function:

Definition at line 235 of file vm_osx.c.

{
  mach_msg_header_t *message;
  mach_msg_header_t *reply;
  kern_return_t retval;
  
  /* allocate the space for the message and reply */
  message = (mach_msg_header_t*)malloc(sizeof(mach_exc_msg_t));
  reply = (mach_msg_header_t*)malloc(sizeof(mach_reply_msg_t));
  /* do this loop forever */
  while(1) {
    /* block until we get an exception message */
    retval = mach_msg(message, MACH_RCV_MSG, 0, sizeof(mach_exc_msg_t), 
                    exc_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
    /* forward off the handling of this message */
    if(!exc_server(message, reply)) {
      GCPRINT(GCOUTF, "INTERNAL ERROR: exc_server() didn't like something\n");
      abort();
    }
    /* send the message back out to the thread */
    retval = mach_msg(reply, MACH_SEND_MSG, sizeof(mach_reply_msg_t), 0, 
                    MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

kern_return_t GC_catch_exception_raise ( mach_port_t  port,
mach_port_t  thread_port,
mach_port_t  task_port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_count 
)

Definition at line 201 of file vm_osx.c.

{
#if GENERATIONS
  /* kernel return value is in exception_data[0], faulting address in
     exception_data[1] */
  if(exception_data[0] == KERN_PROTECTION_FAILURE) {
    if (designate_modified((void*)exception_data[1]))
      return KERN_SUCCESS;
    else
      return KERN_FAILURE;
  } else 
#endif
    return KERN_FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

kern_return_t GC_catch_exception_raise_state ( mach_port_t  port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_cnt,
thread_state_flavor_t *  flavor,
thread_state_t  in_state,
mach_msg_type_number_t  is_cnt,
thread_state_t  out_state,
mach_msg_type_number_t  os_cnt 
)

Definition at line 148 of file vm_osx.c.

{
  return KERN_FAILURE;
}

Here is the caller graph for this function:

kern_return_t GC_catch_exception_raise_state_identitity ( mach_port_t  port,
mach_port_t  thread_port,
mach_port_t  task_port,
exception_type_t  exception_type,
exception_data_t  exception_data,
mach_msg_type_number_t  data_count,
thread_state_flavor_t *  state_flavor,
thread_state_t  in_state,
mach_msg_type_number_t  in_state_count,
thread_state_t  out_state,
mach_msg_type_number_t  out_state_count 
)

Definition at line 178 of file vm_osx.c.

{
  return KERN_FAILURE;
}

Here is the caller graph for this function:

static void macosx_init_exception_handler ( ) [static]

Definition at line 262 of file vm_osx.c.

{
  mach_port_t thread_self, exc_port_s;
  mach_msg_type_name_t type;
  kern_return_t retval;

  /* get ids for ourself */
  if(!task_self) task_self = mach_task_self();
  thread_self = mach_thread_self();

  /* allocate the port we're going to get exceptions on */
  retval = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, &exc_port);
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "Couldn't allocate exception port: %s\n", 
          mach_error_string(retval));
    abort();
  }

  /* extract out the send rights for that port, which the OS needs */
  retval = mach_port_extract_right(task_self, exc_port, MACH_MSG_TYPE_MAKE_SEND,
                               &exc_port_s, &type);
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "Couldn't extract send rights: %s\n", mach_error_string(retval));
    abort();
  }

  /* set the exception ports for this thread to the above */
  retval = thread_set_exception_ports(thread_self, EXC_MASK_BAD_ACCESS, 
                                  exc_port_s, EXCEPTION_DEFAULT, 
                                  ARCH_THREAD_STATE);
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval));
    abort();
  }

#ifdef PPC_HAND_ROLLED_THREAD 
  /* Old hand-rolled thread creation. pthread_create is fine for our
     purposes. */
 {
   /* set up the subthread */
   mach_port_t exc_thread;
   ARCH_thread_state_t *exc_thread_state;
   void *subthread_stack;

   retval = thread_create(task_self, &exc_thread);
   if(retval != KERN_SUCCESS) {
     GCPRINT(GCOUTF, "Couldn't create exception thread: %s\n", mach_error_string(retval));
     abort();
   }
   subthread_stack = (void*)malloc(page_size);
   subthread_stack += (page_size - C_ARGSAVE_LEN - C_RED_ZONE);
   exc_thread_state = (ARCH_thread_state_t*)malloc(sizeof(ARCH_thread_state_t));
   exc_thread_state->srr0 = (unsigned int)exception_thread;
   exc_thread_state->r1 = (unsigned int)subthread_stack;
   retval = thread_set_state(exc_thread, ARCH_THREAD_STATE,
                          (thread_state_t)exc_thread_state,
                          ARCH_THREAD_STATE_COUNT);
   if(retval != KERN_SUCCESS) {
     GCPRINT(GCOUTF, "Couldn't set subthread state: %s\n", mach_error_string(retval));
     abort();
   }
   retval = thread_resume(exc_thread);
   if(retval != KERN_SUCCESS) {
     GCPRINT(GCOUTF, "Couldn't resume subthread: %s\n", mach_error_string(retval));
     abort();
   }
 }
#else
 {
   pthread_t th;
   pthread_create(&th, NULL, (void *(*)(void *))exception_thread, NULL);
 }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* os_vm_alloc_pages ( size_t  len) [static]

Definition at line 79 of file vm_osx.c.

{
  kern_return_t retval;
  void *r;

  if(!task_self) task_self = mach_task_self();

  /* round up to the nearest page: */
  if(len & (page_size - 1))
    len += page_size - (len & (page_size - 1));

  retval = vm_allocate(task_self, (vm_address_t*)&r, len, TRUE);
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "Couldn't allocate memory: %s\n", mach_error_string(retval));
    abort();
  }

  return r;
}
static void os_vm_free_pages ( void p,
size_t  len 
) [static]

Definition at line 99 of file vm_osx.c.

{
  kern_return_t retval;

  retval = vm_deallocate(task_self, (vm_address_t)p, len);
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "WARNING: couldn't deallocate page %p: %s\n", p,
          mach_error_string(retval));
  }
}
static void vm_protect_pages ( void p,
size_t  len,
int  writeable 
) [static]

Definition at line 110 of file vm_osx.c.

{
  kern_return_t retval;

  if(len & (page_size - 1)) {
    len += page_size - (len & (page_size - 1));
  }

  retval = vm_protect(task_self, (vm_address_t)p, len, FALSE,
                    writeable ? VM_PROT_ALL 
                    : (VM_PROT_READ | VM_PROT_EXECUTE));
  if(retval != KERN_SUCCESS) {
    GCPRINT(GCOUTF, "WARNING: couldn't protect %li bytes of page %p%s\n",
          len, p, mach_error_string(retval));
  }
}

Variable Documentation

mach_port_t exc_port = 0 [static]

Definition at line 76 of file vm_osx.c.

mach_port_t task_self = 0 [static]

Definition at line 75 of file vm_osx.c.