* Storing JIT Code
@ 2010-07-19 2:01 Noah Lavine
2010-08-19 5:58 ` Andy Wingo
0 siblings, 1 reply; 3+ messages in thread
From: Noah Lavine @ 2010-07-19 2:01 UTC (permalink / raw)
To: guile-devel
[-- Attachment #1: Type: text/plain, Size: 2189 bytes --]
Hello,
Attached are some patches I made for storing JIT code associated with
objcode objects. These are based on some threads a few weeks ago in
which we discussed how to handle JIT code, with the eventual goal of
adding a JIT compiler to Guile (I'm working on it).
The goal is to have a piece of JIT code associated with each objcode
object. Another possibility would be to associate them with procedure
objects, but that was rejected because it would make the procedure
object 5 words long, which might mess up caching.
I've tried two ways to do this so far: putting the JIT code in a
struct scm_objcode and putting it in the SCM object that always wraps
one of those structs. I tried the first way first, but I hit problems
because strings of bytecode are expected to be valid C structs, and
adding a pointer would require leaving more space there, which would
leak abstractions. Therefore, these patches implement the second way.
(A possible third way would be to put the JIT code in a property.)
The first patch adds the extra slot to the SCM object and initializes
it to C's NULL. This required changing a few functions in objcode.c to
make the SCMs differently. Unfortunately, I also had to change all of
the statically-generated objcode objects in continuations.c,
control.c, gsubr.c, foreign.c, and smob.c, so the patch is quite long.
The second patch adds some infrastructure to the VM to call a dummy
JIT compiler, cache its results, and run the resulting code if any is
generated. I set up a return convention so that the JIT compiler can
fail to compile things and the VM will run as usual, which I think
will be useful while there is a partially-complete compiler. (Although
I'm not convinced I've chosen the best values for it. Currently a NULL
jitcode means we've never tried to compile, and an SCM_BOOL_F means we
tried and failed, and therefore won't try again. Are there better
choices?)
I'm afraid these patches will require the set of small fixes I just
emailed, because one of the diffs modifies a comment that was added in
one of those patches. I believe the first patch is complete, but the
second patch is quite rough still. What do you think of them?
Noah
[-- Attachment #2: 0001-Add-JIT-pointers.patch --]
[-- Type: application/octet-stream, Size: 40413 bytes --]
From fde14a0a21c688978093c789899bd831f7ceb2da Mon Sep 17 00:00:00 2001
From: Noah Lavine <nlavine@haverford.edu>
Date: Sun, 18 Jul 2010 13:30:53 -0400
Subject: [PATCH] Add JIT pointers
Add a fifth machine word to the SCM objects that hold struct scm_objcodes to
store JIT code corresponding to that object code, and initialize them to
NULL.
---
libguile/continuations.c | 3 +-
libguile/control.c | 3 +-
libguile/foreign.c | 52 ++++---
libguile/gsubr.c | 374 ++++++++++++++++++++++++++++++---------------
libguile/objcodes.c | 37 ++++--
libguile/objcodes.h | 2 +
libguile/smob.c | 47 ++++--
7 files changed, 345 insertions(+), 173 deletions(-)
diff --git a/libguile/continuations.c b/libguile/continuations.c
index ed476a8..e9974e1 100644
--- a/libguile/continuations.c
+++ b/libguile/continuations.c
@@ -98,7 +98,8 @@ static const type sym##__unaligned[]
SCM_DECLARE_STATIC_ALIGNED_ARRAY (scm_t_uint8, sym##__bytecode); \
SCM_STATIC_ALIGNED_ARRAY (8, scm_t_cell, sym##__cells) = { \
{ STATIC_OBJCODE_TAG, SCM_PACK (sym##__bytecode) }, \
- { SCM_BOOL_F, SCM_PACK (0) } \
+ { SCM_BOOL_F, SCM_PACK (0) }, \
+ { NULL } \
}; \
static const SCM sym = SCM_PACK (sym##__cells); \
SCM_STATIC_ALIGNED_ARRAY (8, scm_t_uint8, sym##__bytecode)
diff --git a/libguile/control.c b/libguile/control.c
index caf79eb..fca39ab 100644
--- a/libguile/control.c
+++ b/libguile/control.c
@@ -105,7 +105,8 @@ static const type sym##__unaligned[]
SCM_DECLARE_STATIC_ALIGNED_ARRAY (scm_t_uint8, sym##__bytecode); \
SCM_STATIC_ALIGNED_ARRAY (8, scm_t_cell, sym##__cells) = { \
{ STATIC_OBJCODE_TAG, SCM_PACK (sym##__bytecode) }, \
- { SCM_BOOL_F, SCM_PACK (0) } \
+ { SCM_BOOL_F, SCM_PACK (0) }, \
+ { NULL } \
}; \
static const SCM sym = SCM_PACK (sym##__cells); \
SCM_STATIC_ALIGNED_ARRAY (8, scm_t_uint8, sym##__bytecode)
diff --git a/libguile/foreign.c b/libguile/foreign.c
index c541d13..6f68cba 100644
--- a/libguile/foreign.c
+++ b/libguile/foreign.c
@@ -788,20 +788,22 @@ static const struct
#undef CODE
#undef META
-#undef OBJCODE_HEADER
+/* don't undef OBJCODE_HEADER because the init function will use
+ * it to verify that it's the right size. */
#undef META_HEADER
/*
- (defun generate-objcode-cells (n)
- "Generate objcode cells for up to N arguments"
- (interactive "p")
- (let ((i 0))
- (while (< i n)
- (insert
- (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
- (* (+ 4 4 8 4 4 32) i)))
- (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
- (setq i (1+ i)))))
+(defun generate-objcode-cells (n)
+ "Generate objcode cells for up to N arguments"
+ (interactive "p")
+ (let ((i 0))
+ (while (< i n)
+ (insert
+ (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
+ (* (+ 4 4 8 4 4 32) i)))
+ (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
+ (insert " { NULL, 0 },\n")
+ (setq i (1+ i)))))
*/
#define STATIC_OBJCODE_TAG \
SCM_PACK (scm_tc7_objcode | (SCM_F_OBJCODE_IS_STATIC << 8))
@@ -809,45 +811,55 @@ static const struct
static const struct
{
scm_t_uint64 dummy; /* alignment */
- scm_t_cell cells[10 * 2]; /* 10 double cells */
+ scm_t_cell cells[10 * 3]; /* 10 six-word cells (last word unused) */
} objcode_cells = {
0,
/* C-u 1 0 M-x generate-objcode-cells RET */
- {
+ {
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 0) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 56) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 112) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 168) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 224) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 280) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 336) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 392) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 448) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 504) },
- { SCM_BOOL_F, SCM_PACK (0) }
+ { SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
}
};
static const SCM objcode_trampolines[10] = {
SCM_PACK (objcode_cells.cells+0),
- SCM_PACK (objcode_cells.cells+2),
- SCM_PACK (objcode_cells.cells+4),
+ SCM_PACK (objcode_cells.cells+3),
SCM_PACK (objcode_cells.cells+6),
- SCM_PACK (objcode_cells.cells+8),
- SCM_PACK (objcode_cells.cells+10),
+ SCM_PACK (objcode_cells.cells+9),
SCM_PACK (objcode_cells.cells+12),
- SCM_PACK (objcode_cells.cells+14),
- SCM_PACK (objcode_cells.cells+16),
+ SCM_PACK (objcode_cells.cells+15),
SCM_PACK (objcode_cells.cells+18),
+ SCM_PACK (objcode_cells.cells+21),
+ SCM_PACK (objcode_cells.cells+24),
+ SCM_PACK (objcode_cells.cells+27),
};
static SCM
diff --git a/libguile/gsubr.c b/libguile/gsubr.c
index af1c031..ceaddc6 100644
--- a/libguile/gsubr.c
+++ b/libguile/gsubr.c
@@ -274,36 +274,39 @@ static const struct
#undef AC
#undef BC
#undef ABC
-#undef OBJCODE_HEADER
+/* don't undef OBJCODE_HEADER because scm_init_gsubr will use it to verify
+ * that its size is correct. */
#undef META_HEADER
#undef META
/*
;; (nargs * nargs) + nopt + rest * (nargs + 1)
- (defun generate-objcode-cells-helper (n)
- "Generate objcode cells for N arguments"
- (interactive "p")
- (insert (format " /\* %d arguments *\/\n" n))
- (let ((nreq n))
- (while (<= 0 nreq)
- (let ((nopt (- n nreq)))
- (insert
- (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
- (* (+ 4 4 16 4 4 32)
- (+ (* n n) nopt))))
- (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
- (setq nreq (1- nreq))))
- (insert "\n")
- (setq nreq (1- n))
- (while (<= 0 nreq)
- (let ((nopt (- n nreq 1)))
- (insert
- (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
- (* (+ 4 4 16 4 4 32)
- (+ (* n n) nopt n 1))))
- (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
- (setq nreq (1- nreq))))
- (insert "\n")))
+(defun generate-objcode-cells-helper (n)
+ "Generate objcode cells for N arguments"
+ (interactive "p")
+ (insert (format " /\* %d arguments *\/\n" n))
+ (let ((nreq n))
+ (while (<= 0 nreq)
+ (let ((nopt (- n nreq)))
+ (insert
+ (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
+ (* (+ 4 4 16 4 4 32)
+ (+ (* n n) nopt))))
+ (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
+ (insert " { NULL, 0 },\n")
+ (setq nreq (1- nreq))))
+ (insert "\n")
+ (setq nreq (1- n))
+ (while (<= 0 nreq)
+ (let ((nopt (- n nreq 1)))
+ (insert
+ (format " { STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + %d) },\n"
+ (* (+ 4 4 16 4 4 32)
+ (+ (* n n) nopt n 1))))
+ (insert " { SCM_BOOL_F, SCM_PACK (0) },\n")
+ (insert " { NULL, 0 },\n")
+ (setq nreq (1- nreq))))
+ (insert "\n")))
(defun generate-objcode-cells (n)
"Generate objcode cells for up to N arguments"
@@ -320,7 +323,7 @@ static const struct
static const struct
{
scm_t_uint64 dummy; /* alignment */
- scm_t_cell cells[121 * 2]; /* 11*11 double cells */
+ scm_t_cell cells[121 * 3]; /* 11*11 triple cells (last word unused) */
} objcode_cells = {
0,
/* C-u 1 0 M-x generate-objcode-cells RET */
@@ -328,277 +331,398 @@ static const struct
/* 0 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 0) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 1 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 64) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 128) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 192) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 2 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 256) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 320) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 384) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 448) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 512) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 3 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 576) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 640) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 704) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 768) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 832) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 896) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 960) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 4 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1024) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1088) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1152) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1216) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1280) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1344) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1408) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1472) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1536) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 5 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1600) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1664) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1728) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1792) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1856) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1920) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 1984) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2048) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2112) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2176) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2240) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 6 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2304) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2368) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2432) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2496) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2560) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2624) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2688) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2752) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2816) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2880) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 2944) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3008) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3072) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 7 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3136) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3200) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3264) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3328) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3392) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3456) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3520) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3584) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3648) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3712) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3776) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3840) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3904) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 3968) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4032) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 8 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4096) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4160) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4224) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4288) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4352) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4416) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4480) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4544) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4608) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4672) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4736) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4800) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4864) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4928) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 4992) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5056) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5120) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 9 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5184) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5248) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5312) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5376) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5440) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5504) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5568) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5632) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5696) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5760) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5824) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5888) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 5952) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6016) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6080) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6144) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6208) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6272) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6336) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 10 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6400) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6464) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6528) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6592) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6656) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6720) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6784) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6848) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6912) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 6976) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7040) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7104) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7168) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7232) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7296) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7360) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7424) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7488) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7552) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7616) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 7680) },
- { SCM_BOOL_F, SCM_PACK (0) }
+ { SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
}
};
@@ -609,7 +733,7 @@ static const struct
(insert (format " /\* %d arguments *\/\n" n))
(let ((i (* n n)))
(while (< i (* (1+ n) (1+ n)))
- (insert (format " SCM_PACK (objcode_cells.cells+%d),\n" (* i 2)))
+ (insert (format " SCM_PACK (objcode_cells.cells+%d),\n" (* i 3)))
(setq i (1+ i)))
(insert "\n")))
@@ -627,144 +751,144 @@ static const SCM scm_subr_objcode_trampolines[121] = {
SCM_PACK (objcode_cells.cells+0),
/* 1 arguments */
- SCM_PACK (objcode_cells.cells+2),
- SCM_PACK (objcode_cells.cells+4),
+ SCM_PACK (objcode_cells.cells+3),
SCM_PACK (objcode_cells.cells+6),
+ SCM_PACK (objcode_cells.cells+9),
/* 2 arguments */
- SCM_PACK (objcode_cells.cells+8),
- SCM_PACK (objcode_cells.cells+10),
SCM_PACK (objcode_cells.cells+12),
- SCM_PACK (objcode_cells.cells+14),
- SCM_PACK (objcode_cells.cells+16),
-
- /* 3 arguments */
+ SCM_PACK (objcode_cells.cells+15),
SCM_PACK (objcode_cells.cells+18),
- SCM_PACK (objcode_cells.cells+20),
- SCM_PACK (objcode_cells.cells+22),
+ SCM_PACK (objcode_cells.cells+21),
SCM_PACK (objcode_cells.cells+24),
- SCM_PACK (objcode_cells.cells+26),
- SCM_PACK (objcode_cells.cells+28),
- SCM_PACK (objcode_cells.cells+30),
- /* 4 arguments */
- SCM_PACK (objcode_cells.cells+32),
- SCM_PACK (objcode_cells.cells+34),
+ /* 3 arguments */
+ SCM_PACK (objcode_cells.cells+27),
+ SCM_PACK (objcode_cells.cells+30),
+ SCM_PACK (objcode_cells.cells+33),
SCM_PACK (objcode_cells.cells+36),
- SCM_PACK (objcode_cells.cells+38),
- SCM_PACK (objcode_cells.cells+40),
+ SCM_PACK (objcode_cells.cells+39),
SCM_PACK (objcode_cells.cells+42),
- SCM_PACK (objcode_cells.cells+44),
- SCM_PACK (objcode_cells.cells+46),
- SCM_PACK (objcode_cells.cells+48),
+ SCM_PACK (objcode_cells.cells+45),
- /* 5 arguments */
- SCM_PACK (objcode_cells.cells+50),
- SCM_PACK (objcode_cells.cells+52),
+ /* 4 arguments */
+ SCM_PACK (objcode_cells.cells+48),
+ SCM_PACK (objcode_cells.cells+51),
SCM_PACK (objcode_cells.cells+54),
- SCM_PACK (objcode_cells.cells+56),
- SCM_PACK (objcode_cells.cells+58),
+ SCM_PACK (objcode_cells.cells+57),
SCM_PACK (objcode_cells.cells+60),
- SCM_PACK (objcode_cells.cells+62),
- SCM_PACK (objcode_cells.cells+64),
+ SCM_PACK (objcode_cells.cells+63),
SCM_PACK (objcode_cells.cells+66),
- SCM_PACK (objcode_cells.cells+68),
- SCM_PACK (objcode_cells.cells+70),
-
- /* 6 arguments */
+ SCM_PACK (objcode_cells.cells+69),
SCM_PACK (objcode_cells.cells+72),
- SCM_PACK (objcode_cells.cells+74),
- SCM_PACK (objcode_cells.cells+76),
+
+ /* 5 arguments */
+ SCM_PACK (objcode_cells.cells+75),
SCM_PACK (objcode_cells.cells+78),
- SCM_PACK (objcode_cells.cells+80),
- SCM_PACK (objcode_cells.cells+82),
+ SCM_PACK (objcode_cells.cells+81),
SCM_PACK (objcode_cells.cells+84),
- SCM_PACK (objcode_cells.cells+86),
- SCM_PACK (objcode_cells.cells+88),
+ SCM_PACK (objcode_cells.cells+87),
SCM_PACK (objcode_cells.cells+90),
- SCM_PACK (objcode_cells.cells+92),
- SCM_PACK (objcode_cells.cells+94),
+ SCM_PACK (objcode_cells.cells+93),
SCM_PACK (objcode_cells.cells+96),
-
- /* 7 arguments */
- SCM_PACK (objcode_cells.cells+98),
- SCM_PACK (objcode_cells.cells+100),
+ SCM_PACK (objcode_cells.cells+99),
SCM_PACK (objcode_cells.cells+102),
- SCM_PACK (objcode_cells.cells+104),
- SCM_PACK (objcode_cells.cells+106),
+ SCM_PACK (objcode_cells.cells+105),
+
+ /* 6 arguments */
SCM_PACK (objcode_cells.cells+108),
- SCM_PACK (objcode_cells.cells+110),
- SCM_PACK (objcode_cells.cells+112),
+ SCM_PACK (objcode_cells.cells+111),
SCM_PACK (objcode_cells.cells+114),
- SCM_PACK (objcode_cells.cells+116),
- SCM_PACK (objcode_cells.cells+118),
+ SCM_PACK (objcode_cells.cells+117),
SCM_PACK (objcode_cells.cells+120),
- SCM_PACK (objcode_cells.cells+122),
- SCM_PACK (objcode_cells.cells+124),
+ SCM_PACK (objcode_cells.cells+123),
SCM_PACK (objcode_cells.cells+126),
-
- /* 8 arguments */
- SCM_PACK (objcode_cells.cells+128),
- SCM_PACK (objcode_cells.cells+130),
+ SCM_PACK (objcode_cells.cells+129),
SCM_PACK (objcode_cells.cells+132),
- SCM_PACK (objcode_cells.cells+134),
- SCM_PACK (objcode_cells.cells+136),
+ SCM_PACK (objcode_cells.cells+135),
SCM_PACK (objcode_cells.cells+138),
- SCM_PACK (objcode_cells.cells+140),
- SCM_PACK (objcode_cells.cells+142),
+ SCM_PACK (objcode_cells.cells+141),
SCM_PACK (objcode_cells.cells+144),
- SCM_PACK (objcode_cells.cells+146),
- SCM_PACK (objcode_cells.cells+148),
+
+ /* 7 arguments */
+ SCM_PACK (objcode_cells.cells+147),
SCM_PACK (objcode_cells.cells+150),
- SCM_PACK (objcode_cells.cells+152),
- SCM_PACK (objcode_cells.cells+154),
+ SCM_PACK (objcode_cells.cells+153),
SCM_PACK (objcode_cells.cells+156),
- SCM_PACK (objcode_cells.cells+158),
- SCM_PACK (objcode_cells.cells+160),
-
- /* 9 arguments */
+ SCM_PACK (objcode_cells.cells+159),
SCM_PACK (objcode_cells.cells+162),
- SCM_PACK (objcode_cells.cells+164),
- SCM_PACK (objcode_cells.cells+166),
+ SCM_PACK (objcode_cells.cells+165),
SCM_PACK (objcode_cells.cells+168),
- SCM_PACK (objcode_cells.cells+170),
- SCM_PACK (objcode_cells.cells+172),
+ SCM_PACK (objcode_cells.cells+171),
SCM_PACK (objcode_cells.cells+174),
- SCM_PACK (objcode_cells.cells+176),
- SCM_PACK (objcode_cells.cells+178),
+ SCM_PACK (objcode_cells.cells+177),
SCM_PACK (objcode_cells.cells+180),
- SCM_PACK (objcode_cells.cells+182),
- SCM_PACK (objcode_cells.cells+184),
+ SCM_PACK (objcode_cells.cells+183),
SCM_PACK (objcode_cells.cells+186),
- SCM_PACK (objcode_cells.cells+188),
- SCM_PACK (objcode_cells.cells+190),
+ SCM_PACK (objcode_cells.cells+189),
+
+ /* 8 arguments */
SCM_PACK (objcode_cells.cells+192),
- SCM_PACK (objcode_cells.cells+194),
- SCM_PACK (objcode_cells.cells+196),
+ SCM_PACK (objcode_cells.cells+195),
SCM_PACK (objcode_cells.cells+198),
-
- /* 10 arguments */
- SCM_PACK (objcode_cells.cells+200),
- SCM_PACK (objcode_cells.cells+202),
+ SCM_PACK (objcode_cells.cells+201),
SCM_PACK (objcode_cells.cells+204),
- SCM_PACK (objcode_cells.cells+206),
- SCM_PACK (objcode_cells.cells+208),
+ SCM_PACK (objcode_cells.cells+207),
SCM_PACK (objcode_cells.cells+210),
- SCM_PACK (objcode_cells.cells+212),
- SCM_PACK (objcode_cells.cells+214),
+ SCM_PACK (objcode_cells.cells+213),
SCM_PACK (objcode_cells.cells+216),
- SCM_PACK (objcode_cells.cells+218),
- SCM_PACK (objcode_cells.cells+220),
+ SCM_PACK (objcode_cells.cells+219),
SCM_PACK (objcode_cells.cells+222),
- SCM_PACK (objcode_cells.cells+224),
- SCM_PACK (objcode_cells.cells+226),
+ SCM_PACK (objcode_cells.cells+225),
SCM_PACK (objcode_cells.cells+228),
- SCM_PACK (objcode_cells.cells+230),
- SCM_PACK (objcode_cells.cells+232),
+ SCM_PACK (objcode_cells.cells+231),
SCM_PACK (objcode_cells.cells+234),
- SCM_PACK (objcode_cells.cells+236),
- SCM_PACK (objcode_cells.cells+238),
- SCM_PACK (objcode_cells.cells+240)
+ SCM_PACK (objcode_cells.cells+237),
+ SCM_PACK (objcode_cells.cells+240),
+
+ /* 9 arguments */
+ SCM_PACK (objcode_cells.cells+243),
+ SCM_PACK (objcode_cells.cells+246),
+ SCM_PACK (objcode_cells.cells+249),
+ SCM_PACK (objcode_cells.cells+252),
+ SCM_PACK (objcode_cells.cells+255),
+ SCM_PACK (objcode_cells.cells+258),
+ SCM_PACK (objcode_cells.cells+261),
+ SCM_PACK (objcode_cells.cells+264),
+ SCM_PACK (objcode_cells.cells+267),
+ SCM_PACK (objcode_cells.cells+270),
+ SCM_PACK (objcode_cells.cells+273),
+ SCM_PACK (objcode_cells.cells+276),
+ SCM_PACK (objcode_cells.cells+279),
+ SCM_PACK (objcode_cells.cells+282),
+ SCM_PACK (objcode_cells.cells+285),
+ SCM_PACK (objcode_cells.cells+288),
+ SCM_PACK (objcode_cells.cells+291),
+ SCM_PACK (objcode_cells.cells+294),
+ SCM_PACK (objcode_cells.cells+297),
+
+ /* 10 arguments */
+ SCM_PACK (objcode_cells.cells+300),
+ SCM_PACK (objcode_cells.cells+303),
+ SCM_PACK (objcode_cells.cells+306),
+ SCM_PACK (objcode_cells.cells+309),
+ SCM_PACK (objcode_cells.cells+312),
+ SCM_PACK (objcode_cells.cells+315),
+ SCM_PACK (objcode_cells.cells+318),
+ SCM_PACK (objcode_cells.cells+321),
+ SCM_PACK (objcode_cells.cells+324),
+ SCM_PACK (objcode_cells.cells+327),
+ SCM_PACK (objcode_cells.cells+330),
+ SCM_PACK (objcode_cells.cells+333),
+ SCM_PACK (objcode_cells.cells+336),
+ SCM_PACK (objcode_cells.cells+339),
+ SCM_PACK (objcode_cells.cells+342),
+ SCM_PACK (objcode_cells.cells+345),
+ SCM_PACK (objcode_cells.cells+348),
+ SCM_PACK (objcode_cells.cells+351),
+ SCM_PACK (objcode_cells.cells+354),
+ SCM_PACK (objcode_cells.cells+357),
+ SCM_PACK (objcode_cells.cells+360),
};
/* (nargs * nargs) + nopt + rest * (nargs + 1) */
diff --git a/libguile/objcodes.c b/libguile/objcodes.c
index 41a5990..767c0ac 100644
--- a/libguile/objcodes.c
+++ b/libguile/objcodes.c
@@ -44,11 +44,13 @@ verify (((sizeof (SCM_OBJCODE_COOKIE) - 1) & 7) == 0);
* Objcode type
*/
-/* an objcode SCM object is a four-word object containing
+/* an objcode SCM object is a five-word object containing
- scm_tc7_objcode | the flags for this objcode
- the struct scm_objcode C object
- the parent of this objcode, if this is a slice, or #f if none
- the file descriptor this objcode came from if this was mmaped, or 0 if none
+ - the JIT code for this object, NULL if we've never tried to JIT this,
+ and #f if we tried and failed.
*/
static SCM
@@ -97,10 +99,12 @@ make_objcode_by_mmap (int fd)
+ data->metalen)));
}
- sret = scm_double_cell (scm_tc7_objcode | (SCM_F_OBJCODE_IS_MMAP<<8),
- (scm_t_bits)(addr + strlen (SCM_OBJCODE_COOKIE)),
- SCM_UNPACK (SCM_BOOL_F),
- (scm_t_bits)fd);
+ sret = scm_words (scm_tc7_objcode | (SCM_F_OBJCODE_IS_MMAP<<8), 5);
+ SCM_GC_SET_CELL_WORD (sret, 1,
+ (scm_t_bits)(addr + strlen(SCM_OBJCODE_COOKIE)));
+ SCM_GC_SET_CELL_WORD (sret, 2, SCM_UNPACK (SCM_BOOL_F));
+ SCM_GC_SET_CELL_WORD (sret, 3, (scm_t_bits)fd);
+ SCM_GC_SET_CELL_WORD (sret, 4, (scm_t_bits)NULL);
/* FIXME: we leak ourselves and the file descriptor. but then again so does
dlopen(). */
@@ -114,6 +118,7 @@ scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr)
{
const struct scm_objcode *data, *parent_data;
const scm_t_uint8 *parent_base;
+ SCM ret;
SCM_VALIDATE_OBJCODE (1, parent);
parent_data = SCM_OBJCODE_DATA (parent);
@@ -137,8 +142,12 @@ scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr)
assert (SCM_C_OBJCODE_BASE (data) + data->len + data->metalen
<= parent_base + parent_data->len + parent_data->metalen);
- return scm_double_cell (scm_tc7_objcode | (SCM_F_OBJCODE_IS_SLICE<<8),
- (scm_t_bits)data, SCM_UNPACK (parent), 0);
+ ret = scm_words (scm_tc7_objcode, 5);
+ SCM_GC_SET_CELL_WORD (ret, 1, (scm_t_bits)data);
+ SCM_GC_SET_CELL_WORD (ret, 2, SCM_UNPACK (parent));
+ SCM_GC_SET_CELL_WORD (ret, 3, 0);
+ SCM_GC_SET_CELL_WORD (ret, 4, NULL);
+ return ret;
}
#undef FUNC_NAME
@@ -179,7 +188,8 @@ SCM_DEFINE (scm_bytecode_to_objcode, "bytecode->objcode", 1, 0, 0,
size_t size;
const scm_t_uint8 *c_bytecode;
struct scm_objcode *data;
-
+ SCM ret;
+
if (!scm_is_bytevector (bytecode))
scm_wrong_type_arg (FUNC_NAME, 1, bytecode);
@@ -187,17 +197,22 @@ SCM_DEFINE (scm_bytecode_to_objcode, "bytecode->objcode", 1, 0, 0,
c_bytecode = (const scm_t_uint8*)SCM_BYTEVECTOR_CONTENTS (bytecode);
SCM_ASSERT_RANGE (0, bytecode, size >= sizeof(struct scm_objcode));
+
data = (struct scm_objcode*)c_bytecode;
if (data->len + data->metalen != (size - sizeof (*data)))
scm_misc_error (FUNC_NAME, "bad bytevector size (~a != ~a)",
scm_list_2 (scm_from_size_t (size),
scm_from_uint32 (sizeof (*data) + data->len + data->metalen)));
-
+
/* foolishly, we assume that as long as bytecode is around, that c_bytecode
will be of the same length; perhaps a bad assumption? */
- return scm_double_cell (scm_tc7_objcode | (SCM_F_OBJCODE_IS_BYTEVECTOR<<8),
- (scm_t_bits)data, SCM_UNPACK (bytecode), 0);
+ ret = scm_words (scm_tc7_objcode | (SCM_F_OBJCODE_IS_BYTEVECTOR<<8), 5);
+ SCM_GC_SET_CELL_WORD (ret, 1, (scm_t_bits)data);
+ SCM_GC_SET_CELL_WORD (ret, 2, SCM_UNPACK (bytecode));
+ SCM_GC_SET_CELL_WORD (ret, 3, 0);
+ SCM_GC_SET_CELL_WORD (ret, 4, NULL);
+ return ret;
}
#undef FUNC_NAME
diff --git a/libguile/objcodes.h b/libguile/objcodes.h
index 2bff9aa..b92e8ef 100644
--- a/libguile/objcodes.h
+++ b/libguile/objcodes.h
@@ -54,6 +54,8 @@ struct scm_objcode
#define SCM_OBJCODE_IS_BYTEVECTOR(x) (SCM_OBJCODE_FLAGS (x) & SCM_F_OBJCODE_IS_BYTEVECTOR)
#define SCM_OBJCODE_IS_SLICE(x) (SCM_OBJCODE_FLAGS (x) & SCM_F_OBJCODE_IS_SLICE)
+#define SCM_OBJCODE_JITCODE(x) (SCM_CELL_WORD ((x), 4))
+
SCM scm_c_make_objcode_slice (SCM parent, const scm_t_uint8 *ptr);
SCM_API SCM scm_load_objcode (SCM file);
SCM_API SCM scm_objcode_p (SCM obj);
diff --git a/libguile/smob.c b/libguile/smob.c
index 6582612..7d8abb2 100644
--- a/libguile/smob.c
+++ b/libguile/smob.c
@@ -261,7 +261,7 @@ static const struct
static const struct
{
scm_t_uint64 dummy; /* alignment */
- scm_t_cell cells[16 * 2]; /* 4*4 double cells */
+ scm_t_cell cells[16 * 3]; /* 4*4 triple cells (last cell unused) */
} objcode_cells = {
0,
/* C-u 3 M-x generate-objcode-cells RET */
@@ -269,45 +269,62 @@ static const struct
/* 0 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 0) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
+
/* 1 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 64) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 128) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 192) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 2 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 256) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 320) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 384) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 448) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 512) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
/* 3 arguments */
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 576) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 640) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 704) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 768) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 832) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 896) },
{ SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
{ STATIC_OBJCODE_TAG, SCM_PACK (raw_bytecode.bytes + 960) },
- { SCM_BOOL_F, SCM_PACK (0) }
+ { SCM_BOOL_F, SCM_PACK (0) },
+ { NULL, 0 },
}
};
@@ -317,25 +334,25 @@ static const SCM scm_smob_objcode_trampolines[16] = {
SCM_PACK (objcode_cells.cells+0),
/* 1 arguments */
- SCM_PACK (objcode_cells.cells+2),
- SCM_PACK (objcode_cells.cells+4),
+ SCM_PACK (objcode_cells.cells+3),
SCM_PACK (objcode_cells.cells+6),
+ SCM_PACK (objcode_cells.cells+9),
/* 2 arguments */
- SCM_PACK (objcode_cells.cells+8),
- SCM_PACK (objcode_cells.cells+10),
SCM_PACK (objcode_cells.cells+12),
- SCM_PACK (objcode_cells.cells+14),
- SCM_PACK (objcode_cells.cells+16),
-
- /* 3 arguments */
+ SCM_PACK (objcode_cells.cells+15),
SCM_PACK (objcode_cells.cells+18),
- SCM_PACK (objcode_cells.cells+20),
- SCM_PACK (objcode_cells.cells+22),
+ SCM_PACK (objcode_cells.cells+21),
SCM_PACK (objcode_cells.cells+24),
- SCM_PACK (objcode_cells.cells+26),
- SCM_PACK (objcode_cells.cells+28),
- SCM_PACK (objcode_cells.cells+30)
+
+ /* 3 arguments */
+ SCM_PACK (objcode_cells.cells+27),
+ SCM_PACK (objcode_cells.cells+30),
+ SCM_PACK (objcode_cells.cells+33),
+ SCM_PACK (objcode_cells.cells+36),
+ SCM_PACK (objcode_cells.cells+39),
+ SCM_PACK (objcode_cells.cells+42),
+ SCM_PACK (objcode_cells.cells+45),
};
/* (nargs * nargs) + nopt + rest * (nargs + 1) */
--
1.7.1
[-- Attachment #3: 0002-Add-JIT-Infrastructure.patch --]
[-- Type: application/octet-stream, Size: 8670 bytes --]
From 10d47c5561917eb0b9b7fc5a3ef0154ff38925fc Mon Sep 17 00:00:00 2001
From: Noah Lavine <nlavine@haverford.edu>
Date: Sun, 18 Jul 2010 13:35:27 -0400
Subject: [PATCH] Add JIT Infrastructure
Add a dummy JIT compiler, and the infrastructure to invoke it on object code,
run the JIT code if it's generated, and cache the JIT code for future use.
---
libguile/Makefile.am | 2 +
libguile/init.c | 4 ++-
libguile/vm-engine.c | 22 ++++++++++++++++-
libguile/vm-engine.h | 2 +
libguile/vm-i-system.c | 17 +++++++++++++
libguile/vm-jit.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
libguile/vm-jit.h | 39 +++++++++++++++++++++++++++++++
7 files changed, 144 insertions(+), 2 deletions(-)
create mode 100644 libguile/vm-jit.c
create mode 100644 libguile/vm-jit.h
diff --git a/libguile/Makefile.am b/libguile/Makefile.am
index 5eea8dc..3da0009 100644
--- a/libguile/Makefile.am
+++ b/libguile/Makefile.am
@@ -210,6 +210,7 @@ libguile_@GUILE_EFFECTIVE_VERSION@_la_SOURCES = \
vectors.c \
version.c \
vm.c \
+ vm-jit.c \
vports.c \
weaks.c
@@ -583,6 +584,7 @@ modinclude_HEADERS = \
vectors.h \
vm-engine.h \
vm-expand.h \
+ vm-jit.h \
vm.h \
vports.h \
weaks.h
diff --git a/libguile/init.c b/libguile/init.c
index 4843910..7c88a4a 100644
--- a/libguile/init.c
+++ b/libguile/init.c
@@ -128,6 +128,7 @@
#include "libguile/vectors.h"
#include "libguile/version.h"
#include "libguile/vm.h"
+#include "libguile/vm-jit.h"
#include "libguile/vports.h"
#include "libguile/weaks.h"
#include "libguile/guardians.h"
@@ -546,7 +547,8 @@ scm_i_init_guile (SCM_STACKITEM *base)
scm_init_weaks ();
scm_init_guardians (); /* requires smob_prehistory */
scm_init_vports ();
- scm_init_standard_ports (); /* Requires fports */
+ scm_init_jit ();
+ scm_init_standard_ports (); /* Requires fports, jit */
scm_init_expand (); /* Requires structs */
scm_init_memoize (); /* Requires smob_prehistory */
scm_init_eval (); /* Requires smob_prehistory */
diff --git a/libguile/vm-engine.c b/libguile/vm-engine.c
index 7f4641a..a567a85 100644
--- a/libguile/vm-engine.c
+++ b/libguile/vm-engine.c
@@ -31,7 +31,7 @@
#endif
#include "vm-engine.h"
-
+#include "tags.h" /* for SCM_BOOL_F */
static SCM
VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
@@ -47,6 +47,7 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
SCM *objects = NULL; /* constant objects */
size_t object_count = 0; /* length of OBJECTS */
SCM *stack_limit = vp->stack_limit; /* stack limit address */
+ jitf *jitcode = NULL; /* JIT code, if any */
SCM dynstate = SCM_I_CURRENT_THREAD->dynamic_state;
scm_t_int64 vm_cookie = vp->cookie++;
@@ -80,6 +81,10 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
{
SCM prog = program;
+ /* program could also be a smob. maybe other things? */
+ if (SCM_PROGRAM_P(program))
+ jitcode = (jitf *)SCM_OBJCODE_JITCODE(SCM_PROGRAM_OBJCODE(program));
+
/* Boot program */
program = vm_make_boot_program (nargs);
@@ -105,6 +110,21 @@ VM_NAME (SCM vm, SCM program, SCM *argv, int nargs)
/* Let's go! */
BOOT_HOOK ();
+
+ if (jitcode == NULL) {
+ jitcode = jit_objcode(bp);
+ SCM_OBJCODE_JITCODE(SCM_PROGRAM_OBJCODE(program)) = jitcode;
+ }
+ if (jitcode != SCM_BOOL_F) {
+ scm_t_uint8 *sip = ip;
+ SCM *ssp = sp;
+ SCM *sfp = fp;
+ SCM_JITCODE_ENTER(jitcode, sip, ssp, sfp);
+ ip = sip;
+ sp = ssp;
+ fp = sfp;
+ }
+ /* if the jitcode runs, we'll still want to do NEXT afterwards */
NEXT;
#ifndef HAVE_LABELS_AS_VALUES
diff --git a/libguile/vm-engine.h b/libguile/vm-engine.h
index 836648c..b90e481 100644
--- a/libguile/vm-engine.h
+++ b/libguile/vm-engine.h
@@ -90,6 +90,8 @@
#define FP_REG
#endif
+#include "vm-jit.h"
+
\f
/*
* Cache/Sync
diff --git a/libguile/vm-i-system.c b/libguile/vm-i-system.c
index 11f8ae0..5499bcf 100644
--- a/libguile/vm-i-system.c
+++ b/libguile/vm-i-system.c
@@ -744,6 +744,7 @@ VM_DEFINE_INSTRUCTION (53, new_frame, "new-frame", 0, 0, 3)
VM_DEFINE_INSTRUCTION (54, call, "call", 1, -1, 1)
{
+ (jitf *)jitcode = NULL;
nargs = FETCH ();
vm_call:
@@ -778,6 +779,22 @@ VM_DEFINE_INSTRUCTION (54, call, "call", 1, -1, 1)
ip = SCM_C_OBJCODE_BASE (bp);
ENTER_HOOK ();
APPLY_HOOK ();
+
+ jitcode = SCM_OBJCODE_JITCODE(SCM_PROGRAM_OBJCODE(program));
+ if (jitcode == NULL) {
+ jitcode = jit_objcode(bp);
+ SCM_OBJCODE_JITCODE(SCM_PROGRAM_OBJCODE(program)) = jitcode;
+ }
+ if (jitcode != SCM_BOOL_F) {
+ scm_t_uint8 *sip = ip;
+ SCM *ssp = sp;
+ SCM *sfp = fp;
+ SCM_JITCODE_ENTER(jitcode, sip, ssp, sfp);
+ ip = sip;
+ sp = ssp;
+ fp = sfp;
+ }
+ /* if the jitcode runs, we'll still want to do NEXT afterwards */
NEXT;
}
diff --git a/libguile/vm-jit.c b/libguile/vm-jit.c
new file mode 100644
index 0000000..d9a4a08
--- /dev/null
+++ b/libguile/vm-jit.c
@@ -0,0 +1,60 @@
+#include <stdio.h>
+
+#include "libguile/instructions.h"
+#include "libguile/snarf.h"
+#include "libguile/objcodes.h"
+#include "libguile/symbols.h"
+#include "libguile/list.h"
+#include "libguile/tags.h"
+#include "libguile/strings.h" /* for scm_from_locale_string, for the init function */
+#include "libguile/struct.h"
+#include "libguile/numbers.h"
+
+#include "libguile/vm-jit.h" /* defines struct scm_jit_code */
+#include "lightning.h"
+
+/* SCM jitcode_vtable = NULL; */
+
+/* jit_objcode: this procedure either JITs the given object code, and returns a
+ * pointer to an scm_jit_code object with the results, or SCM_BOOL_F if it
+ * couldn't jit the code. this will most likely occur if the jitter hits an
+ * object code that it doesn't know how to translate. */
+jitf *jit_objcode(struct scm_objcode *objcode)
+{
+ /* SCM code; */
+ jitf *code;
+ jit_insn *buffer, *end;
+
+ buffer = scm_gc_calloc(32 * sizeof (jit_insn), "JIT instruction buffer");
+ if (buffer == NULL)
+ return (jitf *)SCM_BOOL_F;
+
+ /* Make a test function */
+ jit_set_ip(buffer);
+ jit_prolog(3);
+ jit_movi_p(JIT_R0, "JIT code called!\n");
+ jit_prepare(1);
+ jit_pusharg_p(JIT_R0);
+ jit_finish(printf);
+ jit_ret();
+
+ end = (jit_insn *)jit_get_ip().ptr;
+ jit_flush_code(buffer, end);
+
+ /* Make the struct */
+ /* code = scm_c_make_structv(jitcode_vtable, 1, 1, (scm_t_bits *)buffer); */
+ code = scm_gc_malloc (sizeof (jitf *), "a table of pointers to machine code");
+ if (code == NULL)
+ return (jitf *)SCM_BOOL_F;
+
+ *code = (jitf *)buffer;
+
+ return code;
+}
+
+void scm_init_jit (void)
+{
+ /* jitcode_vtable = scm_make_vtable (scm_from_locale_string("pO"), SCM_UNDEFINED); */
+
+ return;
+}
diff --git a/libguile/vm-jit.h b/libguile/vm-jit.h
new file mode 100644
index 0000000..8251fef
--- /dev/null
+++ b/libguile/vm-jit.h
@@ -0,0 +1,39 @@
+#ifndef _SCM_VM_JIT_H_
+#define _SCM_VM_JIT_H_
+
+#include "_scm.h"
+#include "libguile/struct.h"
+
+/* jitted code for a procedure will be stored as an array of pointers to the
+ * blocks of the machine code. the generated machine code will expect this array
+ * to be available (how?) when it is called, and all machine code branches will
+ * indirect through this array. this is done to make the code relocatable: as
+ * long as the block array points to the correct blocks, then the code can be
+ * loaded anywhere in memory. this is important because it will allow us to
+ * store the code to a .go file and mmap() it back into memory and have it still
+ * work, which will allow fast startups. if we're storing code for a procedure,
+ * the first pointer in the block array will point to the procedure entry point.
+ *
+ * a block is a basic block of the object code. it's not really a basic block
+ * from the JIT perspective, because all of the instructions are implemented as
+ * calls to C functions.
+ *
+ * (one could also implement position-independent code by only using relative
+ * branches, but it's not clear that GNU Lightning supports this, so I'll use
+ * the table method.) */
+
+typedef void (*jitf)(void *block_pointers, scm_t_uint8 **ip,
+ SCM **sp, SCM **fp);
+
+/* the first block is number 1. */
+#define SCM_C_JITCODE_BLOCK(block_pointers, n) \
+ (*((block_pointers) + (n) - 1))
+ /* SCM_STRUCT_SLOT_REF(obj, n - 1) */
+#define SCM_JITCODE_ENTER(obj, ip, sp, fp) \
+ ((jitf)(SCM_C_JITCODE_BLOCK(obj, 1)))(SCM_C_JITCODE_BLOCK(obj, 1), &ip, &sp, &fp)
+
+jitf *jit_objcode(struct scm_objcode *objcode);
+
+void scm_init_jit (void);
+
+#endif /* not _SCM_VM_JIT_H_ */
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Storing JIT Code
2010-07-19 2:01 Storing JIT Code Noah Lavine
@ 2010-08-19 5:58 ` Andy Wingo
2010-08-19 12:40 ` Noah Lavine
0 siblings, 1 reply; 3+ messages in thread
From: Andy Wingo @ 2010-08-19 5:58 UTC (permalink / raw)
To: Noah Lavine; +Cc: guile-devel
Hi Noah,
On Sun 18 Jul 2010 19:01, Noah Lavine <noah.b.lavine@gmail.com> writes:
> Attached are some patches I made for storing JIT code associated with
> objcode objects. These are based on some threads a few weeks ago in
> which we discussed how to handle JIT code, with the eventual goal of
> adding a JIT compiler to Guile (I'm working on it).
Very interesting patches. They are a good start. Have you gone further
with them?
We should be able to coalesce the "fd" field of objcode with "parent",
as they are mutually exclusive, so perhaps we can have a fourth word in
objcode for jitted code.
Andy
--
http://wingolog.org/
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Storing JIT Code
2010-08-19 5:58 ` Andy Wingo
@ 2010-08-19 12:40 ` Noah Lavine
0 siblings, 0 replies; 3+ messages in thread
From: Noah Lavine @ 2010-08-19 12:40 UTC (permalink / raw)
To: Andy Wingo; +Cc: guile-devel
> Very interesting patches. They are a good start. Have you gone further
> with them?
Thanks! I'm trying to, but it's not working yet. (Currently it'll
print "Jit code called!" a couple times and then segfault.)
> We should be able to coalesce the "fd" field of objcode with "parent",
> as they are mutually exclusive, so perhaps we can have a fourth word in
> objcode for jitted code.
Oh, that's great!
Noah
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-08-19 12:40 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-19 2:01 Storing JIT Code Noah Lavine
2010-08-19 5:58 ` Andy Wingo
2010-08-19 12:40 ` Noah Lavine
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).