finally return h)
"Hash table lap-op -> stack adjustment."))
+(cl-defstruct comp-data-container
+ "Data relocation container structure."
+ (l () :type list
+ :documentation "Constant objects used by functions.")
+ (idx (make-hash-table :test #'equal) :type hash-table
+ :documentation "Obj -> position into the previous field."))
+
(cl-defstruct comp-ctxt
"Lisp side of the compiler context."
(output nil :type string
(funcs-h (make-hash-table) :type hash-table
:documentation "lisp-func-name -> comp-func.
This is to build the prev field.")
- (data-relocs-l () :type list
- :documentation "List of pairs (impure . obj-to-reloc).")
- (data-relocs-idx (make-hash-table :test #'equal) :type hash-table
- :documentation "Obj -> position into data-relocs."))
+ (d-base (make-comp-data-container) :type comp-data-container
+ :documentation "Standard data relocated in use by functions.")
+ (d-impure (make-comp-data-container) :type comp-data-container
+ :documentation "Data relocated that cannot be moved into pure space.
+This is tipically for top-level forms other than defun."))
(cl-defstruct comp-args-base
(min nil :type number
"Type hint predicate for function name FUNC."
(when (member func comp-type-hints) t))
+(defun comp-data-container-check (cont)
+ "Sanity check CONT coherency."
+ (cl-assert (= (length (comp-data-container-l cont))
+ (hash-table-count (comp-data-container-idx cont)))))
+
+(defun comp-add-const-to-relocs-to-cont (obj cont)
+ "Keep track of OBJ into the CONT relocation container.
+The corresponding index is returned."
+ (let ((h (comp-data-container-idx cont)))
+ (if-let ((idx (gethash obj h)))
+ idx
+ (push obj (comp-data-container-l cont))
+ (puthash obj (hash-table-count h) h))))
+
(defun comp-add-const-to-relocs (obj &optional impure)
"Keep track of OBJ into the ctxt relocations.
When IMPURE is non nil OBJ cannot be copied into pure space.
The corresponding index is returned."
- (let ((data-relocs-idx (comp-ctxt-data-relocs-idx comp-ctxt))
- (packed-obj (cons impure obj)))
- (if-let ((idx (gethash packed-obj data-relocs-idx)))
- idx
- (push packed-obj (comp-ctxt-data-relocs-l comp-ctxt))
- (puthash packed-obj (hash-table-count data-relocs-idx) data-relocs-idx))))
+ (comp-add-const-to-relocs-to-cont obj
+ (if impure
+ (comp-ctxt-d-impure comp-ctxt)
+ (comp-ctxt-d-base comp-ctxt))))
(defmacro comp-within-log-buff (&rest body)
"Execute BODY while at the end the log-buffer.
(defun comp-compile-ctxt-to-file (name)
"Compile as native code the current context naming it NAME.
Prepare every function for final compilation and drive the C back-end."
- (cl-assert (= (length (comp-ctxt-data-relocs-l comp-ctxt))
- (hash-table-count (comp-ctxt-data-relocs-idx comp-ctxt))))
+ (comp-data-container-check (comp-ctxt-d-base comp-ctxt))
+ (comp-data-container-check (comp-ctxt-d-impure comp-ctxt))
(comp--compile-ctxt-to-file name))
(defun comp-final (_)
#define CURRENT_THREAD_RELOC_SYM "current_thread_reloc"
#define PURE_RELOC_SYM "pure_reloc"
#define DATA_RELOC_SYM "d_reloc"
+#define DATA_RELOC_IMPURE_SYM "d_reloc_imp"
#define FUNC_LINK_TABLE_SYM "freloc_link_table"
#define LINK_TABLE_HASH_SYM "freloc_hash"
#define TEXT_DATA_RELOC_SYM "text_data_reloc"
+#define TEXT_DATA_RELOC_IMPURE_SYM "text_data_reloc_imp"
#define SPEED XFIXNUM (Fsymbol_value (Qcomp_speed))
#define COMP_DEBUG XFIXNUM (Fsymbol_value (Qcomp_debug))
Lisp_Object exported_funcs_h; /* subr_name -> gcc_jit_function *. */
Lisp_Object imported_funcs_h; /* subr_name -> gcc_jit_field *reloc_field. */
Lisp_Object emitter_dispatcher;
- gcc_jit_rvalue *data_relocs; /* Synthesized struct holding data relocs. */
- gcc_jit_lvalue *func_relocs; /* Synthesized struct holding func relocs. */
+ /* Synthesized struct holding data relocs. */
+ gcc_jit_rvalue *data_relocs;
+ /* Same as before but can't go in pure space. */
+ gcc_jit_rvalue *data_relocs_impure;
+ /* Synthesized struct holding func relocs. */
+ gcc_jit_lvalue *func_relocs;
} comp_t;
static comp_t comp;
comp.void_ptr_type,
NULL));
- Lisp_Object d_reloc_idx = CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt);
- Lisp_Object packed_obj = Fcons (impure, obj);
- Lisp_Object reloc_idx = Fgethash (packed_obj, d_reloc_idx, Qnil);
+ Lisp_Object container = impure ? CALL1I (comp-ctxt-d-impure, Vcomp_ctxt)
+ : CALL1I (comp-ctxt-d-base, Vcomp_ctxt);
+ Lisp_Object reloc_idx =
+ Fgethash (obj, CALL1I (comp-data-container-idx, container), Qnil);
eassert (!NILP (reloc_idx));
gcc_jit_rvalue *reloc_n =
gcc_jit_context_new_rvalue_from_int (comp.ctxt,
gcc_jit_lvalue_as_rvalue (
gcc_jit_context_new_array_access (comp.ctxt,
NULL,
- comp.data_relocs,
+ impure ? comp.data_relocs_impure
+ : comp.data_relocs,
reloc_n));
}
gcc_jit_block_end_with_return (block, NULL, res);
}
+static gcc_jit_rvalue *
+declare_imported_data_relocs (Lisp_Object container, const char *code_symbol,
+ const char *text_symbol)
+{
+ /* Imported objects. */
+ EMACS_INT d_reloc_len =
+ XFIXNUM (CALL1I (hash-table-count,
+ CALL1I (comp-data-container-idx, container)));
+ Lisp_Object d_reloc = Fnreverse (CALL1I (comp-data-container-l, container));
+ d_reloc = Fvconcat (1, &d_reloc);
+
+ gcc_jit_rvalue *reloc_struct =
+ gcc_jit_lvalue_as_rvalue (
+ gcc_jit_context_new_global (
+ comp.ctxt,
+ NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_context_new_array_type (comp.ctxt,
+ NULL,
+ comp.lisp_obj_type,
+ d_reloc_len),
+ code_symbol));
+
+ emit_static_object (text_symbol, d_reloc);
+
+ return reloc_struct;
+}
+
static void
-declare_runtime_imported_data (void)
+declare_imported_data (void)
{
/* Imported symbols by inliner functions. */
CALL1I (comp-add-const-to-relocs, Qnil);
CALL1I (comp-add-const-to-relocs, Qt);
CALL1I (comp-add-const-to-relocs, Qconsp);
CALL1I (comp-add-const-to-relocs, Qlistp);
+
+ /* Imported objects. */
+ comp.data_relocs =
+ declare_imported_data_relocs (CALL1I (comp-ctxt-d-base, Vcomp_ctxt),
+ DATA_RELOC_SYM,
+ TEXT_DATA_RELOC_SYM);
+ comp.data_relocs_impure =
+ declare_imported_data_relocs (CALL1I (comp-ctxt-d-impure, Vcomp_ctxt),
+ DATA_RELOC_IMPURE_SYM,
+ TEXT_DATA_RELOC_IMPURE_SYM);
}
/*
gcc_jit_type_get_pointer (comp.void_ptr_type),
PURE_RELOC_SYM));
- declare_runtime_imported_data ();
- /* Imported objects. */
- EMACS_INT d_reloc_len =
- XFIXNUM (CALL1I (hash-table-count,
- CALL1I (comp-ctxt-data-relocs-idx, Vcomp_ctxt)));
- Lisp_Object d_reloc = Fnreverse (CALL1I (comp-ctxt-data-relocs-l, Vcomp_ctxt));
- d_reloc = Fvconcat (1, &d_reloc);
-
- comp.data_relocs =
- gcc_jit_lvalue_as_rvalue (
- gcc_jit_context_new_global (
- comp.ctxt,
- NULL,
- GCC_JIT_GLOBAL_EXPORTED,
- gcc_jit_context_new_array_type (comp.ctxt,
- NULL,
- comp.lisp_obj_type,
- d_reloc_len),
- DATA_RELOC_SYM));
-
- emit_static_object (TEXT_DATA_RELOC_SYM, d_reloc);
+ declare_imported_data ();
/* Functions imported from Lisp code. */
freloc_check_fill ();
dynlib_sym (handle, CURRENT_THREAD_RELOC_SYM);
EMACS_INT ***pure_reloc = dynlib_sym (handle, PURE_RELOC_SYM);
Lisp_Object *data_relocs = dynlib_sym (handle, DATA_RELOC_SYM);
+ Lisp_Object *data_imp_relocs = dynlib_sym (handle, DATA_RELOC_IMPURE_SYM);
void **freloc_link_table = dynlib_sym (handle, FUNC_LINK_TABLE_SYM);
void (*top_level_run)(Lisp_Object) = dynlib_sym (handle, "top_level_run");
if (!(current_thread_reloc
&& pure_reloc
&& data_relocs
+ && data_imp_relocs
&& freloc_link_table
&& top_level_run)
|| NILP (Fstring_equal (load_static_obj (comp_u, LINK_TABLE_HASH_SYM),
/* Imported data. */
if (!loading_dump)
- comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
+ {
+ comp_u->data_vec = load_static_obj (comp_u, TEXT_DATA_RELOC_SYM);
+ comp_u->data_impure_vec =
+ load_static_obj (comp_u, TEXT_DATA_RELOC_IMPURE_SYM);
- EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
+ if (!NILP (Vpurify_flag))
+ /* Non impure can be copied into pure space. */
+ comp_u->data_vec = Fpurecopy (comp_u->data_vec);
+ }
- if (!loading_dump && !NILP (Vpurify_flag))
- for (EMACS_INT i = 0; i < d_vec_len; i++)
- {
- Lisp_Object packed_obj = AREF (comp_u->data_vec, i);
- if (NILP (XCAR (packed_obj)))
- /* If is not impure can be copied into pure space. */
- XSETCDR (packed_obj, Fpurecopy (XCDR (packed_obj)));
- }
+ EMACS_INT d_vec_len = XFIXNUM (Flength (comp_u->data_vec));
+ for (EMACS_INT i = 0; i < d_vec_len; i++)
+ data_relocs[i] = AREF (comp_u->data_vec, i);
+ d_vec_len = XFIXNUM (Flength (comp_u->data_impure_vec));
for (EMACS_INT i = 0; i < d_vec_len; i++)
- data_relocs[i] = XCDR (AREF (comp_u->data_vec, i));
+ data_imp_relocs[i] = AREF (comp_u->data_impure_vec, i);
if (!loading_dump)
{