diff --git a/shotgun/lib/baker.c b/shotgun/lib/baker.c
index 1c16e44..e5781d9 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 */
 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..962e53a 100644
--- a/shotgun/lib/cpu.h
+++ b/shotgun/lib/cpu.h
@@ -46,11 +46,12 @@
   unsigned int sp; \
   unsigned int fp;

+/* just an 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 +63,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 is pointer to the stack top
+ * stack_size is obviously the size of the stack
+ * enclosing_class 
+ * active_context is context being executed
+ * home_context
+ * main 
+ * paths 
+ * depth is stack depth
+ * current_scope is current visibility scope
+ * ip_ptr is instruction pointer
+ * sp_ptr is stack pointer
+ * 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 +107,32 @@ struct cpu_task_shared {
   CPU_TASK_REGISTERS;
 };

+/* 
+ 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 is current object which self pseudo variable points to
+ sender is message sender
+ locals is list of local variables of the scope
+ IP is for instruction pointer
+ SP is for stack pointer
+ FP is for execution 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 +148,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..09a9fe5 100644
--- a/shotgun/lib/heap.h
+++ b/shotgun/lib/heap.h
@@ -5,9 +5,13 @@ typedef void* address;

 struct heap {
   size_t size;
+  /* lower bound */
   address address;
+  /* current tip of the heap */
   address current;
+  /* upper bound */
   address last;
+  /* GC's scanner position */
   address scan;
 };

@@ -27,6 +31,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 +73,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..62b795d 100644
--- a/shotgun/lib/machine.c
+++ b/shotgun/lib/machine.c
@@ -32,32 +32,45 @@

 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 */
 void machine_print_callstack_limited(machine m, int maxlev) {
+  /* context we are in */
   OBJECT context, tmp;
+  /* module name, method name and file name */
   const char *modname, *methname, *filename;
+  /* means of optimisation: fast context treats OBJECT as series of bytes instead of normal object */
   struct fast_context *fc;
-
+  /* use current machine if not explicitly given */
   if(!m) m = current_machine;
-
+  /* get current context */
   context = m->c->active_context;

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

+  /* make VM instruction pointer point to context instruction pointer */
   FASTCTX(context)->ip = m->c->ip;
-  
+
+  /* while there's a context and trace level is not reached */
   while(RTEST(context) && maxlev--) {
+    
     methctx_reference(m->s, context);
     fc = FASTCTX(context);
-
+    
+    /* figure out module name */
     if(fc->method_module && RTEST(fc->method_module)) {
       modname = SYM2STR(m->s, module_get_name(fc->method_module));
     } else {
       modname = "";
     }
-
+    
+    /* figure out method name */
     if(fc->type == FASTCTX_BLOCK) {
       methname = "";
     } else if(fc->name && RTEST(fc->name)) {
@@ -70,6 +83,7 @@ void machine_print_callstack_limited(machine m, int maxlev) {
       methname = "";
     }

+    /* figure out filename */
     if(fc->method && RTEST(fc->method)) {
       tmp = cmethod_get_file(fc->method);
       if(SYMBOL_P(tmp)) {
@@ -81,24 +95,31 @@ 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 */
 void machine_print_stack(machine m) {
   unsigned int i, start, end;
+  /* flush stack pointer */
   cpu_flush_sp(m->c);
+  /* get stack pointer */
   i = m->c->sp;
+  /* ASK */
   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,8 +133,11 @@ void machine_print_stack(machine m) {

 }

+/* prints VM registers content */
 void machine_print_registers(machine m) {
+  /* flush stack pointer */
   cpu_flush_sp(m->c);
+  /* flush instruction pointer */
   cpu_flush_ip(m->c);
   printf("IP: %04d\nSP: %04d\n", m->c->ip, m->c->sp);
   if(NIL_P(m->c->exception)) {
@@ -123,18 +147,23 @@ void machine_print_registers(machine m) {
   }
 }

+/* handles error reporting */
 void _machine_error_reporter(int sig, siginfo_t *info, void *ctx) {
+  /* name of signal VM recieved */
   const char *signame;
+  /* Rubinius native interface context */
   rni_context *rni_ctx;
   OBJECT addr;

   /* 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 +221,27 @@ 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 VM CPU, subtend, context and state, universe and everything.
+ * 
+ */
 machine machine_new(environment e) {
   machine m;
   int pipes[2];
@@ -220,21 +255,24 @@ machine machine_new(environment e) {
   /* Setup pipes used for message notification. */
   m->message_read_fd =  pipes[0];
   m->message_write_fd = pipes[1];
-
+  /* initialize VM state */
   m->s = rubinius_state_new();
+  /* allocate memory for VM cpu and initialize it's paths list */
   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;

+  /* setup signals and events handling */
   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);
@@ -244,20 +282,27 @@ machine machine_new(environment e) {
   return m;
 }

+/* destroys VM cpu and state objects, frees memory */
 void machine_destroy(machine m) {
   cpu_destroy(m->c);
   state_destroy(m->s);
   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 */
 void machine_handle_type_error(OBJECT obj, const char *message) {
+  /* store error message */
   current_machine->g_firesuit_message = strdup(message);
-
+  
+  /* make errors handle to know error type */
   if(FIXNUM_P(obj)) {
     current_machine->g_firesuit_arg = FixnumType;
   } else if(SYMBOL_P(obj)) {
@@ -269,21 +314,25 @@ void machine_handle_type_error(OBJECT obj, const char *message) {
   } else {
     current_machine->g_firesuit_arg = 0;
   }
-
+  /* now handle it */
   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);

+  /* print the whole backtrace */
   printf("\nRuby backtrace:\n");
   machine_print_callstack(current_machine);

+  /* if firesuit is off exit otherwise store error type and switch to special handling context */
   if(!current_machine->g_use_firesuit) abort();
   current_machine->g_access_violation = FIRE_ASSERT;
   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,10 +355,12 @@ void machine_show_exception(machine m, OBJECT exc) {
   puts("");
 }

+/* initializes VM globals, clear instruction pointer, op, firesuit and so forth */
 int machine_run(machine m) {
+  /* here's where the actual initialization starts */
   cpu_run(m->s, m->c, 0);
   m->c->ip_ptr = &m->s->external_ip;
-
+  /* report if there's an exception */	  
   if(RTEST(m->c->exception)) {
     printf("Toplevel exception detected.\n");
     machine_show_exception(m, m->c->exception);
@@ -318,6 +369,7 @@ int machine_run(machine m) {
   return TRUE;
 }

+/* loads and executes a script */
 int machine_run_file(machine m, const char *path) {
   OBJECT meth;
   int out;
@@ -325,13 +377,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 +395,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 +419,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 +448,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 +465,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 +480,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 +490,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,20 +569,27 @@ void machine_parse_config_file(machine m, const char *path) {
 }

 void machine_migrate_config(machine m) {
+  /* hash table iterator */
   struct hashtable_itr iter;
+  /* VM state */
   rstate state = m->s;
-  
+
+  /* initialize new hash for environment global configuration */  
   m->s->global->config = hash_new_sized(m->s, 500);
-    
+
+  /* unless config is empty */  					
   if(hashtable_count(m->s->config) > 0) {
-  
+    /* Iterate through it */
     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);
+      /* ASK */
       if(is_number(bdata(v))) {
         ov = LL2N(strtoll(bdatae(v,""), NULL, 10));
       } else {
@@ -532,11 +600,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 +624,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 +768,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 +790,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 +864,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 +893,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 +903,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 +915,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 +929,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..98f46a6 100644
--- a/shotgun/lib/machine.h
+++ b/shotgun/lib/machine.h
@@ -9,13 +9,37 @@ 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.
+
+ Rubinius uses CPU abstraction for it's virtual machine. 
+ */
 struct rubinius_machine {
   int id;
   int parent_id;
   pthread_t pthread;
+  /* whether it is an inferior VM: i.e. spawn by another VM. In Ruby  */
   int sub;
   int message_read_fd;
   int message_write_fd;
+	/* VM state: carried around to keep VM context */
   rstate s;
   cpu c;
   struct sigaction error_report;
@@ -23,11 +47,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..7c6e18c 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)

+/* true if v is Ruby false */
 #define FALSE_P(v) ((OBJECT)(v) == (OBJECT)Qfalse)
+/* true if v is Ruby true */
 #define TRUE_P(v) ((OBJECT)(v) == (OBJECT)Qtrue)
+/* true if v is Ruby nil */
 #define NIL_P(v) ((OBJECT)(v) == (OBJECT)Qnil)
+/* true if value of v is undefined */
 #define UNDEF_P(v) ((OBJECT)(v) == (OBJECT)Qundef)
+/* true if v is not nil */
 #define RTEST(v) (((uintptr_t)(v) & 0x7) != 0x6)
-
+/* true if v is a reference */
 #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,20 @@ 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 after surviving 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; })
@@ -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,11 @@ 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 +387,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,6 +418,7 @@ 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)))

 #define BIGNUM_P(obj) (RTYPE(obj, BignumType))
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;