 erts/emulator/beam/beam_bif_load.c |    9 ++++++++-
 erts/emulator/beam/beam_emu.c      |   19 ++++++++++++++++++-
 erts/emulator/beam/beam_load.h     |    1 +
 erts/emulator/beam/export.h        |    9 +++++----
 4 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index d76a7d8..93d735f 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -342,9 +342,16 @@ BIF_RETTYPE finish_after_on_load_2(BIF_ALIST_2)
 	    if (ep != NULL &&
 		ep->code[0] == BIF_ARG_1 &&
 		ep->code[4] != 0) {
+        /* the fixed address is in ep->code[4], see final_touch in beam_load */
 		ep->address = (void *) ep->code[4];
+        /* Original code !
 		ep->code[4] = 0;
-	    }
+        */
+        /* any hipe stub to this function points to ep->code[3], which in turn
+        is em_call_error_handler (to load the module). Since the function is
+        loaded, we can jump to it directly with em_call_from_hipe_stub */
+        ep->code[3] = em_call_from_hipe_stub;
+        }
 	}
 	modp->code[MI_ON_LOAD_FUNCTION_PTR] = 0;
 	set_default_trace_pattern(BIF_ARG_1);
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index fb90a7d..a8744d6 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -221,7 +221,7 @@ BeamInstr beam_continue_exit[1];
 BeamInstr* em_call_error_handler;
 BeamInstr* em_apply_bif;
 BeamInstr* em_call_traced_function;
-
+BeamInstr* em_call_from_hipe_stub;
 
 /* NOTE These should be the only variables containing trace instructions.
 **      Sometimes tests are form the instruction value, and sometimes
@@ -3245,6 +3245,22 @@ void process_main(void)
      goto post_error_handling;
  }
 
+    /*
+     * At this point, I points to the code[3] in the export entry for
+     * a loaded function with a hipe stub.
+     *
+     * code[0]: Module
+     * code[1]: Function
+     * code[2]: Arity
+     * code[3]: &&call_from_hipe_stub
+     * code[4]: Address of function.
+     */
+ OpCase(call_from_hipe_stub): {
+     /* We might want to fix the stub (?) to earn few cycles */
+     SET_I((BeamInstr *)Arg(0));
+     Goto(*I);
+ }
+
  OpCase(call_error_handler):
     /*
      * At this point, I points to the code[3] in the export entry for
@@ -5304,6 +5320,7 @@ void process_main(void)
      em_call_error_handler = OpCode(call_error_handler);
      em_call_traced_function = OpCode(call_traced_function);
      em_apply_bif = OpCode(apply_bif);
+     em_call_from_hipe_stub = OpCode(call_from_hipe_stub);
 
      beam_apply[0]             = (BeamInstr) OpCode(i_apply);
      beam_apply[1]             = (BeamInstr) OpCode(normal_exit);
diff --git a/erts/emulator/beam/beam_load.h b/erts/emulator/beam/beam_load.h
index 26e3054..373d242 100644
--- a/erts/emulator/beam/beam_load.h
+++ b/erts/emulator/beam/beam_load.h
@@ -48,6 +48,7 @@ extern BeamInstr beam_debug_apply[];
 extern BeamInstr* em_call_error_handler;
 extern BeamInstr* em_apply_bif;
 extern BeamInstr* em_call_traced_function;
+extern BeamInstr* em_call_from_hipe_stub;
 typedef struct {
     BeamInstr* start;		/* Pointer to start of module. */
     BeamInstr* end;			/* Points one word beyond last function in module. */
diff --git a/erts/emulator/beam/export.h b/erts/emulator/beam/export.h
index c604fdf..d188ee3 100644
--- a/erts/emulator/beam/export.h
+++ b/erts/emulator/beam/export.h
@@ -45,11 +45,12 @@ typedef struct export
      * code[3]: This entry is 0 unless the 'address' field points to it.
      *          Threaded code instruction to load function
      *		(em_call_error_handler), execute BIF (em_apply_bif,
-     *		em_apply_apply), or call a traced function
-     *		(em_call_traced_function).
+     *    em_apply_apply), call a traced function
+     *    (em_call_traced_function) or call a loaded function (for hipe stub
+     *      of on_load modules).
      * code[4]: Function pointer to BIF function (for BIFs only)
-     *		or pointer to threaded code if the module has an
-     *		on_load function that has not been run yet.
+     *    or pointer to threaded code if the module has an
+     *    on_load function.
      *		Otherwise: 0.
      */
     BeamInstr code[5];
