guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] 01/01: Compiler allocates boxed flonums in unmarked spac


From: Andy Wingo
Subject: [Guile-commits] 01/01: Compiler allocates boxed flonums in unmarked space
Date: Mon, 26 Aug 2019 04:35:56 -0400 (EDT)

wingo pushed a commit to branch master
in repository guile.

commit b02d1b08d7d7f0eaafdd9dcfc3de3a139b25492e
Author: Andy Wingo <address@hidden>
Date:   Mon Aug 26 10:19:24 2019 +0200

    Compiler allocates boxed flonums in unmarked space
    
    This fixes a bug whereby the compiler would sometimes allocate floats in
    marked space.
    
    * libguile/gc-inline.h (scm_inline_gc_malloc_pointerless_words): New
      internal helper.
    * libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
    * libguile/intrinsics.c (allocate_pointerless_words):
      (allocate_pointerless_words_with_freelist): New intrinsics.
    * libguile/jit.c (compile_allocate_pointerless_words):
      (compile_allocate_pointerless_words_immediate): New compilers.
    * libguile/vm-engine.c (allocate_pointerless_words)
      (allocate_pointerless_words_immediate): New opcodes.
    * module/language/cps/compile-bytecode.scm (compile-function):
    * module/language/cps/effects-analysis.scm (param):
    * module/language/cps/reify-primitives.scm (reify-primitives):
    * module/language/cps/specialize-primcalls.scm (specialize-primcalls):
    * module/language/cps/types.scm (allocate-words):
    (allocate-words/immediate):
    * module/system/vm/assembler.scm (system): Add support for the new
      opcodes.
---
 libguile/gc-inline.h                         |  6 ++++
 libguile/intrinsics.c                        | 18 ++++++++++
 libguile/intrinsics.h                        |  2 ++
 libguile/jit.c                               | 54 ++++++++++++++++++++++++++++
 libguile/vm-engine.c                         | 36 +++++++++++++++++--
 module/language/cps/compile-bytecode.scm     |  6 ++++
 module/language/cps/effects-analysis.scm     |  7 ++++
 module/language/cps/reify-primitives.scm     | 13 +++++--
 module/language/cps/specialize-primcalls.scm |  2 ++
 module/language/cps/types.scm                |  4 +++
 module/system/vm/assembler.scm               |  2 ++
 11 files changed, 145 insertions(+), 5 deletions(-)

diff --git a/libguile/gc-inline.h b/libguile/gc-inline.h
index a1932d6..cb55aa8 100644
--- a/libguile/gc-inline.h
+++ b/libguile/gc-inline.h
@@ -117,6 +117,12 @@ scm_inline_gc_malloc_words (scm_thread *thread, size_t 
words)
   return scm_inline_gc_malloc (thread, words * sizeof (void *));
 }
 
+static inline void *
+scm_inline_gc_malloc_pointerless_words (scm_thread *thread, size_t words)
+{
+  return scm_inline_gc_malloc_pointerless (thread, words * sizeof (void *));
+}
+
 static inline SCM
 scm_inline_cell (scm_thread *thread, scm_t_bits car, scm_t_bits cdr)
 {
diff --git a/libguile/intrinsics.c b/libguile/intrinsics.c
index bb7381f..a9b2d98 100644
--- a/libguile/intrinsics.c
+++ b/libguile/intrinsics.c
@@ -430,6 +430,21 @@ allocate_words_with_freelist (scm_thread *thread, size_t 
freelist_idx)
 }
 
 static SCM
+allocate_pointerless_words (scm_thread *thread, size_t n)
+{
+  return SCM_PACK_POINTER (scm_inline_gc_malloc_pointerless_words (thread, n));
+}
+
+static SCM
+allocate_pointerless_words_with_freelist (scm_thread *thread, size_t 
freelist_idx)
+{
+  return SCM_PACK_POINTER
+    (scm_inline_gc_alloc (&thread->pointerless_freelists[freelist_idx],
+                          freelist_idx,
+                          SCM_INLINE_GC_KIND_POINTERLESS));
+}
+
+static SCM
 current_module (scm_thread *thread)
 {
   return scm_i_current_module (thread);
@@ -546,6 +561,9 @@ scm_bootstrap_intrinsics (void)
   scm_vm_intrinsics.facos = acos;
   scm_vm_intrinsics.fatan = atan;
   scm_vm_intrinsics.fatan2 = atan2;
+  scm_vm_intrinsics.allocate_pointerless_words = allocate_pointerless_words;
+  scm_vm_intrinsics.allocate_pointerless_words_with_freelist =
+    allocate_pointerless_words_with_freelist;
 
   scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
                             "scm_init_intrinsics",
diff --git a/libguile/intrinsics.h b/libguile/intrinsics.h
index eed8712..d8c6926 100644
--- a/libguile/intrinsics.h
+++ b/libguile/intrinsics.h
@@ -186,6 +186,8 @@ typedef uint32_t* scm_t_vcode_intrinsic;
   M(f64_from_f64, facos, "facos", FACOS) \
   M(f64_from_f64, fatan, "fatan", FATAN) \
   M(f64_from_f64_f64, fatan2, "fatan2", FATAN2) \
+  M(scm_from_thread_sz, allocate_pointerless_words, 
"allocate-pointerless-words", ALLOCATE_POINTERLESS_WORDS) \
+  M(scm_from_thread_sz, allocate_pointerless_words_with_freelist, 
"allocate-pointerless-words/freelist", 
ALLOCATE_POINTERLESS_WORDS_WITH_FREELIST) \
   /* Add new intrinsics here; also update scm_bootstrap_intrinsics.  */
 
 enum scm_vm_intrinsic
diff --git a/libguile/jit.c b/libguile/jit.c
index 136b8bc..f1c7a49 100644
--- a/libguile/jit.c
+++ b/libguile/jit.c
@@ -2089,6 +2089,60 @@ compile_allocate_words_immediate (scm_jit_state *j, 
uint16_t dst, uint16_t nword
 }
 
 static void
+compile_allocate_pointerless_words (scm_jit_state *j, uint16_t dst, uint16_t 
nwords)
+{
+  jit_gpr_t t = T0;
+
+  emit_store_current_ip (j, t);
+  emit_call_2 (j, scm_vm_intrinsics.allocate_pointerless_words, thread_operand 
(),
+               sp_sz_operand (j, nwords));
+  emit_retval (j, t);
+  record_gpr_clobber (j, t);
+  emit_reload_sp (j);
+  emit_sp_set_scm (j, dst, t);
+}
+
+static void
+compile_allocate_pointerless_words_immediate (scm_jit_state *j, uint16_t dst, 
uint16_t nwords)
+{
+  size_t bytes = nwords * sizeof(SCM);
+  size_t idx = scm_inline_gc_bytes_to_freelist_index (bytes);
+
+  if (SCM_UNLIKELY (idx >= SCM_INLINE_GC_FREELIST_COUNT))
+    {
+      jit_gpr_t t = T0;
+      emit_store_current_ip (j, t);
+      emit_call_1 (j, GC_malloc_atomic, jit_operand_imm (JIT_OPERAND_ABI_WORD, 
bytes));
+      emit_retval (j, t);
+      emit_reload_sp (j);
+      emit_sp_set_scm (j, dst, t);
+    }
+  else
+    {
+      jit_gpr_t res = T0;
+      ptrdiff_t offset = offsetof(struct scm_thread, pointerless_freelists);
+      offset += idx * sizeof(void*);
+      emit_ldxi (j, res, THREAD, offset);
+      jit_reloc_t fast = jit_bnei (j->jit, res, 0);
+      emit_store_current_ip (j, res);
+      emit_call_2 (j, 
scm_vm_intrinsics.allocate_pointerless_words_with_freelist,
+                   thread_operand (),
+                   jit_operand_imm (JIT_OPERAND_ABI_WORD, idx));
+      emit_retval (j, res);
+      emit_reload_sp (j);
+      jit_reloc_t done = jit_jmp (j->jit);
+
+      jit_patch_here (j->jit, fast);
+      jit_gpr_t new_freelist = T1;
+      emit_ldr (j, new_freelist, res);
+      jit_stxi (j->jit, offset, THREAD, new_freelist);
+
+      jit_patch_here (j->jit, done);
+      emit_sp_set_scm (j, dst, res);
+    }
+}
+
+static void
 compile_scm_ref (scm_jit_state *j, uint8_t dst, uint8_t obj, uint8_t idx)
 {
   emit_sp_ref_scm (j, T0, obj);
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 0c2c8e7..6b1e20d 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -3280,8 +3280,40 @@ VM_NAME (scm_thread *thread)
       NEXT (2);
     }
 
-  VM_DEFINE_OP (157, unused_157, NULL, NOP)
-  VM_DEFINE_OP (158, unused_158, NULL, NOP)
+  /* allocate-pointerless-words dst:12 count:12
+   *
+   * Allocate a fresh object consisting of COUNT words and store it into
+   * DST.  The result will not be traced by GC.  COUNT is a u64 local.
+   */
+  VM_DEFINE_OP (157, allocate_pointerless_words, "allocate-pointerless-words", 
DOP1 (X8_S12_S12))
+    {
+      uint16_t dst, size;
+
+      UNPACK_12_12 (op, dst, size);
+
+      SYNC_IP ();
+      SP_SET (dst, CALL_INTRINSIC (allocate_pointerless_words,
+                                   (thread, SP_REF_U64 (size))));
+      NEXT (1);
+    }
+
+  /* allocate-words/immediate dst:12 count:12
+   *
+   * Allocate a fresh object consisting of COUNT words and store it into
+   * DST.  The result will not be traced by GC.  COUNT is an immediate.
+   */
+  VM_DEFINE_OP (158, allocate_pointerless_words_immediate, 
"allocate-pointerless-words/immediate", DOP1 (X8_S12_C12))
+    {
+      uint16_t dst, size;
+
+      UNPACK_12_12 (op, dst, size);
+
+      SYNC_IP ();
+      SP_SET (dst, CALL_INTRINSIC (allocate_pointerless_words, (thread, 
size)));
+
+      NEXT (1);
+    }
+
   VM_DEFINE_OP (159, unused_159, NULL, NOP)
   VM_DEFINE_OP (160, unused_160, NULL, NOP)
   VM_DEFINE_OP (161, unused_161, NULL, NOP)
diff --git a/module/language/cps/compile-bytecode.scm 
b/module/language/cps/compile-bytecode.scm
index ff59317..6e7dab8 100644
--- a/module/language/cps/compile-bytecode.scm
+++ b/module/language/cps/compile-bytecode.scm
@@ -162,6 +162,12 @@
          (emit-allocate-words asm (from-sp dst) (from-sp (slot nfields))))
         (($ $primcall 'allocate-words/immediate (annotation . nfields))
          (emit-allocate-words/immediate asm (from-sp dst) nfields))
+        (($ $primcall 'allocate-pointerless-words annotation (nfields))
+         (emit-allocate-pointerless-words asm (from-sp dst)
+                                       (from-sp (slot nfields))))
+        (($ $primcall 'allocate-pointerless-words/immediate
+            (annotation . nfields))
+         (emit-allocate-pointerless-words/immediate asm (from-sp dst) nfields))
         (($ $primcall 'scm-ref annotation (obj idx))
          (emit-scm-ref asm (from-sp dst) (from-sp (slot obj))
                        (from-sp (slot idx))))
diff --git a/module/language/cps/effects-analysis.scm 
b/module/language/cps/effects-analysis.scm
index f5d6bb5..03a8fea 100644
--- a/module/language/cps/effects-analysis.scm
+++ b/module/language/cps/effects-analysis.scm
@@ -363,6 +363,13 @@ the LABELS that are clobbered by the effects of LABEL."
                                      ((ann . size)
                                       (&allocate
                                        (annotation->memory-kind ann)))))
+  ((allocate-pointerless-words size)
+                                   (&allocate (annotation->memory-kind param)))
+  ((allocate-pointerless-words/immediate)
+                                   (match param
+                                     ((ann . size)
+                                      (&allocate
+                                       (annotation->memory-kind ann)))))
   ((scm-ref obj idx)               (&read-object
                                     (annotation->memory-kind param)))
   ((scm-ref/tag obj)               (&read-field
diff --git a/module/language/cps/reify-primitives.scm 
b/module/language/cps/reify-primitives.scm
index 547ea59..8165fb2 100644
--- a/module/language/cps/reify-primitives.scm
+++ b/module/language/cps/reify-primitives.scm
@@ -416,7 +416,7 @@
                         ($primcall 'load-u64 %tc16-flonum ()))))
          (setk label ($kargs names vars
                        ($continue ktag0 src
-                         ($primcall 'allocate-words/immediate
+                         ($primcall 'allocate-pointerless-words/immediate
                                     `(flonum . ,(match (target-word-size)
                                                   (4 4)
                                                   (8 2)))
@@ -507,7 +507,14 @@
               ;; ((ulsh/immediate (u6? y) x) (ulsh x y))
               (_
                (match (cons name args)
-                 (('allocate-words/immediate)
+                 (((or 'allocate-words/immediate
+                       'allocate-pointerless-words/immediate))
+                  (define op
+                    (match name
+                      ('allocate-words/immediate
+                       'allocate-words)
+                      ('allocate-pointerless-words/immediate
+                       'allocate-pointerless-words)))
                   (match param
                     ((ann . n)
                      (if (u8? n)
@@ -516,7 +523,7 @@
                            (letv n*)
                            (letk kop ($kargs ('n) (n*)
                                        ($continue k src
-                                         ($primcall 'allocate-words ann 
(n*)))))
+                                         ($primcall op ann (n*)))))
                            (setk label ($kargs names vars
                                          ($continue kop src
                                            ($primcall 'load-u64 n ())))))))))
diff --git a/module/language/cps/specialize-primcalls.scm 
b/module/language/cps/specialize-primcalls.scm
index 51c10a2..6410d80 100644
--- a/module/language/cps/specialize-primcalls.scm
+++ b/module/language/cps/specialize-primcalls.scm
@@ -122,6 +122,8 @@
           (_ #f)))
       (specialize-case
         (('allocate-words (? uint? n)) (allocate-words/immediate n ()))
+        (('allocate-pointerless-words (? uint? n))
+         (allocate-pointerless-words/immediate n ()))
         (('scm-ref o (? uint? i)) (scm-ref/immediate i (o)))
         (('scm-set! o (? uint? i) x) (scm-set!/immediate i (o x)))
         ;; Assume (tail-)pointer-ref/immediate can always be emitted directly.
diff --git a/module/language/cps/types.scm b/module/language/cps/types.scm
index cf2fe91..0a06eb0 100644
--- a/module/language/cps/types.scm
+++ b/module/language/cps/types.scm
@@ -742,6 +742,10 @@ minimum, and maximum."
     ((annotation . size)
      (define! result (annotation->type annotation) size size))))
 
+(define-type-inferrer-aliases allocate-words allocate-pointerless-words)
+(define-type-inferrer-aliases allocate-words/immediate
+  allocate-pointerless-words/immediate)
+
 (define-type-inferrer/param (scm-ref param obj idx result)
   (restrict! obj (annotation->type param)
              (1+ (&min/0 idx)) (target-max-size-t/scm))
diff --git a/module/system/vm/assembler.scm b/module/system/vm/assembler.scm
index cb43110..a09e5f6 100644
--- a/module/system/vm/assembler.scm
+++ b/module/system/vm/assembler.scm
@@ -144,6 +144,8 @@
 
             emit-allocate-words
             emit-allocate-words/immediate
+            emit-allocate-pointerless-words
+            emit-allocate-pointerless-words/immediate
 
             emit-scm-ref
             emit-scm-set!



reply via email to

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