diff --git a/rts/rts/gc_jgc.c b/rts/rts/gc_jgc.c
index 64b4c5d..421e29b 100644
--- a/rts/rts/gc_jgc.c
+++ b/rts/rts/gc_jgc.c
@@ -7,6 +7,10 @@
 
 #if _JHC_GC == _JHC_GC_JGC
 
+#ifdef _JHC_JGC_FIXED_MEGABLOCK
+static char aligned_megablock_1[MEGABLOCK_SIZE] __attribute__ ((aligned(BLOCK_SIZE)));
+static char gc_stack_base_area[(1UL << 8)*sizeof(gc_t)];
+#endif
 gc_t saved_gc;
 struct s_arena *arena;
 static gc_t gc_stack_base;
@@ -56,7 +60,10 @@ stack_grow(struct stack *s, unsigned grow)
 inline static void
 stack_check(struct stack *s, unsigned n) {
         if(__predict_false(s->size - s->ptr < n)) {
-                stack_grow(s,n + 1024);
+#ifndef _JHC_JGC_STACKGROW
+#define _JHC_JGC_STACKGROW (1024)
+#endif
+                stack_grow(s,n + (_JHC_JGC_STACKGROW));
         }
 }
 
@@ -190,7 +197,11 @@ static struct s_cache *array_caches_atomic[GC_STATIC_ARRAY_NUM];
 void
 jhc_alloc_init(void) {
         VALGRIND_PRINTF("Jhc-Valgrind mode active.\n");
+#ifdef _JHC_JGC_FIXED_MEGABLOCK
+        saved_gc = gc_stack_base = (void *) gc_stack_base_area;
+#else
         saved_gc = gc_stack_base = malloc((1UL << 18)*sizeof(gc_stack_base[0]));
+#endif
         arena = new_arena();
         if(nh_stuff[0]) {
                 nh_end = nh_start = nh_stuff[0];
@@ -318,7 +329,16 @@ struct s_megablock *
 s_new_megablock(struct s_arena *arena)
 {
         struct s_megablock *mb = malloc(sizeof(*mb));
+#ifdef _JHC_JGC_FIXED_MEGABLOCK
+        static int count = 0;
+        if (count != 0) {
+                abort();
+        }
+        count++;
+        mb->base = aligned_megablock_1;
+#else
         mb->base = jhc_aligned_alloc(MEGABLOCK_SIZE);
+#endif
         VALGRIND_MAKE_MEM_NOACCESS(mb->base,MEGABLOCK_SIZE);
         mb->next_free = 0;
         return mb;
@@ -334,6 +354,7 @@ get_free_block(gc_t gc, struct s_arena *arena) {
                 SLIST_REMOVE_HEAD(&arena->free_blocks,link);
                 return pg;
         } else {
+#ifndef _JHC_JGC_NAIVEGC
                 if((arena->block_used >= arena->block_threshold)) {
                         gc_perform_gc(gc);
                         // if we are still using 80% of the heap after a gc, raise the threshold.
@@ -341,6 +362,7 @@ get_free_block(gc_t gc, struct s_arena *arena) {
                                 arena->block_threshold *= 2;
                         }
                 }
+#endif
                 if(__predict_false(!arena->current_megablock))
                         arena->current_megablock = s_new_megablock(arena);
                 struct s_megablock *mb = arena->current_megablock;
@@ -466,6 +488,11 @@ s_alloc(gc_t gc, struct s_cache *sc)
        sc->arena->number_allocs++;
 #endif
         struct s_block *pg = SLIST_FIRST(&sc->blocks);
+#ifdef _JHC_JGC_NAIVEGC
+        if(__predict_false(!pg)) {
+                gc_perform_gc(gc);
+        }
+#endif
         if(__predict_false(!pg)) {
                 pg = get_free_block(gc, sc->arena);
                 VALGRIND_MAKE_MEM_NOACCESS(pg, BLOCK_SIZE);
diff --git a/rts/rts/gc_jgc.h b/rts/rts/gc_jgc.h
index 9501c7a..17b1d8a 100644
--- a/rts/rts/gc_jgc.h
+++ b/rts/rts/gc_jgc.h
@@ -12,8 +12,19 @@ struct s_cache;
 typedef void* *gc_t;
 typedef void* heap_t;  // a pointer into the GCed heap.
 
-#define BLOCK_SIZE     (1UL << 12)
-#define MEGABLOCK_SIZE (1UL << 20)
+#if defined(_JHC_JGC_BLOCK_SHIFT) && defined(_JHC_JGC_MEGABLOCK_SHIFT)
+#if (_JHC_JGC_BLOCK_SHIFT) >= (_JHC_JGC_MEGABLOCK_SHIFT)
+#error "_JHC_JGC_MEGABLOCK_SHIFT should be larger than _JHC_JGC_BLOCK_SHIFT."
+#endif
+#elif defined(_JHC_JGC_BLOCK_SHIFT) || defined(_JHC_JGC_MEGABLOCK_SHIFT)
+#error "Should define both _JHC_JGC_BLOCK_SHIFT and _JHC_JGC_MEGABLOCK_SHIFT."
+#else
+#define _JHC_JGC_BLOCK_SHIFT     12
+#define _JHC_JGC_MEGABLOCK_SHIFT 20
+#endif /* defined(_JHC_JGC_BLOCK_SHIFT) && defined(_JHC_JGC_MEGABLOCK_SHIFT) */
+
+#define BLOCK_SIZE     (1UL << (_JHC_JGC_BLOCK_SHIFT))
+#define MEGABLOCK_SIZE (1UL << (_JHC_JGC_MEGABLOCK_SHIFT))
 #define S_BLOCK(val) ((struct s_block *)((uintptr_t)(val) & ~(BLOCK_SIZE - 1)))
 #define TO_BLOCKS(x) (((x) + sizeof(uintptr_t) - 1)/sizeof(uintptr_t))
 
diff --git a/rts/rts/jhc_rts.c b/rts/rts/jhc_rts.c
index 075f330..cc73c8c 100644
--- a/rts/rts/jhc_rts.c
+++ b/rts/rts/jhc_rts.c
@@ -144,6 +144,7 @@ eval(sptr_t s)
 #if _JHC_DEBUG
                         GETHEAD(ds) = BLACK_HOLE;
 #endif
+                        fn = (eval_fn)SET_THUMB_BIT(fn);
 #if _JHC_GC == _JHC_GC_JGC
                         wptr_t r = (*fn)(gc,NODEP(ds));
 #else
diff --git a/rts/rts/jhc_rts.h b/rts/rts/jhc_rts.h
index 0446601..83904ca 100644
--- a/rts/rts/jhc_rts.h
+++ b/rts/rts/jhc_rts.h
@@ -95,3 +95,13 @@ bool jhc_valid_lazy(sptr_t s);
 #endif
 
 #endif
+
+/*
+ * Detail:
+ * http://communities.mentor.com/community/cs/archives/arm-gnu/msg01904.html
+ */
+#ifdef _JHC_ARM_STAY_IN_THUMB_MODE
+#define SET_THUMB_BIT(fn)    TO_SPTR(0x1,(sptr_t)fn)
+#else
+#define SET_THUMB_BIT(fn)    (fn)
+#endif
