guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 179/437: Add heuristic code to estimate space and resize


From: Andy Wingo
Subject: [Guile-commits] 179/437: Add heuristic code to estimate space and resize if required jit buffer.
Date: Mon, 2 Jul 2018 05:14:13 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit 44d4fa5444aa7f4c6e766403c0f8e8a014fdd4f4
Author: pcpa <address@hidden>
Date:   Tue Jan 29 16:37:43 2013 -0200

    Add heuristic code to estimate space and resize if required jit buffer.
---
 ChangeLog                       | 18 ++++++++++++
 configure.ac                    |  4 ++-
 include/lightning/jit_private.h |  9 ++++++
 lib/jit_arm.c                   | 24 +++-------------
 lib/jit_mips.c                  | 24 +++-------------
 lib/jit_ppc.c                   | 24 +++-------------
 lib/jit_x86-cpu.c               |  2 +-
 lib/jit_x86.c                   | 24 +++-------------
 lib/lightning.c                 | 64 +++++++++++++++++++++++++++++++++++++++++
 9 files changed, 111 insertions(+), 82 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1322aac..2a4170b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2013-01-29 Paulo Andrade <address@hidden>
+
+       * configure.ac: Use AC_CONFIG_HEADERS instead of AC_CONFIG_HEADER
+       to have HAVE_CONFIG_H defined with latest aclocal.
+
+       * include/lightning/jit_private.h, lib/lightning.c: Add new
+       abstraction to use an heuristic to calculate amount of space
+       required for jit generation, and code to reallocate buffer if
+       did miscalculate it.
+
+       * lib/jit_arm.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_x86.c:
+       Update to use new code to estimate and resize of required buffer
+       for jit code.
+
+       * lib/jit_x86-cpu.c: Minor cosmetic change to avoid adding a
+       non required rex prefix when calling a function pointer stored
+       in a register.
+
 2013-01-24 Paulo Andrade <address@hidden>
 
        * check/Makefile.am: "make debug" target should pass only
diff --git a/configure.ac b/configure.ac
index 83a7805..9e9f939 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,12 +19,14 @@ AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([dist-bzip2])
 AC_CONFIG_MACRO_DIR(m4)
 
-AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS(config.h)
 
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_LIBTOOL
 
+AC_CHECK_FUNCS(mremap,,)
+
 AC_CHECK_LIB(gmp, __gmpz_init, ,
        [AC_MSG_ERROR([GNU MP not found, see http://gmplib.org/])])
 
diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h
index c32f0b4..b0be3d9 100644
--- a/include/lightning/jit_private.h
+++ b/include/lightning/jit_private.h
@@ -18,6 +18,10 @@
 #ifndef _jit_private_h
 #define _jit_private_h
 
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
 #include <assert.h>
 #include <limits.h>
 #include <stdio.h>
@@ -277,6 +281,7 @@ struct jit_state {
     mpz_t                blockmask;    /* mask of visited basic blocks */
     struct {
        jit_uint8_t      *ptr;
+       jit_uint8_t      *end;
        jit_word_t        length;
     } code;
     struct {
@@ -408,6 +413,10 @@ _jit_classify(jit_state_t*, jit_code_t);
 extern jit_bool_t
 _jit_regarg_p(jit_state_t*, jit_node_t*, jit_int32_t);
 
+#define emit_code()            _emit_code(_jit)
+extern jit_pointer_t
+_emit_code(jit_state_t*);
+
 #define emit_ldxi(r0, r1, i0)  _emit_ldxi(_jit, r0, r1, i0)
 extern void
 _emit_ldxi(jit_state_t*, jit_int32_t, jit_int32_t, jit_word_t);
diff --git a/lib/jit_arm.c b/lib/jit_arm.c
index db4d514..95cbfac 100644
--- a/lib/jit_arm.c
+++ b/lib/jit_arm.c
@@ -784,7 +784,7 @@ _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
 }
 
 jit_pointer_t
-_jit_emit(jit_state_t *_jit)
+_emit_code(jit_state_t *_jit)
 {
     jit_node_t         *node;
     jit_node_t         *temp;
@@ -801,23 +801,6 @@ _jit_emit(jit_state_t *_jit)
        jit_int32_t      patch_offset;
     } undo;
 
-    if (_jit->function)
-       jit_epilog();
-    jit_optimize();
-
-    _jit->emit = 1;
-
-    _jit->code.length = 16 * 1024 * 1024;
-    _jit->code.ptr = mmap(NULL, _jit->code.length,
-                         PROT_EXEC | PROT_READ | PROT_WRITE,
-                         MAP_PRIVATE | MAP_ANON, -1, 0);
-    assert(_jit->code.ptr != MAP_FAILED);
-    _jit->pc.uc = _jit->code.ptr;
-
-    /* clear jit_flag_patch from label nodes if reallocating buffer
-     * and starting over
-     */
-
     _jit->function = NULL;
 
     jit_reglive_setup();
@@ -1025,6 +1008,9 @@ _jit_emit(jit_state_t *_jit)
                }                                                       \
                break
     for (node = _jit->head; node; node = node->next) {
+       if (_jit->pc.uc >= _jit->code.end)
+           return (NULL);
+
        value = jit_classify(node->code);
        jit_regarg_set(node, value);
        switch (node->code) {
@@ -1542,8 +1528,6 @@ _jit_emit(jit_state_t *_jit)
     }
 
     __clear_cache(_jit->code.ptr, _jit->pc.uc);
-    _jit->done = 1;
-    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_mips.c b/lib/jit_mips.c
index f5cbdf5..57be725 100644
--- a/lib/jit_mips.c
+++ b/lib/jit_mips.c
@@ -663,7 +663,7 @@ _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
 }
 
 jit_pointer_t
-_jit_emit(jit_state_t *_jit)
+_emit_code(jit_state_t *_jit)
 {
     jit_node_t         *node;
     jit_node_t         *temp;
@@ -676,23 +676,6 @@ _jit_emit(jit_state_t *_jit)
        jit_int32_t      patch_offset;
     } undo;
 
-    if (_jit->function)
-       jit_epilog();
-    jit_optimize();
-
-    _jit->emit = 1;
-
-    _jit->code.length = 16 * 1024 * 1024;
-    _jit->code.ptr = mmap(NULL, _jit->code.length,
-                         PROT_EXEC | PROT_READ | PROT_WRITE,
-                         MAP_PRIVATE | MAP_ANON, -1, 0);
-    assert(_jit->code.ptr != MAP_FAILED);
-    _jit->pc.uc = _jit->code.ptr;
-
-    /* clear jit_flag_patch from label nodes if reallocating buffer
-     * and starting over
-     */
-
     _jit->function = NULL;
 
     jit_reglive_setup();
@@ -774,6 +757,9 @@ _jit_emit(jit_state_t *_jit)
                }                                                       \
                break
     for (node = _jit->head; node; node = node->next) {
+       if (_jit->pc.uc >= _jit->code.end)
+           return (NULL);
+
        value = jit_classify(node->code);
        jit_regarg_set(node, value);
        switch (node->code) {
@@ -1249,8 +1235,6 @@ _jit_emit(jit_state_t *_jit)
 #if defined(__linux__)
     _flush_cache((char *)_jit->code.ptr, _jit->pc.uc - _jit->code.ptr, ICACHE);
 #endif
-    _jit->done = 1;
-    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c
index 443fcac..aaa2035 100644
--- a/lib/jit_ppc.c
+++ b/lib/jit_ppc.c
@@ -685,7 +685,7 @@ _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
 }
 
 jit_pointer_t
-_jit_emit(jit_state_t *_jit)
+_emit_code(jit_state_t *_jit)
 {
     jit_node_t         *node;
     jit_node_t         *temp;
@@ -698,23 +698,6 @@ _jit_emit(jit_state_t *_jit)
        jit_int32_t      patch_offset;
     } undo;
 
-    if (_jit->function)
-       jit_epilog();
-    jit_optimize();
-
-    _jit->emit = 1;
-
-    _jit->code.length = 16 * 1024 * 1024;
-    _jit->code.ptr = mmap(NULL, _jit->code.length,
-                         PROT_EXEC | PROT_READ | PROT_WRITE,
-                         MAP_PRIVATE | MAP_ANON, -1, 0);
-    assert(_jit->code.ptr != MAP_FAILED);
-    _jit->pc.uc = _jit->code.ptr;
-
-    /* clear jit_flag_patch from label nodes if reallocating buffer
-     * and starting over
-     */
-
     _jit->function = NULL;
 
     jit_reglive_setup();
@@ -797,6 +780,9 @@ _jit_emit(jit_state_t *_jit)
                }                                                       \
                break
     for (node = _jit->head; node; node = node->next) {
+       if (_jit->pc.uc >= _jit->code.end)
+           return (NULL);
+
        value = jit_classify(node->code);
        jit_regarg_set(node, value);
        switch (node->code) {
@@ -1212,8 +1198,6 @@ _jit_emit(jit_state_t *_jit)
     }
 
     __clear_cache(_jit->code.ptr, _jit->pc.uc);
-    _jit->done = 1;
-    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/jit_x86-cpu.c b/lib/jit_x86-cpu.c
index 197f780..997855d 100644
--- a/lib/jit_x86-cpu.c
+++ b/lib/jit_x86-cpu.c
@@ -3023,7 +3023,7 @@ _bxsubi_u(jit_state_t *_jit, jit_word_t i0, jit_int32_t 
r0, jit_word_t i1)
 static void
 _callr(jit_state_t *_jit, jit_int32_t r0)
 {
-    rex(0, 1, _NOREG, _NOREG, r0);
+    rex(0, 0, _NOREG, _NOREG, r0);
     ic(0xff);
     mrm(0x03, 0x02, r7(r0));
 }
diff --git a/lib/jit_x86.c b/lib/jit_x86.c
index 3d9f048..4ff1dab 100644
--- a/lib/jit_x86.c
+++ b/lib/jit_x86.c
@@ -868,7 +868,7 @@ _jit_retval_d(jit_state_t *_jit, jit_int32_t r0)
 }
 
 jit_pointer_t
-_jit_emit(jit_state_t *_jit)
+_emit_code(jit_state_t *_jit)
 {
     jit_node_t         *node;
     jit_node_t         *temp;
@@ -881,23 +881,6 @@ _jit_emit(jit_state_t *_jit)
        jit_int32_t      patch_offset;
     } undo;
 
-    if (_jit->function)
-       jit_epilog();
-    jit_optimize();
-
-    _jit->emit = 1;
-
-    _jit->code.length = 16 * 1024 * 1024;
-    _jit->code.ptr = mmap(NULL, _jit->code.length,
-                         PROT_EXEC | PROT_READ | PROT_WRITE,
-                         MAP_PRIVATE | MAP_ANON, -1, 0);
-    assert(_jit->code.ptr != MAP_FAILED);
-    _jit->pc.uc = _jit->code.ptr;
-
-    /* clear jit_flag_patch from label nodes if reallocating buffer
-     * and starting over
-     */
-
     _jit->function = NULL;
 
     jit_reglive_setup();
@@ -1125,6 +1108,9 @@ _jit_emit(jit_state_t *_jit)
                }                                                       \
                break
     for (node = _jit->head; node; node = node->next) {
+       if (_jit->pc.uc >= _jit->code.end)
+           return (NULL);
+
        value = jit_classify(node->code);
        jit_regarg_set(node, value);
        switch (node->code) {
@@ -1629,8 +1615,6 @@ _jit_emit(jit_state_t *_jit)
        word = node->code == jit_code_movi ? node->v.n->u.w : node->u.n->u.w;
        patch_at(node, _jit->patches.ptr[offset].inst, word);
     }
-    _jit->done = 1;
-    jit_annotate();
 
     return (_jit->code.ptr);
 }
diff --git a/lib/lightning.c b/lib/lightning.c
index 9b20a1e..e9de59d 100644
--- a/lib/lightning.c
+++ b/lib/lightning.c
@@ -1238,6 +1238,70 @@ _jit_regarg_clr(jit_state_t *_jit, jit_node_t *node, 
jit_int32_t value)
        jit_regset_clrbit(_jit->regarg, jit_regno(node->w.w));
 }
 
+jit_pointer_t
+_jit_emit(jit_state_t *_jit)
+{
+    jit_pointer_t       code;
+    jit_node_t         *node;
+    jit_int32_t                 mult;
+    size_t              length;
+
+    if (_jit->function)
+       jit_epilog();
+    jit_optimize();
+
+    /* Heuristic to guess code buffer size */
+    mult = 4;
+
+    _jit->emit = 1;
+
+    _jit->code.length = _jit->pool.length * 1024 * mult;
+
+    _jit->code.ptr = mmap(NULL, _jit->code.length,
+                         PROT_EXEC | PROT_READ | PROT_WRITE,
+                         MAP_PRIVATE | MAP_ANON, -1, 0);
+    assert(_jit->code.ptr != MAP_FAILED);
+    _jit->code.end = _jit->code.ptr + _jit->code.length - 64;
+    _jit->pc.uc = _jit->code.ptr;
+
+    for (;;) {
+       if ((code = emit_code()) == NULL) {
+           for (node = _jit->head; node; node = node->next) {
+               if (node->code == jit_code_label && node->link)
+                   node->flag &= ~jit_flag_patch;
+           }
+           ++mult;
+           length = _jit->pool.length * 1024 * mult;
+
+#if !HAVE_MREMAP
+           munmap(_jit->code.ptr, _jit->code.length);
+#endif
+
+#if HAVE_MREMAP
+           _jit->code.ptr = mremap(_jit->code.ptr, _jit->code.length,
+                                   length, MREMAP_MAYMOVE, NULL);
+#else
+           _jit->code.ptr = mmap(NULL, length,
+                                 PROT_EXEC | PROT_READ | PROT_WRITE,
+                                 MAP_PRIVATE | MAP_ANON, -1, 0);
+#endif
+
+           assert(_jit->code.ptr != MAP_FAILED);
+           _jit->code.length = length;
+           _jit->code.end = _jit->code.ptr + _jit->code.length - 64;
+           _jit->pc.uc = _jit->code.ptr;
+           _jit->patches.offset = 0;
+       }
+       else
+           break;
+    }
+
+    _jit->done = 1;
+    jit_annotate();
+
+    return (code);
+}
+
 /*   Compute initial reglive and regmask set values of a basic block.
  * reglive is the set of known live registers
  * regmask is the set of registers not referenced in the block



reply via email to

[Prev in Thread] Current Thread [Next in Thread]