diff --git a/shotgun/lib/baker.c b/shotgun/lib/baker.c
index 1c16e44..4e8e977 100644
--- a/shotgun/lib/baker.c
+++ b/shotgun/lib/baker.c
@@ -9,8 +9,13 @@
 #include "shotgun/lib/baker.h"
 #include "shotgun/lib/tuple.h"

+/* how many times object should be traced before tenuring */
 #define DEFAULT_TENURE_AGE 6

+/* 
+creates and initializes new copying GC instance
+it start with space A as "from" space and B as "to" space
+*/
 baker_gc baker_gc_new(int size) {
   baker_gc g;
   g = (baker_gc)calloc(1, sizeof(struct baker_gc_struct));
@@ -29,27 +34,32 @@ baker_gc baker_gc_new(int size) {
   return g;
 }

+/* prints various garbage collector information */
 void baker_gc_describe(baker_gc g) {
-  printf("Size:    %x (%d)\n", (unsigned int)g->current->size, (int)g->current->size);
-  printf("Current: %p => %p\n", (void*)g->current->address, (void*)g->current->last);
-  printf("Next:    %p => %p\n", (void*)g->next->address, (void*)g->next->last);
-  printf("RS Size: %zd\n", ptr_array_length(g->remember_set));
+  printf("Size :    %x (%d)\n", (unsigned int)g->current->size, (int)g->current->size);
+  printf("Current (\"from\") heap space address: %p => %p\n", (void*)g->current->address, (void*)g->current->last);
+  printf("Next (\"to\") heap space address:    %p => %p\n", (void*)g->next->address, (void*)g->next->last);
+  printf("Remember set size: %zd\n", ptr_array_length(g->remember_set));
 }

+/* baker GC uses two heap spaces of the same size */
 int baker_gc_memory_allocated(baker_gc g) {
   return g->current->size * 2;
 }

+/* returns how much memory is used by "from" heap space */
 int baker_gc_memory_in_use(baker_gc g) {
   return g->current->current - g->current->address;
 }

+/* enlarges "to" space of the heap (where new objects are allocated) by value of sz */
 int baker_gc_enlarge_next(baker_gc g, size_t sz) {
   rheap h;
   h = heap_new(sz);
   return baker_gc_set_next(g, h);
 }

+/* sets "to" heap space, always returns TRUE */
 int baker_gc_set_next(baker_gc g, rheap h) {
   if(g->next == g->space_a) {
     g->space_a = h;
@@ -60,21 +70,24 @@ int baker_gc_set_next(baker_gc g, rheap h) {
   return TRUE;
 }

+/* gets start address of current "from" heap space */
 address baker_gc_start_address(baker_gc g) {
   return g->current->address;
 }

+/* total baker GC memory usage */
 size_t baker_gc_used(baker_gc g) {
   return g->used;
 }

+/* reset memory usage info */
 void baker_gc_reset_used(baker_gc g) {
   g->used = 0;
 }

+/* performs flip operation on heap spaces */
 int baker_gc_swap(baker_gc g) {
   rheap tmp;
-  
   tmp = g->current;
   g->current = g->next;
   g->next = tmp;
@@ -83,8 +96,6 @@ int baker_gc_swap(baker_gc g) {
   g->last_end =   (char*)tmp->current;

   heap_reset(tmp);
-  /* Reset used to the what the current has used. */
-  /* g->used = (uintptr_t)g->current->current - (uintptr_t)g->current->address; */
   return TRUE;
 }

@@ -95,6 +106,7 @@ int baker_gc_destroy(baker_gc g) {
   return TRUE;
 }

+/* sets forwarding pointer on object */
 void baker_gc_set_forwarding_address(OBJECT obj, OBJECT dest) {
   SET_FORWARDED(obj);
   obj->klass = dest;
@@ -118,25 +130,6 @@ OBJECT baker_gc_forwarded_object(OBJECT obj) {
   }                                           \
   ret; })

-/*
-static inline OBJECT baker_gc_maybe_mutate(baker_gc g, OBJECT iobj) {
-  OBJECT ret;
-
-  if(baker_gc_forwarded_p(iobj)) {
-    ret = baker_gc_forwarded_object(iobj);
-  } else if(baker_gc_contains_p(g, iobj)) {
-    ret = baker_gc_mutate_object(g, iobj);
-  } else {
-    ret = iobj;
-  }
-  
-  // assert(baker_gc_contains_spill_p(g, ret));
-    
-  CHECK_PTR(ret);
-  
-  return ret;
-}
-*/

 int _object_stores_bytes(OBJECT self);
 static int depth = 0;
@@ -191,11 +184,12 @@ static void _mutate_references(STATE, baker_gc g, OBJECT iobj) {
   //printf("%d: Mutating references of %p\n", depth, iobj);

   if(!_object_stores_bytes(iobj)) {
+		/* follow object field references and mutate them */
     fields = NUM_FIELDS(iobj);
     for(i = 0; i < fields; i++) {
       tmp = NTH_FIELD(iobj, i);
       if(!REFERENCE_P(tmp)) continue;
-
+			/* TODO: duplicated in other places: extract to separate function? */
       if(FORWARDED_P(tmp)) {
         mut = tmp->klass;
       } else if(heap_contains_p(g->current, tmp) || heap_contains_p(state->om->contexts, tmp)) {
@@ -203,8 +197,9 @@ static void _mutate_references(STATE, baker_gc g, OBJECT iobj) {
       } else {
         mut = tmp;
       }
-        
+      /* update field reference */
       SET_FIELD_DIRECT(iobj, i, mut);
+			/* update remember set, set "remembered" flag on iobj */
       RUN_WB2(om, iobj, mut);
     }
   } else {
@@ -341,8 +336,6 @@ void baker_gc_mutate_context(STATE, baker_gc g, OBJECT iobj, int shifted, int to
     assert(NIL_P(fc->sender) || fc->sender->obj_type == MContextType || fc->sender->obj_type == BContextType);
   }

-  
-  
   fc_mutate(method);
   fc_mutate(block);
   fc_mutate(literals);
@@ -418,6 +411,7 @@ OBJECT baker_gc_mutate_object(STATE, baker_gc g, OBJECT obj) {
       xassert(obj->klass != Qnil);
       dest = heap_copy_object(g->next, obj);
       g->used++;
+			/* when object is moved to new heap forwarded pointer is left in new generation ("from") heap */
       baker_gc_set_forwarding_address(obj, dest);
       if(!obj->ForeverYoung) INCREMENT_AGE(dest);
       if(obj->obj_type == WrapsStructType) MARK_WRAPPED_STRUCT(obj);
@@ -480,10 +474,11 @@ unsigned int baker_gc_collect(STATE, baker_gc g, ptr_array roots) {
   size_t i, sz;
   OBJECT tmp, root;
   struct method_cache *end, *ent;
+  /* rs for remember set */
   ptr_array rs;

   saved_contexts = 0;
-  
+  /* increase number of GC cycles passed */
   g->num_collection++;

   /* empty it out. */
@@ -491,8 +486,7 @@ unsigned int baker_gc_collect(STATE, baker_gc g, ptr_array roots) {
   ptr_array_clear(g->tenured_objects);

   // printf("Running garbage collector...\n");
-  
-  
+  /* start tracing from root set */
   sz = ptr_array_length(roots);
   for(i = 0; i < sz; i++) {
     root = (OBJECT)(ptr_array_get_index(roots, i));
@@ -522,7 +516,7 @@ unsigned int baker_gc_collect(STATE, baker_gc g, ptr_array roots) {
   }


-  /* Now the stack. */
+  /* Now the stack, sp is for stack pointer. */
   OBJECT *sp;

   sp = state->current_stack;
diff --git a/shotgun/lib/baker.h b/shotgun/lib/baker.h
index 15dfe90..90ae1ea 100644
--- a/shotgun/lib/baker.h
+++ b/shotgun/lib/baker.h
@@ -3,6 +3,38 @@

 #include "shotgun/lib/heap.h"

+/*
+ Rubinius uses Henry Baker's generational GC that divides heap into spaces: 
+ notably "from" space and "to" space. After tracing live objects are 
+ moved from "from" space to "to"
+ space leaving forwarding address that points to new object location in "to"
+ space at the old object location. When object moved (also referenced as
+ "evacuated") it may point to objects in "from" heap space. So these
+ referenced objects are copied as well and pointers are updates.
+ This is called scavenging. Then "from" space can be reused and
+ heap spaces flipped.
+
+ Objects tenured to old generation after surviving certain number of
+ GC cycles.
+ 
+ Pros of this alrogithm is that it does not stop the world for too long
+ and leaves much much less heap fragmentation than naive mark and sweep
+ algorithm.
+ 
+ Overview of Baker's algorithm is available online at
+ http://web.media.mit.edu/~lieber/Lieberary/GC/Realtime/Realtime.html
+
+ space_a and space_b are two heap spaces used
+ current is "from" heap space
+ next is "to" heap space
+ used is how much memory overall heap uses 
+ (offset = current heap peak position - heap bottom)
+
+ tenure_age is how many times object should be traced before 
+ tenuring: may vary between GC instances
+ num_collection is how many GC cycles passed
+ 
+*/
 struct baker_gc_struct {
   rheap space_a;
   rheap space_b;
diff --git a/shotgun/lib/cpu.c b/shotgun/lib/cpu.c
index 2126070..fcc4e17 100644
--- a/shotgun/lib/cpu.c
+++ b/shotgun/lib/cpu.c
@@ -66,6 +66,7 @@ OBJECT cpu_scope_pop(STATE, cpu c) {
   return c->current_scope;
 }

+/* initializes VM core: from global methods, main routine to current scope, thread and so forth */
 void cpu_initialize_context(STATE, cpu c) {
   c->active_context = Qnil;
   c->depth = 0;
diff --git a/shotgun/lib/cpu.h b/shotgun/lib/cpu.h
index db833f3..a28918a 100644
--- a/shotgun/lib/cpu.h
+++ b/shotgun/lib/cpu.h
@@ -27,7 +27,30 @@
 #define BS_JUMP 2

 #define CTX_FLAG_NO_LONG_RETURN (1<<0)
+/*
+literals: literals frame

+literal frame stores items that cannot be referenced 
+by bytecodes, such as class variables, most of 
+literal constants (numbers, strings, symbols, method call sites) and 
+message selectors other than special
+TODO: describe those specials in Rubinius
+
+locals: local variables frame
+
+local variables frame stores compiled method's 
+local variables
+
+argcount: method's arity
+TODO: investigate and document negative arities
+
+self: message receiver
+ip  : instruction pointer, position of next bytecode to be executed in CompiledMethod
+sp  : stack pointer, current position on the stack
+fp  : execution frame (current context) pointer
+
+method_module: module or class that holds the method
+*/
 #define CPU_REGISTERS OBJECT sender; \
   OBJECT block; \
   OBJECT method; \
@@ -46,11 +69,12 @@
   unsigned int sp; \
   unsigned int fp;

+/* optimisation: context with direct access to size */
 struct fast_context {
   CPU_REGISTERS
   unsigned int size;
 };
-
+/* fast context treats OBJECT as series of bytes instead of normal object */
 #define FASTCTX(ctx) ((struct fast_context*)BYTES_OF(ctx))

 /* 1Meg of stack */
@@ -62,6 +86,27 @@ struct fast_context {
 #define TASK_SET_FLAG(task, flag) (task->flags |= flag)
 #define TASK_CLEAR_FLAG(task, flag) (task->flags ^= flag)

+/* 
+ * stack_slave: when tasks are duplicated they share the same stack (TODO: clarify)
+ * cache_index is deprecated after SendSite introduction
+ * exception 
+ * stack_top: pointer to top of the stack
+ * stack_size: obviously the size of the stack
+ * enclosing_class 
+ * active_context represents current state of the interpreter
+ * home_context: home context of BlockContext is MethodContext which CompiledMethod contained the block
+ * main 
+ * paths 
+ * depth: stack depth
+ * current_scope: current visibility scope
+ * ip_ptr: instruction pointer, position of next bytecode to be executed in CompiledMethod
+ * sp_ptr: stack pointer, current position on the stack
+ * call_flags 
+ * debug_channel
+ * flags 
+ * control_channel
+ * blockargs is list of arguments passed to the block of executed method
+ */
 #define CPU_TASK_REGISTERS long int args; \
   unsigned long int stack_slave; \
   long int cache_index; \
@@ -85,14 +130,41 @@ struct cpu_task_shared {
   CPU_TASK_REGISTERS;
 };

+/*
+ Each Shotgun task maintains an operand stack (Shotgun is a 
+ stack-based VM though it uses so called spaghetti stack) 
+ and a reference to the current execution context. 
+ Tasks are very similar to threads, but lack pre-emption or 
+ scheduling. In practice, they are similar to Ruby 1.9 
+ fibres, although unlike fibres, there is currently no way 
+ to co-operatively multi-task (or yield to a co-routine) 
+ using Rubinius tasks.
+  
+ active     : true for active tasks
+ saved_errno: error code saved when the trouble strikes
+*/
 struct cpu_task {
   CPU_TASK_REGISTERS;
   unsigned int active;
   int saved_errno;
 };

+/*
+ Normal registers are saved and restored per new method call.
+ Task registers are saved and restored when tasks are switched.
+
+ self  : current object which self pseudo variable points to
+ sender: message sender
+ locals: list of local variables of the scope
+ IP    : instruction pointer
+ SP    : stack pointer
+ FP    : frame pointer
+
+ these point to different locations on the stack
+ see http://en.wikipedia.org/wiki/Call_stack for more details
+ 
+ */
 struct rubinius_cpu {
-  /* Normal registers are saved and restored per new method call . */
   OBJECT self, sender;
   OBJECT locals;
   IP_TYPE *data;
@@ -108,7 +180,6 @@ struct rubinius_cpu {
   OBJECT current_thread, main_thread;
   int in_primitive;

-  /* Task registers are saved and restored when tasks are switched. */
   CPU_TASK_REGISTERS;
 };

diff --git a/shotgun/lib/environment.c b/shotgun/lib/environment.c
index 64d0942..904bc8b 100644
--- a/shotgun/lib/environment.c
+++ b/shotgun/lib/environment.c
@@ -182,6 +182,7 @@ int environment_load_machine(environment e, machine m) {
   return TRUE;
 }

+/* NOTE: this duplicates rubinius_global from environment.h */
 struct thread_args {
   environment e;
   machine m;
diff --git a/shotgun/lib/environment.h b/shotgun/lib/environment.h
index ee781d6..685ae80 100644
--- a/shotgun/lib/environment.h
+++ b/shotgun/lib/environment.h
@@ -4,6 +4,17 @@
 #include 
 #include "shotgun/lib/machine.h"

+/*
+ Rubinius environment stores load paths,
+ platform configuration, list of spawned machines,
+ event loop
+ and synchronization mutex.
+ 
+ One environment is automatically created on
+ VM start.
+
+ Each environment lives in it's own pthread
+ */
 struct rubinius_environment {
   pthread_mutex_t mutex;
   struct hashtable *machines;
@@ -12,6 +23,7 @@ struct rubinius_environment {
   char *platform_path;
   char *core_path;
   char *loader_path;
+
   int machine_id;

   struct hashtable *messages;
diff --git a/shotgun/lib/hash.c b/shotgun/lib/hash.c
index 4e6d5c6..cca840d 100644
--- a/shotgun/lib/hash.c
+++ b/shotgun/lib/hash.c
@@ -191,7 +191,7 @@ OBJECT hash_add(STATE, OBJECT h, unsigned int hsh, OBJECT key, OBJECT data) {

   // printf("hash_add: adding %od\n",hsh);
   entry = hash_find_entry(state, h, hsh);
-
+ 
   if(RTEST(entry)) {
     tuple_put(state, entry, 2, data);
     return data;
@@ -207,6 +207,7 @@ OBJECT hash_add(STATE, OBJECT h, unsigned int hsh, OBJECT key, OBJECT data) {
   return data;
 }

+/* Sets key/value pair to hash */
 OBJECT hash_set(STATE, OBJECT hash, OBJECT key, OBJECT val) {
   return hash_add(state, hash, object_hash_int(state, key), key, val);
 }
diff --git a/shotgun/lib/heap.c b/shotgun/lib/heap.c
index 2a2b45a..5768ae1 100644
--- a/shotgun/lib/heap.c
+++ b/shotgun/lib/heap.c
@@ -34,19 +34,21 @@ int heap_allocate_memory(rheap h) {
   h->last = (void*)((uintptr_t)h->address + h->size - 1);
   return heap_reset(h);
 }
-
+/* make current and scan position point to heap bottom */
 int heap_reset(rheap h) {
   h->current = h->address;
   h->scan = h->current;
   return TRUE;
 }
-
+n
+/* heap allocation predicate */
 int heap_allocated_p(rheap h) {
   return h->address > 0;
 }

 #ifndef FAST_HEAP

+/* whether given address is between heap bottom and heap top */
 int heap_contains_p(rheap h, address addr) {

   if(addr < h->address) return FALSE;
@@ -65,6 +67,7 @@ address heap_allocate(rheap h, int size) {
   return addr;
 }

+/* whether SIZE bytes fit the heap without calling for heap enlarge */
 int heap_enough_space_p(rheap h, int size) {
   if (size < 0) abort();
   if(h->current + size > h->last + 1) return FALSE;
@@ -73,6 +76,7 @@ int heap_enough_space_p(rheap h, int size) {

 #endif

+/* whether number of fields fit the heap without calling for heap enlarge */
 int heap_enough_fields_p(rheap h, int fields) {
   int size;

@@ -85,6 +89,7 @@ int heap_enough_fields_p(rheap h, int fields) {
 OBJECT heap_copy_object(rheap h, OBJECT obj) {
   address out;
   int size;
+  /* avoid copying what's already on the heap */
   if(heap_contains_p(h, obj)) return obj;
   size = SIZE_IN_BYTES(obj);

@@ -94,7 +99,11 @@ OBJECT heap_copy_object(rheap h, OBJECT obj) {
   return (OBJECT)out;
 }

-/* Functions to support the cheney scan algorithm. */
+/* 
+ * Shotgun uses very slight variation Cheney's algorithm for young generation.
+ * 
+ * See http://en.wikipedia.org/wiki/Cheney_algorithm
+ */

 OBJECT heap_next_object(rheap h) {
   return (OBJECT)(h->current);
@@ -104,6 +113,7 @@ int heap_fully_scanned_p(rheap h) {
   return h->scan == h->current;
 }

+/* makes scan point to next object location */
 OBJECT heap_next_unscanned(rheap h) {
   OBJECT obj;
   if(heap_fully_scanned_p(h)) return 0;
diff --git a/shotgun/lib/heap.h b/shotgun/lib/heap.h
index 08265fb..ad5c48e 100644
--- a/shotgun/lib/heap.h
+++ b/shotgun/lib/heap.h
@@ -3,6 +3,12 @@

 typedef void* address;

+/*
+ address : lower heap bound address
+ curret  : current tip of the heap
+ last    : upper heap bound address
+ scan    : GC scanner position
+ */
 struct heap {
   size_t size;
   address address;
@@ -27,6 +33,7 @@ int heap_fully_scanned_p(rheap h);
 OBJECT heap_next_unscanned(rheap h);
 int heap_enough_fields_p(rheap h, int fields);

+/* controls fast heap allocation using inline functions on and off */
 #define FAST_HEAP 1

 #ifdef FAST_HEAP
@@ -68,4 +75,3 @@ unsigned int heap_enough_space_p(rheap h, unsigned int size);
 #endif

 #endif
-
diff --git a/shotgun/lib/machine.c b/shotgun/lib/machine.c
index 1775975..a67cc8a 100644
--- a/shotgun/lib/machine.c
+++ b/shotgun/lib/machine.c
@@ -32,32 +32,39 @@

 static int _recursive_reporting = 0;

+/* use this to convert symbol into Ruby string
+ * st is for state
+ */
 #define SYM2STR(st, sym) string_byte_address(st, rbs_symbol_to_string(st, sym))

+/* 
+ outputs limited number of lines of VM call stack
+ current active machine used unless explicitly given
+*/
 void machine_print_callstack_limited(machine m, int maxlev) {
   OBJECT context, tmp;
   const char *modname, *methname, *filename;
   struct fast_context *fc;
-
   if(!m) m = current_machine;
-
   context = m->c->active_context;

+  /* flush stack and instruction pointers */
   cpu_flush_ip(m->c);
   cpu_flush_sp(m->c);

   FASTCTX(context)->ip = m->c->ip;
-  
+
   while(RTEST(context) && maxlev--) {
+    
     methctx_reference(m->s, context);
     fc = FASTCTX(context);
-
+    
     if(fc->method_module && RTEST(fc->method_module)) {
       modname = SYM2STR(m->s, module_get_name(fc->method_module));
     } else {
       modname = "";
     }
-
+    
     if(fc->type == FASTCTX_BLOCK) {
       methname = "";
     } else if(fc->name && RTEST(fc->name)) {
@@ -81,24 +88,29 @@ void machine_print_callstack_limited(machine m, int maxlev) {
       filename = "";
     }

+    /* execution logging */
     fprintf(stderr, "%10p %s#%s+%d in %s:%d\n",
       (void*)context, modname, methname,
       fc->ip,
       filename,
       cpu_ip2line(m->s, fc->method, fc->ip)
     );
+    /* transfer control back to message sender */
     context = fc->sender;
   }
 }

+/* prints the whole VM call stack */
 void machine_print_callstack(machine m) {
     machine_print_callstack_limited(m, -1);
 }

+/* prints of given VM stack trace */
 void machine_print_stack(machine m) {
   unsigned int i, start, end;
   cpu_flush_sp(m->c);
   i = m->c->sp;
+  /* TODO: document these magic numbers */
   start = (i < 5 ? 0 : i - 5);
   end =   (i + 5 > m->c->stack_size) ? m->c->stack_size : i + 5;
   for(i = start; i < end; i++) {
@@ -112,6 +124,7 @@ void machine_print_stack(machine m) {

 }

+/* prints VM registers content */
 void machine_print_registers(machine m) {
   cpu_flush_sp(m->c);
   cpu_flush_ip(m->c);
@@ -123,6 +136,7 @@ void machine_print_registers(machine m) {
   }
 }

+/* handles error reporting */
 void _machine_error_reporter(int sig, siginfo_t *info, void *ctx) {
   const char *signame;
   rni_context *rni_ctx;
@@ -130,11 +144,13 @@ void _machine_error_reporter(int sig, siginfo_t *info, void *ctx) {

   /* See if the error happened during the running of a C function.
      If so, we raise an exception about the error. */
+  /* Grab Subtend context first */
   rni_ctx = subtend_retrieve_context();
   if(rni_ctx->nmc && rni_ctx->nmc->system_set) {
     /* TODO: generate the C backtrace as a string array and pass it
        via the nmc or global_context so that the exception can include
        it. */
+    /* Set RNI faulting instruction and switch to system context */
     rni_ctx->fault_address = info->si_addr;
     rni_ctx->nmc->jump_val = SEGFAULT_DETECTED;
     setcontext(&rni_ctx->nmc->system);
@@ -192,21 +208,29 @@ void _machine_error_reporter(int sig, siginfo_t *info, void *ctx) {
   exit(-2);
 }

+/* initialize signals handling and errors reporting */
 void machine_setup_signals(machine m) {
-        m->error_report.sa_sigaction = _machine_error_reporter;
-        sigemptyset(&m->error_report.sa_mask);
-        m->error_report.sa_flags = SA_SIGINFO;
-        sigaction(SIGSEGV, &m->error_report, NULL);
-        sigaction(SIGBUS, &m->error_report, NULL);
-        sigaction(SIGABRT, &m->error_report, NULL);
+  m->error_report.sa_sigaction = _machine_error_reporter;
+  sigemptyset(&m->error_report.sa_mask);
+  m->error_report.sa_flags = SA_SIGINFO;
+  sigaction(SIGSEGV, &m->error_report, NULL);
+  sigaction(SIGBUS, &m->error_report, NULL);
+  sigaction(SIGABRT, &m->error_report, NULL);
 }

+/* initialize event base used by libevent */
 static void machine_setup_events(machine m) {
   /* libev will not "autodetect" kqueue because it is broken on darwin */
   m->s->event_base = ev_loop_new(EVFLAG_FORKCHECK);
   m->s->thread_infos = NULL;
 }

+/* Creates and initializes Rubinius VM.
+ * Sets up the VM CPU, machine message buckets,
+ * subtend, event handling, context and state, 
+ * universe and everything.
+ * 
+ */
 machine machine_new(environment e) {
   machine m;
   int pipes[2];
@@ -217,24 +241,23 @@ machine machine_new(environment e) {
   m->sub = 0;
   pipe(pipes);

-  /* Setup pipes used for message notification. */
+
   m->message_read_fd =  pipes[0];
   m->message_write_fd = pipes[1];
-
   m->s = rubinius_state_new();
   m->c = cpu_new(m->s);
-  /* Initialize the instruction addresses. */
   cpu_run(m->s, m->c, TRUE);
   m->c->ip_ptr = &m->s->external_ip;

   machine_setup_signals(m);
   machine_setup_events(m);
+  
   cpu_initialize(m->s, m->c);
   cpu_bootstrap(m->s);
   subtend_setup(m->s);
   cpu_setup_top_scope(m->s, m->c);
   cpu_initialize_context(m->s, m->c);
-
+  /* make MAIN Ruby contant point to main routine of the application*/
   machine_set_const(m, "MAIN", m->c->main);
   cpu_task_configure_preemption(m->s);
   environment_add_machine(e, m);
@@ -250,14 +273,18 @@ void machine_destroy(machine m) {
   free(m);
 }

+/* handles errors gracefully */
 void machine_handle_fire(int kind) {
+  /* store type of violation */
   current_machine->g_access_violation = kind;
+  /* then switch to special context to handle it gracefully */
   setcontext(¤t_machine->g_firesuit);
 }

+/* handles type errors in the VM: error message and type are preserved */
 void machine_handle_type_error(OBJECT obj, const char *message) {
   current_machine->g_firesuit_message = strdup(message);
-
+  
   if(FIXNUM_P(obj)) {
     current_machine->g_firesuit_arg = FixnumType;
   } else if(SYMBOL_P(obj)) {
@@ -269,10 +296,10 @@ void machine_handle_type_error(OBJECT obj, const char *message) {
   } else {
     current_machine->g_firesuit_arg = 0;
   }
-
   machine_handle_fire(FIRE_TYPE);
 }

+/* handles failed assertions in the VM code */
 void machine_handle_assert(const char *reason, const char *file, int line) {
   fprintf(stderr, "VM Assertion: %s (%s:%d)\n", reason, file, line);

@@ -284,6 +311,7 @@ void machine_handle_assert(const char *reason, const char *file, int line) {
   setcontext(¤t_machine->g_firesuit);
 }

+/* returns unmarshalled file */
 OBJECT machine_load_file(machine m, const char *path) {
   return cpu_unmarshal_file(m->s, path, 0);
 }
@@ -306,6 +334,9 @@ void machine_show_exception(machine m, OBJECT exc) {
   puts("");
 }

+/* initializes VM globals, clears instruction pointer, op, firesuit and so forth.
+   returns FALSE on exception
+ */
 int machine_run(machine m) {
   cpu_run(m->s, m->c, 0);
   m->c->ip_ptr = &m->s->external_ip;
@@ -318,6 +349,7 @@ int machine_run(machine m) {
   return TRUE;
 }

+/* loads and executes a script. Returns FALSE if load failed. */
 int machine_run_file(machine m, const char *path) {
   OBJECT meth;
   int out;
@@ -325,13 +357,14 @@ int machine_run_file(machine m, const char *path) {
   if(m->s->excessive_tracing) {
     printf("[ Loading file %s]\n", path);
   }
-
+  
   meth = machine_load_file(m, path);
   if(!RTEST(meth)) {
     printf("Unable to load '%s'.\n", path);
     return FALSE;
   }
- 
+  
+  /* re-init cpu stack */
   m->c->depth = 0;
   cpu_stack_push(m->s, m->c, meth, FALSE);
   cpu_run_script(m->s, m->c, meth);
@@ -342,16 +375,19 @@ int machine_run_file(machine m, const char *path) {
   return out;
 }

+/* sets contstand under given module or class */
 void machine_set_const_under(machine m, const char *str, OBJECT val, OBJECT under) {
   OBJECT tbl;
   tbl = module_get_constants(under);
   lookuptable_store(m->s, tbl, string_new(m->s, str), val);
 }

+/* Sets constant under Object class */
 void machine_set_const(machine m, const char *str, OBJECT val) {
   machine_set_const_under(m, str, val, m->s->global->object);
 }

+/* stores Ruby VM launch arguments */
 void machine_save_args(machine m, int argc, char **argv) {
   char **na;
   na = calloc(argc, sizeof(char*));
@@ -363,6 +399,7 @@ void machine_save_args(machine m, int argc, char **argv) {
   machine_setup_argv(m, argc, argv);
 }

+/* Sets standard IO streams (stdin, stdout, stderr) to Ruby constants */
 void machine_setup_standard_io(machine m) {
   machine_set_const(m, "STDIN", io_new(m->s, 0, "r"));
   machine_set_const(m, "STDOUT", io_new(m->s, 1, "w"));
@@ -391,6 +428,7 @@ int *machine_setup_piped_io(machine m) {
   return pipes;
 }

+/* sets up RUBY_BIN_PATH Ruby constant and VM interpreter name */
 void machine_setup_ruby(machine m, char *name) {
   char buf[MAXPATHLEN];
   char wd[MAXPATHLEN];
@@ -407,6 +445,7 @@ void machine_setup_ruby(machine m, char *name) {
   m->interpreter = strdup(name);
 }

+/* sets ARGV and ARG0 Ruby constants */
 void machine_setup_argv(machine m, int argc, char **argv) {
   OBJECT ary;
   int i;
@@ -421,6 +460,7 @@ void machine_setup_argv(machine m, int argc, char **argv) {
   machine_set_const(m, "ARGV", ary);
 }

+/* utility: checks whether string contains only digits */
 int is_number(char *str) {
   while(*str) {
     if(!isdigit(*str)) return FALSE;
@@ -430,6 +470,7 @@ int is_number(char *str) {
   return TRUE;
 }

+/* utility: strips trailing non-alnum chars from string */
 static char *trim_str(char *str) {
   int i;
   while(*str && !isalnum(*str)) str++;
@@ -508,19 +549,22 @@ void machine_parse_config_file(machine m, const char *path) {
 }

 void machine_migrate_config(machine m) {
+  /* hash table iterator */
   struct hashtable_itr iter;
   rstate state = m->s;
-  
+
+  /* initialize new hash for environment global configuration */  
   m->s->global->config = hash_new_sized(m->s, 500);
-    
+
   if(hashtable_count(m->s->config) > 0) {
-  
     hashtable_iterator_init(&iter, m->s->config);

     do {
+      /* Key, value */
       OBJECT ok, ov;
       bstring k = (bstring)hashtable_iterator_key(&iter);
       bstring v = (bstring)hashtable_iterator_value(&iter);
+      /* object key: Ruby string created from bstring library C string */
       ok = string_newfrombstr(m->s, k);
       if(is_number(bdata(v))) {
         ov = LL2N(strtoll(bdatae(v,""), NULL, 10));
@@ -532,11 +576,12 @@ void machine_migrate_config(machine m) {
     } while (hashtable_iterator_advance(&iter));

   }
-  
+  /* Make RUBY_CONFIG point to global configuration */
   machine_set_const(m, "RUBY_CONFIG", m->s->global->config);
   machine_setup_from_config(m);
 }

+/* applies debug configuraiton options to VM state */
 void machine_setup_from_config(machine m) {
   bstring s;

@@ -555,6 +600,7 @@ void machine_setup_from_config(machine m) {
   bdestroy (s);
 }

+/* initializes platform and arc related Ruby constants like RUBY_PLATFORM, OS and L64 */
 void machine_setup_config(machine m) {
   OBJECT mod;
   STATE;
@@ -698,6 +744,7 @@ void machine_setup_config(machine m) {
   machine_set_const_under(m, "MESSAGE_IO", io_new(m->s, m->message_read_fd, "r"), mod);
 }

+/* sets up debugging flags */
 void machine_config_env(machine m) {
   char *config;
   if(getenv("RDEBUG")) {
@@ -719,6 +766,7 @@ void machine_config_env(machine m) {
   }  
 }

+/* loads files in the directory, respects load order hint file .load_order.txt */
 int machine_load_directory(machine m, const char *prefix) {
   char *path;
   char *file;
@@ -792,6 +840,12 @@ int machine_load_object(machine m, char *name, uint8_t *data, long length) {
   return TRUE;
 }

+/* 
+ * loads and executes Rubinius bytecode archive (*.rba, similar to *.jar or *.elc)
+ * 
+ * Rubinius' rba files are essentialy zip archived bytecode. .load_order file 
+ * must be loaded first to respect bytecode dependencies.
+ */
 int machine_load_ar(machine m, const char *path) {
   int ret = FALSE;

@@ -815,6 +869,7 @@ int machine_load_rba(machine m, const char *path) {
 int machine_load_bundle(machine m, const char *path) {
   struct stat sb;

+  /* return false if file does no exist */
   if(stat(path, &sb) != 0) return FALSE;

   if(S_ISDIR(sb.st_mode)) {
@@ -824,6 +879,11 @@ int machine_load_bundle(machine m, const char *path) {
   return machine_load_rba(m, path);
 }

+/* 1. saves the command line arguments used to invoke the VM.
+ * 2. initializes platform and arc related Ruby constants
+ * 3. sets up debugging flags from configuration
+ * 4. sets standard IO streams (stdin, stdout, stderr) to Ruby constants STDIN, STDOUT and STDERR
+ */
 void machine_setup_normal(machine m, int argc, char **argv) {
   machine_save_args(m, argc, argv);
   machine_setup_config(m);
@@ -831,6 +891,13 @@ void machine_setup_normal(machine m, int argc, char **argv) {
   machine_setup_standard_io(m);
 }

+/*
+ * 1. sets inferior machine flag to true (inferior machine is one spawned by another, a "child")
+ * 2. saves the command line arguments used to invoke the VM.
+ * 3. initializes platform and arc related Ruby constants
+ * 4. sets up debugging flags from configuration
+ * 5. sets up piped IO streams (stdin, stdout, stderr) to Ruby constants STDIN, STDOUT and STDERR
+ */
 int *machine_setup_thread(machine m, int argc, char **argv) {
   m->sub = TRUE;
   machine_save_args(m, argc, argv);
@@ -838,4 +905,3 @@ int *machine_setup_thread(machine m, int argc, char **argv) {
   machine_config_env(m);
   return machine_setup_piped_io(m);
 }
-
diff --git a/shotgun/lib/machine.h b/shotgun/lib/machine.h
index c5e82b4..82815e7 100644
--- a/shotgun/lib/machine.h
+++ b/shotgun/lib/machine.h
@@ -9,6 +9,30 @@ typedef struct rubinius_machine *machine;
 #include "shotgun/lib/shotgun.h"
 #include "shotgun/lib/environment.h"

+/* 
+ Rubinius supports multiple VM (MVM) feature: machines may be spawned off other machines, 
+ every machine has an identifier which is incremented when new machine is added to environment.
+
+ Machines pass messages to each other thus concurrency is cooperative like in Erlang.
+ Incoming and outcoming messages are passed using stream descriptors.
+ Incoming messages queue can be accessed in Ruby as MESSAGE_IO constant.
+
+ Each VM operates in a separate pthread. Spawned VMs are known as "inferior VMs",
+ this is reflected by VM_INFERIOR constant value in Ruby. VMs has name and keep
+ arguments (notably argc/argv) passed on run.
+
+ To carry VM context around Rubinius uses rstate structure. It contains a variety of things
+ from object memory to stack frames state and so forth.
+
+ If SIGSEGV/SIGBUS/SIGABRT happens during the execution it is handled by special context
+ known as firesuite. Error message and type are accessible and shown in VM backtrace.
+
+ To force Rubinius VM use print additional information set show_config flag to 1.
+
+ sub : flag that indicates whether it is an inferior VM: i.e. spawn by another VM. In Ruby 
+ you can get this using VM_INFERIOR constant
+  
+ */
 struct rubinius_machine {
   int id;
   int parent_id;
@@ -16,6 +40,7 @@ struct rubinius_machine {
   int sub;
   int message_read_fd;
   int message_write_fd;
+  /* VM state: carried around to keep global VM context */
   rstate s;
   cpu c;
   struct sigaction error_report;
@@ -23,11 +48,13 @@ struct rubinius_machine {
   int argc;
   char **argv;
   int show_config;
-  ucontext_t g_firesuit;
   /* work around a bug in 10.5's libc versus header files */
 #if defined(__APPLE__) && defined(HAS_UCONTEXT) /* patch for tiger */
   _STRUCT_MCONTEXT __system_mc;
 #endif
+
+/* these members relate to segfaults handling so they get reported correctly and VM exit gracefully(ish) */
+  ucontext_t g_firesuit;  
   int g_use_firesuit;
   int g_access_violation;
   int g_firesuit_arg;
diff --git a/shotgun/lib/object.h b/shotgun/lib/object.h
index 5af6e35..5b5bca9 100644
--- a/shotgun/lib/object.h
+++ b/shotgun/lib/object.h
@@ -52,7 +52,7 @@ static inline void object_copy_body(STATE, OBJECT self, OBJECT dest) {
   memcpy(object_byte_start(state, dest), object_byte_start(state, self), s1);
 }

-
+/* Ruby's is_a? */
 #define ISA(o, c) object_kind_of_p(state, o, c)

 static inline uintptr_t object_get_id(STATE, OBJECT self) {
diff --git a/shotgun/lib/object_memory.h b/shotgun/lib/object_memory.h
index b9c7746..fc5afc7 100644
--- a/shotgun/lib/object_memory.h
+++ b/shotgun/lib/object_memory.h
@@ -15,17 +15,26 @@
 #define OMCollectYoung  0x1
 #define OMCollectMature 0x2

+/* set of flags */
 struct object_memory_struct {
+  /*  */
   int collect_now;
+  /*  */
   int enlarge_now;
+  /*  */
   int tenure_now;
+  /*  */
   int new_size;
+  /*  */
   int last_object_id;
+  /* Rubinius uses Baker's generational GC as well asm marking and sweeping */
   baker_gc gc;
   mark_sweep_gc ms;
+  /*  */
   int last_tenured;
+	/* */
   int bootstrap_loaded;
-  
+	/* */
   rheap contexts;
   /* The first not referenced stack context */
   OBJECT context_bottom;
diff --git a/shotgun/lib/oop.h b/shotgun/lib/oop.h
index 5631dc0..831d2ad 100644
--- a/shotgun/lib/oop.h
+++ b/shotgun/lib/oop.h
@@ -20,7 +20,9 @@ typedef intptr_t native_int;

 #define TAG_REF     0x0
 #define TAG_FIXNUM  0x1
+/* literals are numbers, symbols, ranges, regexp */
 #define TAG_LITERAL 0x2
+
 #define TAG_DATA    0x3

 #define TAG(v) (((intptr_t)v) & TAG_MASK)
@@ -213,16 +215,18 @@ A rubinius object can be followed by:

 /* Object access, lowest level. These read and set fields of an OBJECT
  * directly. They're built on to integrate with the GC properly. */
-
 #define CLASS_OBJECT(obj) (obj->klass)
 #define SIZE_OF_OBJECT ((unsigned int)(sizeof(OBJECT)))
-
 #define NUM_FIELDS(obj)                 (obj->field_count)
 #define SET_NUM_FIELDS(obj, fel)        (obj->field_count = fel)
+/* size of rubinius_object_t plus size of fields (all in bytes) */
 #define SIZE_IN_BYTES_FIELDS(fel)       ((unsigned int)(sizeof(struct rubinius_object_t) + \
                                          fel*SIZE_OF_OBJECT))
+/* size of rubinius_object_t and fields in words */
 #define SIZE_IN_WORDS_FIELDS(fel)       (sizeof(struct rubinius_object_t)/SIZE_OF_OBJECT + fel)
+/* size of object in bytes */
 #define SIZE_IN_BYTES(obj)              SIZE_IN_BYTES_FIELDS(obj->field_count)
+/* size of fields only */
 #define SIZE_OF_BODY(obj)               (obj->field_count * SIZE_OF_OBJECT)
 #define ADDRESS_OF_FIELD(obj, fel)      (&obj->field[fel])
 #define NTH_FIELD_DIRECT(obj, fel)      (obj->field[fel])
@@ -259,18 +263,24 @@ to be a simple test for that bit pattern.
 #define Qtrue  ((OBJECT)10L)
 #define Qundef ((OBJECT)18L)

+/* returns TRUE when v is Ruby false, FALSE otherwise */
 #define FALSE_P(v) ((OBJECT)(v) == (OBJECT)Qfalse)
+/* returns TRUE when v is Ruby true, FALSE otherwise */
 #define TRUE_P(v) ((OBJECT)(v) == (OBJECT)Qtrue)
+/* returns TRUE if v is Ruby nil, FALSE otherwise */
 #define NIL_P(v) ((OBJECT)(v) == (OBJECT)Qnil)
+/* returns TRUE when  value of v is undefined, FALSE otherwise */
 #define UNDEF_P(v) ((OBJECT)(v) == (OBJECT)Qundef)
+/* returns TRUE when  v is not nil, FALSE otherwise */
 #define RTEST(v) (((uintptr_t)(v) & 0x7) != 0x6)
-
+/* returns TRUE when  v is a reference, FALSE otherwise */
 #define REFERENCE_P(v) (TAG(v) == TAG_REF)
-
+/* same as REFERENCE_P but checks v value first */
 #define REFERENCE2_P(v) (v && REFERENCE_P(v))

 #define INDEXED(obj) (REFERENCE_P(obj) && !obj->StoresBytes)

+/* copy flags not used by garbage collector */
 static inline void object_copy_nongc_flags(OBJECT target, OBJECT source)
 {
   target->obj_type        = source->obj_type;
@@ -282,17 +292,21 @@ static inline void object_copy_nongc_flags(OBJECT target, OBJECT source)
 }

 #define CLEAR_FLAGS(obj)     (obj)->all_flags = 0
+/* stack context has GC zone unspecified */
 #define stack_context_p(obj) ((obj)->gc_zone == UnspecifiedZone)
+/* use this to check forwarded pointer on object: 
+ * when object is copied from space to space by GC,
+ * forwarding pointer is left in old location
+ */
 #define SET_FORWARDED(obj)   (obj)->Forwarded = TRUE
 #define FORWARDED_P(obj)     ((obj)->Forwarded)

+/* objects are getting old as they survive GC tracing */
 #define AGE(obj)           (obj->copy_count)
 #define CLEAR_AGE(obj)     (obj->copy_count = 0)
 #define INCREMENT_AGE(obj) (obj->copy_count++)

 /* Object access. */
-
-/* Setting the class of an object */
 #define rbs_set_class(om, obj, cls) ({ \
     OBJECT _o = (obj), _c = (cls); \
     RUN_WB2(om, _o, _c); _o->klass = _c; })
@@ -300,7 +314,6 @@ static inline void object_copy_nongc_flags(OBJECT target, OBJECT source)
 #define SET_CLASS(o,v) rbs_set_class(state->om, o, v)

 /* Accessing and assigning the fields of an object */
-
 #define SET_FIELD(obj, fel, val) rbs_set_field(state->om, obj, fel, val)
 #define NTH_FIELD(obj, fel) rbs_get_field(obj, fel)

@@ -331,10 +344,12 @@ static inline void object_copy_nongc_flags(OBJECT target, OBJECT source)
   RUN_WB2(om, _o, _v); \
   SET_FIELD_DIRECT(_o, fel, _v); })

+/* alias macro for obtaining object field directly by position */
 #define rbs_get_field(obj, fel) NTH_FIELD_DIRECT(obj, fel)

 #else /*DISABLE_CHECKS*/

+/* compared to _bad_reference prints more verbose error message */
 static void _bad_reference2(OBJECT in, int fel) {
   printf("Attempted to access field %d in an object with %lu fields.\n", 
     fel, (unsigned long)NUM_FIELDS(in));
@@ -346,8 +361,10 @@ static void _bad_reference2(OBJECT in, int fel) {

 #if EXTRA_PROTECTION

+/* versions that check for reference */
 static void _bad_reference(OBJECT in) {
   printf("Attempted to access field of non-reference.\n");
+	/* handle segfault */
   if(current_machine->g_use_firesuit) {
     machine_handle_fire(FIRE_NULL);
   } 
@@ -369,7 +386,7 @@ static void _bad_reference(OBJECT in) {

 #else /*EXTRA_PROTECTION*/

-/* These are the typically used versions. The don't check for ref, they
+/* These are the typically used versions. They don't check for ref, they
    the segfault handler do that. */

 #define rbs_set_field(om, obj, fel, val) ({ \
@@ -400,8 +417,10 @@ static void _bad_reference(OBJECT in) {

 /* Type tests. */
 #define RTYPE(obj,type) (REFERENCE_P(obj) && obj->obj_type == type)
+/* shortcut, doing what Ruby's is_a? does */
 #define RISA(obj,cls) (REFERENCE_P(obj) && ISA(obj,BASIC_CLASS(cls)))

+/* Type predicates */
 #define BIGNUM_P(obj) (RTYPE(obj, BignumType))
 #define FLOAT_P(obj) (RTYPE(obj, FloatType))
 #define COMPLEX_P(obj) (FALSE)
@@ -424,6 +443,7 @@ static void _bad_reference(OBJECT in) {

 #define CTX_P(obj) RISA(obj, fastctx)
 #define BYTEARRAY_P(obj) RTYPE(obj, ByteArrayType)
+/* iseq is instruction sequence */
 #define ISEQ_P(obj) RTYPE(obj, ISeqType)
 #define TASK_P(obj) RTYPE(obj, TaskType)
 #define CHANNEL_P(obj) RTYPE(obj, ChannelType)
diff --git a/shotgun/lib/shotgun.h b/shotgun/lib/shotgun.h
index 0f9fb5e..15a2c9b 100644
--- a/shotgun/lib/shotgun.h
+++ b/shotgun/lib/shotgun.h
@@ -2,7 +2,7 @@
 #define RBS_SHOTGUN_H

 #define INTERNAL_DEBUG 0
-
+/* whether tracking various VM stats */
 #define TRACK_STATS 0
 #define DISABLE_CHECKS 1
 // #define TIME_LOOKUP 1
diff --git a/shotgun/lib/state.h b/shotgun/lib/state.h
index f070a4e..958a4b2 100644
--- a/shotgun/lib/state.h
+++ b/shotgun/lib/state.h
@@ -137,6 +137,7 @@ struct rubinius_state {

   rni_handle_table *handle_tbl;

+  /* pointer to bottom of the stack  */
   unsigned long *stack_bottom;

   struct hashtable *cleanup;
@@ -146,9 +147,10 @@ struct rubinius_state {
   void *thread_infos;
   unsigned int event_id;

+  /* Stuff sampling profiler uses, not critical for VM operations */
   OBJECT *samples;
   int max_samples, cur_sample;
-  
+  /* again, profiler stats */
   int excessive_tracing, gc_stats;
   int check_events, pending_threads, pending_events;

diff --git a/shotgun/lib/string.c b/shotgun/lib/string.c
index b50c926..ba8d07b 100644
--- a/shotgun/lib/string.c
+++ b/shotgun/lib/string.c
@@ -109,6 +109,7 @@ OBJECT string_append(STATE, OBJECT self, OBJECT other) {
   return self;
 }

+/* returns pointer to bytearray string based on */
 char *string_byte_address(STATE, OBJECT self) {
   OBJECT data;

diff --git a/shotgun/lib/subtend/nmc.h b/shotgun/lib/subtend/nmc.h
index 8e88102..aaa02b0 100644
--- a/shotgun/lib/subtend/nmc.h
+++ b/shotgun/lib/subtend/nmc.h
@@ -4,7 +4,7 @@

 #include "shotgun/lib/cpu.h"
 #include "shotgun/lib/subtend/nmethod.h"
-
+/* Rubinius native interface: native method context */
 struct rni_nmc {
   int num_handles;
   int used;