Commit Graph

407 Commits

Author SHA1 Message Date
Matthew Flatt
6c9dbea31f make pretty-print-newline work on any output port
The documentation says that it should work on any output port,
although there's special treatment of ports that originate
from `pretty-print` itself.

Closes #1579.
2017-01-30 05:41:49 -07:00
Gustavo Massaccesi
a21b33a760 mark struct operations as single valued and mark preserving
Also, the optimizer recognizes struct operations as procedures,
so it will reduce

  (procedure? my-struct?) ==> #t
2017-01-29 20:05:46 -03:00
Gustavo Massaccesi
601587c068 advance effect clocks after reductions
After some reductions, the new rator advance less the effect
clocks than the original rator. For example in

    (equal? x 7) ==> (eq? x 7)

    (my-struct? x) ==> #t or #f
2017-01-29 20:05:46 -03:00
Gustavo Massaccesi
b73e1dfd6c consider the flags of unclonable lambdas for reductions
The lambdas can be marked as single valued and/or mark preserving.
With this information is possible to remove unnecessary wrapping
like the `values` in

    (let ([f (lambda () '(1))])
      (display f f)
      (values (f)))

or in reductions like

   (car (list (f))) ==> (values (f)) ==> (f)

Moreover, this is useful to test that the optimizer has marked
correctly the function f as single valued and mark preserving.
2017-01-29 20:05:45 -03:00
Matthew Flatt
aa130df8b2 fix prop:custom-write printing on structure ports
When a `prop:custom-write` function prints to a given port for
recursive printing, don't reject a port that is a structure port.

Relevant to #1579
2017-01-27 18:04:20 -07:00
Matthew Flatt
03f2deeea9 fix module->namespace problem resoring bindings
If a module has any sort of complex bindings, such as a definition of
a macor-introduced identifiers, then `module->namespace` and variants
(like `variable-reference->namespace`) need to recreate suitable
bindings. Make sure that the module-path index for recreated bindings
is the run-time one, not the compile-time one.

Closes #1584
2017-01-27 17:30:35 -07:00
Gustavo Massaccesi
0a5c510b72 advance the vclock for a values with 0 or more than 1 argument
To avoid moving expressions that may have a side effect, the optimizer must
recognize that in this position this will cause an error and advance
the virtual clock.

Currently the only primitive that is flagged as SCHEME_PRIM_IS_OMITABLE and
may have multiple return values is `values`.

Thanks to Robby for finding the original version of the test.
2017-01-27 18:18:26 -03:00
Matthew Flatt
0e12201c4d fix bytecode writer for immediate compile-time values
When a hash table or other special value appears immediately on the
right-hand side of `define-values`, it needs to be protected by an
explicit quote when writing to bytecode.

Closes #1580
2017-01-27 09:07:53 -07:00
Matthew Flatt
89512edad9 fix JIT handling of struct type property predicates and accessors
When the JIT guesses that a rator will always be a struct type
property or accessor, the run-time check to confirm that guess
was broken.
2017-01-27 07:53:03 -07:00
Matthew Flatt
aead07b5de bytecode compiler: fix misuse of "optimize" mode on a "resolved" form
Thanks to Robby for the test.
2017-01-20 21:35:09 -07:00
Matthew Flatt
736cdfb2c1 yet more repairs to the interaction of errors and let-values
Continuing the saga that includes 8190a7730d and d1ba9fbb6e, it turns
out that a 0-binding clause as the last one isn't so special after
all. A little later in the optimizer, now that we're sometimes moving
an error to the body, we can't assume that the body can be discard
if an error was detected.
2017-01-20 18:07:05 -07:00
Gustavo Massaccesi
d1ba9fbb6e fix wcm on error in let's
Repairs a problem with 8190a7730d, which can incorerctly
move an erroring experssion into tail position.
2017-01-20 15:04:11 -07:00
Matthew Flatt
8190a7730d fix optimizer bug related to errors and zero-values binding 2017-01-20 12:19:05 -07:00
Matthew Flatt
80e8e0f9e0 fix a mismatch between the optimizer and validator
Thanks to Leif for the report and test case.
2017-01-18 15:39:38 -07:00
Matthew Flatt
3f2de918d8 fix variable-reference->namespace for phase > 0
Set up bindings and shift phases as needed to make
`variable-reference->namespace` work in a run-time position when the
enclosing module is instantiated at a phase other than 0.

Thanks to Rohin Shah for the bug report.
2017-01-16 08:53:57 -07:00
Matthew Flatt
b138c340e1 fix extended {read,peek}-char-or-special
The changes in 08ca76b741 require the primitives to be reclassified
from non-CM to general.

Also, add an internal shortcut for checking arity.
2017-01-15 10:02:57 -07:00
Matthew Flatt
2cf6691439 expose read capabilities of string->number
Extend the `string->number` parser for use by readers, which need
error messages and/or extflonum results.
2017-01-13 08:09:19 -08:00
Matthew Flatt
08ca76b741 extend {read,peek}-char-or-special
Support an external implementation of `read-syntax` by exposing
functionality that is currently internal to `read-syntax`: a srcloc
argument to a "special"-producing port function and wrapping special
results to reliably distinguish them from characters.
2017-01-13 08:09:18 -08:00
Matthew Flatt
7ef20dd606 transplant-output-port: defend against weird ports
Avoid an error within `transplant-output-port` if the given output
port's position somehow goes down instead of up.

Merge to v6.8
2017-01-11 08:06:25 -07:00
Matthew Flatt
8ff011fc51 fix srcloc collapse for a path to a file in a root directory 2017-01-08 07:14:28 -06:00
Matthew Flatt
83d4cf4485 add test that a sandbox can be created in a sandbox 2017-01-03 13:09:36 -07:00
Matthew Flatt
e041d0f32f fix optimizer bug related to detected arity errors
When multiple-binding `let-values` form is split into a single-binding
form on the grounds that the right-hand side will definitely error,
the optimizer's effect clocks were advance incorrectly.

Closes #1552
2017-01-02 07:00:22 -07:00
Matthew Butterick
fc194d7337 update copyright year to 2017 2017-01-02 06:42:31 -07:00
Matthew Flatt
88aa7fdeff don't reorder some unsafe expressions that can depend on an effect
For example, an `unsafe-unbox` call should not be moved past the
call to an unknown function that might change a box's content.

Thanks to Sergey Pinaev for the report.
2016-12-23 08:01:30 -07:00
Gustavo Massaccesi
992f990860 optimizer: merge lookup_constant_proc and optimize_for_inline
The objective of lookup_constant_proc and the first part of
optimize_for_inline was to find out if the value of an expression was a
procedure and get it to analyze its properties or try to inline it. Both
were called together in a few places, because each one had some special
cases that were missing in the other.

So, move the lookup and special cases from optimize_for_inline to
lookup_constant_proc, and keep only the code relevant to inlinig in
optimize_for_inline.
2016-12-22 23:34:27 -03:00
Matthew Flatt
8a7852ebbf fix re-expansion of a simple #%module-body form with submodules
Closes #1538
2016-12-15 08:05:02 -07:00
Gustavo Massaccesi
22d61c41d5 optimizer: merge single_valued_expression and definitely_no_wcm_in_tail
Both function have a similar purpose and implementation, so merge them to consider
all the special cases for both uses.

In particular, detect that:
  (if x (error 'e) (void)) is single-valued
  (with-continuation-mark <chaperone-key> <val> <omittable>) is  not tail sensitive.

Also, as ensure_single_value was checking also that the expression was has not a
continuation mark in tail position, it added in some cases an unnecessary
wrapper. Now ensure_single_value checks only that the expression produces
a single vale and a new function ensure_single_value_noncm checks both
properties like the old function.
2016-12-14 20:18:21 -03:00
Gustavo Massaccesi
6d1018fbe8 optimizer: fix interaction of arithmetic reductions and wcm
Also fix a similar problem with branches reduction in a Boolean context.
2016-12-14 20:13:28 -03:00
Matthew Flatt
ce370c2f64 fix preservation of properties absent a source location 2016-12-14 08:13:17 -07:00
Matthew Flatt
d7b18e7a9c adjust map and for ... in-list to not retain their lists
Adjust list and stream handling as sequences so that during the body

 (for ([i (in-list l)])
   ....)

then `i` and its cons cell in `l` are not implicitly retained while
the body is evaluated. A `for .... in-stream` similarly avoids
retaining the stream whose head is being used in the loop body.

The `map`, `for-each`, `andmap`, and `ormap` functions are similarly
updated.

The `make-do-sequence` protocol allows an optional extra result so
that new sequence types could have the same properties. It's not clear
that using `make-do-sequence` is any more useful than creating the new
sequence as a stream, but it was easier to expose the new
functionality than to hide it.

Making this work required a repair to the optimizer, which would
incorrectly move an `if` expression in a way that could affect
space complexity, as well as a few repairs to the run-time system
(especially in the vicinity of the built-in `map`, which we should
just get rid of eventually, anyway).
2016-12-13 19:20:41 -07:00
Matthew Flatt
5e94a906cd compile simple for/list to avoid reverse
Compile a `for[*]/list` form to behave more like `map` by `cons`ing
onto a recursive call, instead of accumulating a list to reverse.

This style of compilation requires a different strategy than before.
A form like

 (for*/fold ([v 0]) ([i (in-range M)]
                     [j (in-range N)])
   j)

compiles as nested loops, like

 (let i-loop ([v 0] [i 0])
   (if (unsafe-fx< i M)
       (i-loop (let j-loop ([v v] [j 0])
                 (if (unsafe-fx< j N)
                     (j-loop (SEL v j) (unsafe-fx+ j 1))
                     v))
               (unsafe-fx+ i 1))
       v))

instead of mutually recursive loops, like

 (let i-loop ([v 0] [i 0])
   (if (unsafe-fx< i M)
       (let j-loop ([v v] [j 0])
         (if (unsafe-fx< j N)
             (j-loop (SEL v j) (unsafe-fx+ j 1))
             (i-loop v (unsafe-fx+ i 1))))
       v))

The former runs slightly faster. It's difficult to say why, for
certain, but the reason may be that the JIT can generate more direct
jumps for self-recursion than mutual recursion. (In the case of mutual
recursion, the JIT has to generate one function or the other to get a
known address to jump to.)

Nested loops con't work for `for/list`, though, since each `cons`
needs to be wrapped around the whole continuation of the computation.
So, the `for` compiler adapts, depending on the initial form. (With a
base, CPS-like approach to support `for/list`, it's easy to use the
nested mode when it works by just not fully CPSing.)

Forms that use `#:break` or `#:final` use the mutual-recursion
approach, because `#:break` and #:final` are easier and faster that
way. Internallt, that simplies the imoplementation. Externally, a
`for` loop with `#:break` or `#:final` can be slightly faster than
before.
2016-12-13 18:27:06 -07:00
Alexis King
62170e6218 Add index(es)-of and index(es)-where to racket/list 2016-12-10 13:01:12 -08:00
Matthew Flatt
c7e8166725 split optimizer and JIT test suites 2016-12-09 09:20:52 -07:00
Matthew Flatt
9c1b870769 optimizer: fix interaction of escaping expressions and wcm
The optimizer can detect that some expressions will escape through
an error, and it can discard surrounding code in that case. It should
not change the tailness of a `with-continuation-mark` form by
liftng it out of a nested position, however. Doing so can eliminate
stack frames that should be visible via errotrace, for example.
This change fixes the optimizer to wrap an extra `(begin ... (void))`
around an expression if it's lifted out of a nested context and
might have a `with-continuation-mark` form in tail position.
2016-12-09 08:58:40 -07:00
Matthew Flatt
8f9d4860fd change syntax to preserve all properties on a template
In

 (with-syntax ([x ....])
   #'(x y))

and property on the source syntax object `(x y)` was lost in
constructing a new syntax object to substitute for `x`, while
properties on preserved literal syntax objects, such as `y`
were intact. Change `syntax` to preserve properties for
reconstructed parts of the template.

This change exposes a problem with 'transparent taint modes,
where the internal "is original?" property was preserved while
losing scopes that wuld cancel originalness. So, that's fixed
here, too.
2016-12-07 09:15:14 -07:00
Gustavo Massaccesi
25dc89a238 more reductions in ignored expressions
extend optimize_ignore to go inside expressions with
begin, begin0 and let.

Also, try to reuse begin's in the first argument of
make_discarding_sequence.
2016-12-04 23:18:43 -03:00
Matthew Flatt
200fbe9b95 fix rename-file-or-directory for raising exn:failsystem:fail:exists
Broken by 0133954c84, which avoided a made-up `EEXIST` but left in
place a no-loner-appropriate test for raising `exn:failsystem:fail:exists`.
2016-12-01 10:21:11 -07:00
Matthew Flatt
ba1f5be532 fix potential crash when printing a changing hash table
If a mutable hash table changes while it's being printed,
various parts of the printing function could see a mismatch
between the current size and an old array size. To avoid this
problem, extract the size whenever extracting the array.
2016-11-28 18:17:36 -07:00
Matthew Flatt
3a782d01db fix interaction of module->namespace and syntax-source-module
An identifier that gets a module context via `module->namespace` plus
`namespace-syntax-introduce` should not count as having the module as
its source as reported by `syntax-source-module`.

The correct behavior happened for the wrong reason prior to commit
cb6af9664c.

Closes #1515
2016-11-21 17:40:44 -07:00
Matthew Flatt
02b0a30988 improve ellipsis-count checking wrapper
For a template expression that involevs ellipses, a wrapper is added
to catch failures an report as an "incompatible ellipsis match count"
error. The wrapper was only added when there are multiple pattern
variables with ellipses, but it turns out that it's possible to fail
with incompatible counts using a single pattern variable.

Besides handlign that case, the revised check avoids an unnecessary
wrapper in cases where multiple pattern variables have ellipses but
they are used independently in a template.

Closes #1511
2016-11-21 10:01:36 -07:00
Sam Tobin-Hochstadt
c5cce7aa7b Fix test for values, and simplify test case. (#1525)
Repairs 7c22c42c7.
2016-11-21 11:02:56 -05:00
Matthew Flatt
7c22c42c72 fix optimizer imprecision for values
Without this repair,

 #lang racket/base
 (require 2htdp/abstraction)
 (for/list ((dropping-which-one (in-naturals)))
   1)

fails to compile with a "optimizer clock tracking has gone wrong"
error. A variant of this test (that doesn't depend on `2htdp`)
is now in the "optimize.rktl"; a simpler and more direct test
should be possible, but I wasn't able to construct one.
2016-11-20 18:06:46 -07:00
Gustavo Massaccesi
9ebfdb54e7 extend reductions for expressions like (if (if X Y #f) Z K)
=> (if X (if Y Z K) K) where K is a constant,
to expressions where the inner `if` is (if X Y #t) or (if X #t/#f Y)
2016-11-15 11:37:17 -03:00
Matthew Flatt
115dec6fd9 fix bug in scheduler
When a thread that is blocked on a set of semaphores and channels
is suspended and resumed after one of the events becomes ready,
and if the event has a wrapper function, then the wrapper was
not applied and the event selection was not reported correctly.

Thanks to Philip McGrath for reporting the problem.
2016-11-14 08:21:42 -07:00
Alexis King
393afa3759 Track the origin of modules produced by module+ forms
This ensures the 'origin property is propagated from macros that expand
to module+ forms.
2016-11-08 10:15:48 -08:00
Gustavo Massaccesi
5833390396 optimizer: extend the reductions like (equal? x y) => (eq? x y)
This kind of reductions were applied only when x or y was a constant.

Classify the relevant predicates in 4 categories. In particular,
if <expr> satisfy pred? we can use this classification to apply
the correct reduction:

(equal? <expr> y) ==> [no reduction, unless y has a different type]
(equal? <expr> y) ==> (eqv? <expr> y)
(equal? <expr> y) ==> (eq? <expr> y)
(equal? <expr> y) ==> (begin <expr> (pred? y))
2016-11-01 20:40:01 -03:00
Gustavo Massaccesi
7c1cb1a2f0 optimizer: add symbol?, keyword? and char? to the relevant predicates
Also, add a new primitive interned-char? that is hidden, but it's
useful to track in the optimizer the the chars? with a value < 256
that are interned because they are treated specially, and if they
are equal? then they are eq?.
2016-11-01 20:40:00 -03:00
Andrew Kent
82204d1444 faster in-*-id-table (#1499) 2016-10-30 14:28:13 -04:00
Georges Dupéron
df2b1dad45 Fixes #1497 free-id-table-ref! with procedure failure argument stores the procedure, not its result 2016-10-28 10:47:48 -05:00
Matthew Flatt
cb6af9664c fix expand + compile + write + read + module->namespace
... + prefix-in + relative-path module. All of those ingredients
(or some similar alternatives) are necessary to trigger a slow
way of saving module context for interaction evaluation where
a module-path index shift was getting lost.
2016-10-26 17:09:30 -06:00