summaryrefslogtreecommitdiff
path: root/libguile/vm-i-scheme.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-05-01 00:31:18 +0200
committerAndy Wingo <wingo@pobox.com>2010-05-01 00:31:18 +0200
commit9a974fd38438eee10a2e5389c14129193c833860 (patch)
tree7c81a896c61ef67e417d9dabe9fba215d1a6ccb0 /libguile/vm-i-scheme.c
parent52272fc764d0ca3eee00dcf7f1f51734198ad777 (diff)
downloadguile-9a974fd38438eee10a2e5389c14129193c833860.tar.gz
optimize and bugfix make-struct VM opcode
* libguile/_scm.h (SCM_OBJCODE_MINOR_VERSION): Bump for make-struct change. * libguile/struct.c (scm_i_alloc_struct): Use scm_words instead of scm_gc_malloc to simplify the code and inline the call to GC_MALLOC. * module/language/tree-il/compile-glil.scm (*primcall-ops*): Compile make-struct/no-tail to make-struct. * module/language/tree-il/primitives.scm (define-primitive-expander): Allow a conditional branch of #f to aboirt inlining. (make-struct): Expand into make-struct/no-tail in the case that tail-size is 0. * libguile/vm-i-scheme.c (make-struct): Adapt to always assume tail-size is 0. Inline allocation if possible. Don't decrement the SP past live objects on the stack, which could cause GC to miss references. Use the NULLSTACK macro.
Diffstat (limited to 'libguile/vm-i-scheme.c')
-rw-r--r--libguile/vm-i-scheme.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/libguile/vm-i-scheme.c b/libguile/vm-i-scheme.c
index 3e31691cc..f076d6b8c 100644
--- a/libguile/vm-i-scheme.c
+++ b/libguile/vm-i-scheme.c
@@ -420,36 +420,34 @@ VM_DEFINE_INSTRUCTION (166, make_struct, "make-struct", 2, -1, 1)
{
unsigned h = FETCH ();
unsigned l = FETCH ();
- scm_t_bits n_args = ((h << 8U) + l);
- SCM vtable = sp[1 - n_args], n_tail = sp[2 - n_args];
- const SCM *inits = sp - n_args + 3;
-
- sp -= n_args - 1;
+ scm_t_bits n = ((h << 8U) + l);
+ SCM vtable = sp[-(n - 1)];
+ const SCM *inits = sp - n + 2;
+ SCM ret;
SYNC_REGISTER ();
if (SCM_LIKELY (SCM_STRUCTP (vtable)
&& SCM_VTABLE_FLAG_IS_SET (vtable, SCM_VTABLE_FLAG_SIMPLE)
- && SCM_I_INUMP (n_tail)))
+ && (SCM_STRUCT_DATA_REF (vtable, scm_vtable_index_size) + 1
+ == n)
+ && !SCM_VTABLE_INSTANCE_FINALIZER (vtable)))
{
- scm_t_bits n_inits, len;
-
- n_inits = SCM_I_INUM (n_tail) + n_args - 2;
- len = SCM_STRUCT_DATA_REF (vtable, scm_vtable_index_size);
-
- if (SCM_LIKELY (n_inits == len))
- {
- SCM obj;
-
- obj = scm_i_alloc_struct (SCM_STRUCT_DATA (vtable), n_inits);
- memcpy (SCM_STRUCT_DATA (obj), inits, n_inits * sizeof (SCM));
-
- RETURN (obj);
- }
+ /* Verily, we are making a simple struct with the right number of
+ initializers, and no finalizer. */
+ ret = scm_words ((scm_t_bits)SCM_STRUCT_DATA (vtable) | scm_tc3_struct,
+ n + 1);
+ SCM_SET_CELL_WORD_1 (ret, (scm_t_bits)SCM_CELL_OBJECT_LOC (ret, 2));
+ memcpy (SCM_STRUCT_DATA (ret), inits, (n - 1) * sizeof (SCM));
}
+ else
+ ret = scm_c_make_structv (vtable, 0, n - 1, (scm_t_bits *) inits);
- RETURN (scm_c_make_structv (vtable, scm_to_size_t (n_tail),
- n_args - 2, (scm_t_bits *) inits));
+ sp -= n;
+ NULLSTACK (n);
+ PUSH (ret);
+
+ NEXT;
}
VM_DEFINE_FUNCTION (167, struct_ref, "struct-ref", 2)