Commit graph

320 commits

Author SHA1 Message Date
Daniel Kochmański
6dcff2267b stacks: rename env runtime stack operators ecl_vms_*
ecl_stack_* was not specific enough.
2025-05-14 10:53:59 +02:00
Daniel Kochmański
815e0daa05 stacks: make runtime stack accessors inline functions
Also remove an unused operator FEstack_advance.
2025-05-14 10:53:59 +02:00
Daniel Kochmański
ad81ee8f42 stacks: move runtime stack to a separate structure 2025-05-14 10:53:59 +02:00
Daniel Kochmański
da3dc34241 stacks: move the binding stack to a separate structure 2025-05-14 10:53:59 +02:00
Daniel Kochmański
2f9ce70e8f stack frames: dereference directly to env->stack
Previously we've cached the stack base and dereferenced from there, but when the
stack is resized, this reference is invalidated and there is no good fix it in
all frames (we don't store back references).

This commit replaces pointers with indexes, so the stack frame is always
displaced onto the current lisp stack.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
2382fa41ab bytecmp: track the maximal size of the locals environment
After the function is compiled we assign the width to nlcl. This will be used to
determine the necessary size of the stack frame for locals.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
512a31301d bytecmp: [unbug] remove assertions that are now not necessary 2025-05-09 13:55:59 +02:00
Daniel Kochmański
16996f8d38 bytevm: treat blocks and tags as normal local bindings
Previously when unbinding we've skipped blocks and tags and let the frame exit
to collect the frame variable. This commit simplifies managing the environment
in the compiler.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
878fc3441c bytecmp: compute the locals env size correctly
Previously our calculations were off because:

- we've counted special variables
- we didn't decrement the env size when unbound

One could argue that we need only to increment it, but then we'd end up with the
size too big. Consider:

(progn
 (let ((a 1)) (foobar))
 (let ((b 1)) (foobar)))

In this snippet we have two local variables, but we never look at locals beyond
the first element.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
8bc957d88f bytecmp: [debug] add assertions for the current environment size
env_size is not computed correctly (neither max size nor current size), these
assertions are meant to help with mending the issue in order to correctly
determine the size of the locals environment.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
600901da05 bytecodes: add a new slot nlcl denoting the maximal number of locals
Currently it is initialized to NIL, the next commit will assign to it a correct
value.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
9addb2cc4a bytevm: access interpreter locals in fifo order
This is a preliminary step before replacing a structure consed on a heap with
the lisp stack.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
34f546027f compiler: factor the local entry index into a function
c_lcl_idx computes the location of the entry in the locals env. It does traverse
the list again, so it adds a little overhead, but this will allow us to
customize it later to compute a location from the bottom.
2025-05-09 13:55:59 +02:00
Daniel Kochmański
eb6a64def9 lexenv: remove unused function from the compiler 2025-03-27 22:45:34 +01:00
Daniel Kochmański
77fe30efdd bytecmp: ensure that we close around referenced local macros
This is necessary to recompile bytecodes when they contain macro expansions.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
0fb64f5c91 bytecmp: [degression] insert CFB local macros in the lexenv
This is necessary if we want to recompile bytecodes either with CCMP or BCMP.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
92772b1afd bytecmp: implement flat closures
This commit replaces capturing whole LEX with an explicit vector of closed
variables. We introduce a set of additional opcodes that deal with closed
entities. Locals are referred as lcl and closed variables as lex.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
7637f84629 bytecmp: [regression] don't stick macros at the lexenv beginning
This commit causes an intentional regression in the bytecodes compiler - we
don't carry over macros and symbol macros, so we can't recompile bytecompiled
function with the native compiler if they reference them.

That will be fixed in a more organized manner after flat closures are in place.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
710ac09e1d bytecmp: refactor handling object references
- split c_tag_ref into three functions c_{tag,blk,fun}_ref, clean c_var_ref

  small differences between functions made the former harder to read
  also update comments about the compiler environment

  functions are refactored to have a similar shape and return the
  same (internal) structure that denotes the object scope and purpose

- don't push special variables as locations in the environment

  that was (an irrelevant) bug, because special variables are not in the en

- rename asm_c to asm_arg_data

  This name better resembles the purpose of the operator
2025-03-27 22:45:34 +01:00
Daniel Kochmański
8e44c6322f bytevm: enclose macros over local functions defined with flet/labels
This change requires a kludge that addresses an issue with creating shallow
copies of the environment.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
32dfca42e5 bytevm: introduce unsafe primops SI:CONS-CAR and SI:CONS-CDR 2025-03-27 22:45:34 +01:00
Daniel Kochmański
497ece5a77 bytevm: move stepping logic out to trace.lsp
We use the environment hook to install the stepper.
2025-03-27 22:45:34 +01:00
Daniel Kochmański
44033ce73e si_need_to_make_load_form_p: use hash table for load form cache
For very long lists going with list search gives us O(n²).
2024-12-29 20:32:25 +01:00
Marius Gerbershagen
d336b3053d implement faster function calls
The previous function call sequence for ordinary global functions
looked as follows.

1. check whether the function is defined, i.e. whether
   symbol->symbol.gfdef is not NULL
2. set the_env->function to symbol->symbol.gfdef
3. call the function pointer symbol->symbol.gfdef->cfun.entry

This commit implements a performance optimization that enables us to
skip the first step. The basic idea is to replace symbol->symbol.gfdef
with a closure that signals an undefined-function condition.

However, straightforwardly implementing this would have the
disadvantage that it would consume a larger amount of memory for each
symbol without a function definition. To get around this, we reorder
the fields of the ecl_symbol struct such that the symbol can serve as
the function object itself, introducing an entry point that is only
used for undefined functions.

Benchmarking shows an improvement of about 10% in thight loops
compared to the old method.
2024-03-03 18:26:47 +01:00
Daniel Kochmański
5aa1a52db2 bytecmp: remove unused defines 2023-11-23 08:02:38 +01:00
Marius Gerbershagen
b65b7d3825 cmp: expand compiler macros for callsites in the same source file as the compiler macro definition 2023-10-30 12:01:21 +01:00
Marius Gerbershagen
d437bd0779 speed up looking up and setting values of dynamic variables
Introduce ecl_cmp_symbol_value and ecl_cmp_setq which do the minimal
amount of work needed to implement symbol-value and setq for dynamic
variables which we have checked to be non-null and of type symbol in
the compiler.

Also introduce a type check in ecl_symbol_value to be consistent with
ecl_setq which also checks the type. These two functions are mainly
used for the embedding interface now, so for that reason it is also
useful to have a type check in there.
2023-10-30 12:01:18 +01:00
Daniel Kochmański
4ec4187427 si_need_to_make_load_form_p: t_sse_pack does not need a constructor 2023-09-25 13:13:27 +02:00
Daniel Kochmański
7b56516679 cosmetic: improve cmpenv comments to include the qualifier :declare 2023-02-21 14:34:11 +01:00
Daniel Kochmański
4831831f74 Merge branch 'bytecmp-closure-optimization' into 'develop'
bytecmp: create fewer unnecessary closures

See merge request embeddable-common-lisp/ecl!281
2023-02-14 21:06:11 +00:00
Daniel Kochmański
8ba1bb888a si_process_lambda_list: process all variables in an uniform manner
The comment mentioned that aux variables (the sixth value) are returned the
same way as requireds, optionals and keywords however factually that was not
the case - the number of variables was not the first element of the list. This
commit updates the function and all its callers.
2023-01-22 20:12:58 +01:00
Marius Gerbershagen
998f1f4c4a bytecmp: create fewer unnecessary closures
Previously, we unconditionally created closures when a lambda form was
encountered in a non-empty lexical environment. Now we check first if
something from the enclosing environment is actually used in the
function.
2023-01-01 12:53:43 +01:00
Marius Gerbershagen
1c989247c1 bytecmp: use load time forms when needed in the case macro
Closes #669.
2022-01-23 10:37:06 +01:00
Marius Gerbershagen
8a38c9a3c2 remove register storage class specifier
This option is not needed anymore, ignored by modern compilers and has
been removed in the C++17 standard.

Fixes #647.
2021-07-17 12:13:05 +02:00
Marius Gerbershagen
2985758cd3 bytecmp: don't leave c_env->lex_env uninitialized
Was previously only initialized in si_eval_with_env. Due to the
introduction of si_bc_compile_from_stream, it was used uninitialized
in this new function, leading to segfaults.
2021-01-16 19:08:50 +01:00
Daniel Kochmański
32704f8cf5 bytecmp: error when make-load-form has a circular dependency 2020-12-27 19:15:13 +01:00
Marius Gerbershagen
3cec96739d bytecmp: fix evaluation order of load time forms
We need to defer initialization forms until all dependent creation
forms have been compiled (see CLHS make-load-form). Closes #562.

Co-authored-by: Marius Gerbershagen <marius.gerbershagen@gmail.com>
2020-12-27 19:12:49 +01:00
Marius Gerbershagen
b730412ebc bytecmp: preserve the identity for literal objects
When a literal appears in the file multiple times its identity should be
preserved.

CLHS 3.2.4.4:

> If two literal objects appearing in the source code for a single
> file processed with the file compiler are the identical, the
> corresponding objects in the compiled code must also be the identical.

Previously, every bytecode object created during ext::bc-compile-file
had its own vector of constants making it impossible to satisfy this
constraint. Thus, we change ext::bc-compile-file to use the same
constants vector for all bytecode objects from the same file. The
simplest way to achieve this is to use the same compiler environment
for all of the compilation process and push the read-compile loop
into the si_bc_compile_from_stream function implemented in C.
2020-12-27 19:04:00 +01:00
Marius Gerbershagen
e5736d393a bytecmp: don't treat load time forms as toplevel forms
This prevents top level forms from being evaluated in the middle
of another top level form.
2020-12-27 19:04:00 +01:00
Marius Gerbershagen
be46fc0caa bytecmp: factor out c_restore_env (used together with c_new_env) 2020-12-27 19:03:57 +01:00
Daniel Kochmański
c18b6d6967 bytecmp: represent bytecodes as a lisp vector
Previously they were passed as an index array, now they are a simple
vector (the cl_object).
2020-12-27 18:53:22 +01:00
Marius Gerbershagen
4e1847f775 clos: don't call make-load-form in the code walker for defmethod
Fixes #594.
2020-09-18 21:22:32 +02:00
Marius Gerbershagen
c6b4296bb8 cosmetic: fix some compiler warnings 2020-04-29 20:35:37 +02:00
Daniel Kochmański
aa34ab7119 compiler: rewrite clos::need-to-make-load-form-p
Function is rewritten in C in compiler.d to remove a dependency
between the bytecodes compiler and the clos module. It may be more
performant thanks to more precise type handing, however we use a list
instead of a hashtable, so it may be slower with lookup. To assess
that we should run some benchmarks against real code -- rewriting C
code to work with a hash table should be trivial.

clos::need-to-make-load-form-p is now si::need-to-make-load-form-p and
may be called from C code as si_need_to_make_load_form_p.
2020-04-08 22:01:16 +02:00
Daniel Kochmański
554855c8a4 compiler.d: add a static function push to a safe list handling
- the function push complements the function pop
- rename the local macro push from c_labels_flet to push_back to
  better reflect its purpose
2020-03-27 11:48:34 +01:00
Marius Gerbershagen
c1c68bb4fe bytecmp: fix return value of multiple-value-bind with no variable bindings and no body
Statements such as (multiple-value-bind () :foo) returned :foo instead
of nil (see the multiple-value-bind.11-13 tests in the ansi-test
suite).
2019-08-19 19:46:27 +02:00
Daniel Kochmański
ea87100a06 long-float: remove conditionalization
Many parts of the source code were bent backward to support builds
without long floats which are always present given we depend expect
c99 compiler.

The corresponding C macros (ECL_LONG_FLOAT) and the *feature*
entry (:long-float) are marked as deprecated in the documentation.
2019-05-24 21:04:59 +00:00
Daniel Kochmański
f87d50f053 bytecmp: tagbody: ensure ECL_NIL->ECL_NIL_SYMBOL conversion
Issue comes from the fact that list and symbol types are not
disjoint. Fixes #475.

My personal opinion (to put some rambling in a commit message) is that
having NIL being so many things is a blatant mistake and shouldn't be
picked up for Common Lisp (though many programs would probably break
and it wouldn't be so Common then).
2019-02-24 14:22:13 +01:00
Marius Gerbershagen
3bd980ce43 bytecmp: improve closure generation for macros
Only close around functions and variables when actually needed.
    Reverse changes to compiler environment, since we need the
    bytecode and native compiler environemnts to be
    similar (si::eval-with-env is called in the native compiler with
    its own compiler environment, so having symbol macros both
    c_env->variables and c_env->macros could be problematic).
2018-06-24 15:47:55 +02:00
Marius Gerbershagen
25a72ff80a cosmetic: indentation fixes and some comments 2018-06-23 21:37:26 +02:00