Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2010-09

RIP NoGlobals

52 messages · 15 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Hans-Peter Diettrich

A last note on the NoGlobals branch, and parallel processing in the compiler:

I couldn't find any way to move global variables from globals.pas into e.g. fmodule (tmodule, current_module), without breaking ppudump dependencies. As long as nobody can provide a solution for this problem, I see no chance for any parallel processing in the compiler.

Now I'll resume my original work on multiple front-ends, this time using a git repository - thanks to Graeme for the FPC and Lazarus repositories :-)

DoDi

Reply by email

Adem
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
I couldn't find any way to move global variables from globals.pas into e.g. fmodule (tmodule, current_module), without breaking ppudump dependencies.

I suspect you have thought about this, but let me try anyway.

If globals.pas is where twins are conjoined (think of Siamese twins), how about (instead of having a separate executable for 'ppudump') consuming 'ppudump' functionality into the main executable (and activating it through a commadline switch)?

Reply by email

Florian Klaempfl
to Hans-Peter Diettrich: A last note on the NoGlobals branch, and parallel processing in the compiler: I couldn't…
Hans-Peter Diettrich wrote 7 lines
A last note on the NoGlobals branch, and parallel processing in the compiler: I couldn't find any way to move global variables from globals.pas into e.g. fmodule (tmodule, current_module), without breaking ppudump dependencies. As long as nobody can provide a solution for this problem, I see no chance for any parallel processing in the compiler.

I think it was already proposed to use threadvars in this case if needed?

Now I'll resume my original work on multiple front-ends, this time using a git repository

Well, I wonder what the advantage of this will be, besides that there will be not feedback possible on the changes, so the chances to get these changes into trunk are also very little.

Reply by email

Hans-Peter Diettrich
to Florian Klaempfl
Show quoted text 10 lines
Am 29.09.2010 01:17, schrieb Hans-Peter Diettrich: > A last note on the NoGlobals branch, and parallel processing in the > compiler: > > I couldn't find any way to move global variables from globals.pas into > e.g. fmodule (tmodule, current_module), without breaking ppudump > dependencies. As long as nobody can provide a solution for this problem, > I see no chance for any parallel processing in the compiler. I think it was already proposed to use threadvars in this case if needed?

Threadvars are not a solution, until it's known in which situations/places they have to be updated. Depending on the task of an thread, some variables have to be copied from (or shared with?) other threads, and the details have to be figured out separately, for every intended task.

Show quoted text 6 lines
> Now I'll resume my original work on multiple front-ends, this time using > a git repository Well, I wonder what the advantage of this will be, besides that there will be not feedback possible on the changes, so the chances to get these changes into trunk are also very little.

There has been no feedback on my preceding work, until it finally was rejected for mostly formal reasons. Git allows to work on multiple topics (branches) at the same time, and commits can be amended, so that it should be possible to group together related changes, independently from their introduction sequence.

While the preceding tries can be separated into multiple steps, which only are useless until they are used for e.g. threading, the front-end project will have no such intermediate steps of public interest.

DoDi

Reply by email

Hans-Peter Diettrich
to Adem: I suspect you have thought about this, but let me try anyway. If globals.pas is where…
Show quoted text 9 lines
> I couldn't find any way to move global variables from globals.pas into > e.g. fmodule (tmodule, current_module), without breaking ppudump > dependencies. I suspect you have thought about this, but let me try anyway. If globals.pas is where twins are conjoined (think of Siamese twins), how about (instead of having a separate executable for 'ppudump') consuming 'ppudump' functionality into the main executable (and activating it through a commadline switch)?

Great :-)

Will this solution be acceptable?

DoDi

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: Threadvars are not a solution, until it's known in which situations/places they have to…
Hans-Peter Diettrich wrote 18 lines
Florian Klaempfl schrieb: >> Now I'll resume my original work on multiple front-ends, this time using >> a git repository > > Well, I wonder what the advantage of this will be, besides that there > will be not feedback possible on the changes, so the chances to get > these changes into trunk are also very little. There has been no feedback on my preceding work, until it finally was rejected for mostly formal reasons. Git allows to work on multiple topics (branches) at the same time, and commits can be amended, so that it should be possible to group together related changes, independently from their introduction sequence. While the preceding tries can be separated into multiple steps, which only are useless until they are used for e.g. threading, the front-end project will have no such intermediate steps of public interest.

FWIW, I appreciate the git usage -- hopefully Han's work would serve as a base to reinvigorate FPC development.

Alexander S. Klenin

Reply by email

Florian Klämpfl
to Alexander Klenin
Alexander Klenin wrote 24 lines
On Thu, Sep 30, 2010 at 00:05, Hans-Peter Diettrich wrote: > Florian Klaempfl schrieb: >>> Now I'll resume my original work on multiple front-ends, this time using >>> a git repository >> >> Well, I wonder what the advantage of this will be, besides that there >> will be not feedback possible on the changes, so the chances to get >> these changes into trunk are also very little. > > There has been no feedback on my preceding work, until it finally was > rejected for mostly formal reasons. Git allows to work on multiple topics > (branches) at the same time, and commits can be amended, so that it should > be possible to group together related changes, independently from their > introduction sequence. > > While the preceding tries can be separated into multiple steps, which only > are useless until they are used for e.g. threading, the front-end project > will have no such intermediate steps of public interest. > FWIW, I appreciate the git usage -- hopefully Han's work would serve as a base to reinvigorate FPC development.

I don't see how using git and working on multiple frontend support solves the current problems of fpc: too much supported platforms and features and too few developers working on bug fixing.

Reply by email

Florian Klämpfl
to Florian Klämpfl
Florian Klämpfl wrote
too much supported platforms and features and too few developers working on bug fixing.

Just as a side node, development of open bugs during the last years: summary_graph_cumulative_bydate.php.png

Reply by email

Michael Van Canneyt
to Florian Klämpfl
Florian Klämpfl wrote 10 lines
Am 29.09.2010 19:49, schrieb Florian Klämpfl: > Am 29.09.2010 19:42, schrieb Florian Klämpfl: >> too much supported platforms and >> features and too few developers working on bug fixing. > > Just as a side node, development of open bugs during the last years: > summary_graph_cumulative_bydate.php.png Sorry, copy&pasting went wrong: <http://www.florianklaempfl.de/summary_graph_cumulative_bydate.php.png>

Only 5% open bugs ? That's not bad. At work it's much worse.

Michael.

Reply by email

Florian Klämpfl
to Michael Van Canneyt
Michael Van Canneyt wrote 16 lines
On Wed, 29 Sep 2010, Florian Klämpfl wrote: > Am 29.09.2010 19:49, schrieb Florian Klämpfl: >> Am 29.09.2010 19:42, schrieb Florian Klämpfl: >>> too much supported platforms and >>> features and too few developers working on bug fixing. >> >> Just as a side node, development of open bugs during the last years: >> summary_graph_cumulative_bydate.php.png > > Sorry, copy&pasting went wrong: > <http://www.florianklaempfl.de/summary_graph_cumulative_bydate.php.png> Only 5% open bugs ? That's not bad. At work it's much worse.

Problem is imo: the open ones are the time consuming. And imo over time the absolute number of open bugs should at least stay stable and not increase.

Reply by email

Michael Van Canneyt
to Florian Klämpfl
Florian Klämpfl wrote 21 lines
Am 29.09.2010 19:57, schrieb Michael Van Canneyt: > > > On Wed, 29 Sep 2010, Florian Klämpfl wrote: > >> Am 29.09.2010 19:49, schrieb Florian Klämpfl: >>> Am 29.09.2010 19:42, schrieb Florian Klämpfl: >>>> too much supported platforms and >>>> features and too few developers working on bug fixing. >>> >>> Just as a side node, development of open bugs during the last years: >>> summary_graph_cumulative_bydate.php.png >> >> Sorry, copy&pasting went wrong: >> <http://www.florianklaempfl.de/summary_graph_cumulative_bydate.php.png> > > Only 5% open bugs ? That's not bad. At work it's much worse. Problem is imo: the open ones are the time consuming. And imo over time the absolute number of open bugs should at least stay stable and not increase.

That is only true if the functionality stays the same. Since there is more functionality, it is normal that there are more bugs.

About the 'time consuming': yes, there you are right. It takes some dedicated people to fix those.

Michael.

Reply by email

Hans-Peter Diettrich
to Florian Klämpfl: Just as a side node, development of open bugs during the last years:…
Show quoted text 5 lines
> too much supported platforms and > features and too few developers working on bug fixing. Just as a side node, development of open bugs during the last years: summary_graph_cumulative_bydate.php.png

This situation could be improved by an OO rewrite - better modularization, separation and encapsulation of the entire compiler parts.

In the past months I've been working on several aspects of such refactoring:
- moving global variables into objects (mainly current_module)
- turning back-ends into classes
- separation of parser (front-end) from AST processing (building AST, optimization, code generation)

When we agree to turn the current codebase into such an OO approach, eventually adding documentation, the maintenance could be simplified a lot. During my experiments I've learned how fragile the current state of the compiler codebase is - even a minor change can have inpredictable consequences in other parts of the code. Chasing and fixing an bug would be much easier, when it can be isolated in a specific compiler module, and then can be fixed with only local impact. Visual debug features (AST treeview, ASM preview...) can be added without affecting the release versions - such features already turned out to be very useful, in all my decompiler development.

Since such refactoring affects really *all* existing units, it could be done in a very new repository, resulting in an FPC 3.0 version. Then we can agree which road to follow - the old spaghetti code or the new OO approach - or whether we fork and follow both branches independently.

DoDi

Reply by email

Florian Klämpfl
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 15 lines
Florian Klämpfl schrieb: >> too much supported platforms and >> features and too few developers working on bug fixing. > > Just as a side node, development of open bugs during the last years: > summary_graph_cumulative_bydate.php.png This situation could be improved by an OO rewrite - better modularization, separation and encapsulation of the entire compiler parts. In the past months I've been working on several aspects of such refactoring: - moving global variables into objects (mainly current_module) - turning back-ends into classes

The fpc back end is completly OOP?

- separation of parser (front-end) from AST processing (building AST, optimization, code generation)

I fear that this will make the code even more fragile because the code gets spread among more locations.

When we agree to turn the current codebase into such an OO approach, eventually adding documentation, the maintenance could be simplified a lot.

We had for 1.0 a rather complete documentation. However, it outdated too quick and it didn't simplify maintainance in any way.

During my experiments I've learned how fragile the current state of the compiler codebase is - even a minor change can have inpredictable consequences in other parts of the code.

This won't change. A compiler is simply something very interwinded. Your problems with cyclic unit dependencies prove it.

Chasing and fixing an bug would be much easier, when it can be isolated in a specific compiler module, and then can be fixed with only local impact.

Nice dream, but that's exactly the problem of the harder bugs: they cause conditions not forseen by the original writer of the code.

Visual debug features (AST treeview, ASM preview...)
printnode(node);
Show quoted text 10 lines
can be added without affecting the release versions - such features already turned out to be very useful, in all my decompiler development. Since such refactoring affects really *all* existing units, it could be done in a very new repository, resulting in an FPC 3.0 version. Then we can agree which road to follow - the old spaghetti code or the new OO approach - or whether we fork and follow both branches independently.

While I agree that we should refactor parts of the compiler, it should be done in an evolutionary way. Don't forget, work on 2.0 took 6 years.

Reply by email

Mattias Gaertner
to Florian Klämpfl
Show quoted text 7 lines
[...] > During my experiments I've learned how fragile the current state of > the compiler codebase is - even a minor change can have inpredictable > consequences in other parts of the code. This won't change. A compiler is simply something very interwinded. Your problems with cyclic unit dependencies prove it.

While touching the fpc sources I often got a compile error which was "fixed" by compiling a second time. Is this normal?

Mattias

Reply by email

Jonas Maebe
to Mattias Gaertner
Mattias Gaertner wrote
While touching the fpc sources I often got a compile error which was "fixed" by compiling a second time. Is this normal?

There are some bugs in the ppu loading logic (mostly related to "inline" in combination with cyclic dependencies) that are triggered by the compiler sources (resulting either in compilation errors or crashes). However, usually the only way to solves them is to delete all ppu files. In my experience, recompiling results in the same problem in such situations.

Jonas

Reply by email

Mattias Gaertner
to Jonas Maebe
Show quoted text 8 lines
On 29 Sep 2010, at 23:50, Mattias Gaertner wrote: > While touching the fpc sources I often got a compile > error which was "fixed" by compiling a second time. > Is this normal? There are some bugs in the ppu loading logic (mostly related to "inline" in combination with cyclic dependencies) that are triggered by the compiler sources (resulting either in compilation errors or crashes). However, usually the only way to solves them is to delete all ppu files. In my experience, recompiling results in the same problem in such situations.

Interesting.
I didn't use the makefile to compile but created a lazarus package using the compiler settings from the pp.lpi.
The package compiles without error, but compiling the test program (a simple one liner compiler.compile('');) that only sees the ppu files gives an error (checksum changed, unit not found). Compiling the package a second time compiles again without error and the test program compiles too.

Mattias

Reply by email

Ralf A. Quint
to Florian Klämpfl: Problem is imo: the open ones are the time consuming. And imo over time the absolute…
Florian Klämpfl wrote 7 lines
Am 29.09.2010 19:57, schrieb Michael Van Canneyt: > > Only 5% open bugs ? That's not bad. At work it's much worse. Problem is imo: the open ones are the time consuming. And imo over time the absolute number of open bugs should at least stay stable and not increase.

Now, one interesting question/stat would rather
be: How long do bugs stay open? How long does it
take to resolve the issues of a bug?

Ralf

Reply by email

Hans-Peter Diettrich
to Florian Klämpfl: The fpc back end is completly OOP? I fear that this will make the code even more fragile…
Show quoted text 6 lines
> In the past months I've been working on several aspects of such > refactoring: > - moving global variables into objects (mainly current_module) > - turning back-ends into classes The fpc back end is completly OOP?

To some degree. Basic data types are hard coded, and prevent the use of multiple back-ends in one binary.

Show quoted text 5 lines
> - separation of parser (front-end) from AST processing (building AST, > optimization, code generation) I fear that this will make the code even more fragile because the code gets spread among more locations.

It's a matter of the related interfaces/APIs.

Show quoted text 6 lines
> When we agree to turn the current codebase into such an OO approach, > eventually adding documentation, the maintenance could be simplified a > lot. We had for 1.0 a rather complete documentation. However, it outdated too quick and it didn't simplify maintainance in any way.

That's because the implementation didn't follow the documentation. A strict OO design can be implemented according to the documentation.

Show quoted text 6 lines
> During my experiments I've learned how fragile the current state of > the compiler codebase is - even a minor change can have inpredictable > consequences in other parts of the code. This won't change. A compiler is simply something very interwinded. Your problems with cyclic unit dependencies prove it.

These problems only prove poor coding conventions. When speed is favored over stability and flexibility, such code is principally hard to maintain :-(

Show quoted text 6 lines
> Chasing and fixing an bug would > be much easier, when it can be isolated in a specific compiler module, > and then can be fixed with only local impact. Nice dream, but that's exactly the problem of the harder bugs: they cause conditions not forseen by the original writer of the code.

Such situations can be reduced by more high-level interfaces, that don't leave much room for unsupported or illegal states of the related objects.

While I agree that we should refactor parts of the compiler, it should be done in an evolutionary way. Don't forget, work on 2.0 took 6 years.

And the results of that work are not really pleasing :-( It's patchwork in many parts, that destabilized the legacy code.

DoDi

Reply by email

Hans-Peter Diettrich
to Mattias Gaertner: On Wed, 29 Sep 2010 22:34:18 +0200 While touching the fpc sources I often got a compile…
While touching the fpc sources I often got a compile error which was "fixed" by compiling a second time. Is this normal?

Sometimes I get very strange error messages, about types that are not used in the indicated locations.

There exist more possible problems, with the data types stored in the .ppu files. E.g. an exception counter is stored as a byte, but an integer is used throughout the remaining code. I dunno how inlines or generics are involved (where generics are not used in the compiler itself).

DoDi

Reply by email

Graeme Geldenhuys
to Mattias Gaertner: On Wed, 29 Sep 2010 22:34:18 +0200 While touching the fpc sources I often got a compile…

Op 2010-09-29 23:50, Mattias Gaertner het geskryf:

While touching the fpc sources I often got a compile error which was "fixed" by compiling a second time. Is this normal?

I get a similar problem with FPC 2.4.3 and fpGUI. fpGUI is in a Lazarus package, so compiled units are in a single location for any fpGUI based project. I might make a minor change in fpGUI and compile the package, then I get a "identifier not found" (which I know exists in that same unit). Simply clicking compile again, and then it compiles fine.

I've had the issue for a few months now - on multiple development machines. I'm not sure if it is related, but it sounds like a similar problem.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://opensoft.homeip.net:8080/fpgui/

Reply by email

Florian Klaempfl
to Hans-Peter Diettrich: To some degree. Basic data types are hard coded, and prevent the use of multiple…
Hans-Peter Diettrich wrote 10 lines
Florian Klämpfl schrieb: >> In the past months I've been working on several aspects of such >> refactoring: >> - moving global variables into objects (mainly current_module) >> - turning back-ends into classes > > The fpc back end is completly OOP? To some degree. Basic data types are hard coded,

True, not every type is a class in Object Pascal.

and prevent the use of multiple back-ends in one binary.

... which has no use.

Show quoted text 18 lines
>> - separation of parser (front-end) from AST processing (building AST, >> optimization, code generation) > > I fear that this will make the code even more fragile because the code > gets spread among more locations. It's a matter of the related interfaces/APIs. >> When we agree to turn the current codebase into such an OO approach, >> eventually adding documentation, the maintenance could be simplified a >> lot. > > We had for 1.0 a rather complete documentation. However, it outdated too > quick and it didn't simplify maintainance in any way. That's because the implementation didn't follow the documentation. A strict OO design can be implemented according to the documentation.

Yes, in an ideal world with endless resources.

Show quoted text 10 lines
>> During my experiments I've learned how fragile the current state of >> the compiler codebase is - even a minor change can have inpredictable >> consequences in other parts of the code. > > This won't change. A compiler is simply something very interwinded. Your > problems with cyclic unit dependencies prove it. These problems only prove poor coding conventions. When speed is favored over stability and flexibility,

Indeed, currently people complain more about FPC's speed than about it's stability.

Show quoted text 6 lines
> While I agree that we should refactor parts of the compiler, it should > be done in an evolutionary way. Don't forget, work on 2.0 took 6 years. And the results of that work are not really pleasing :-(

Really? Show me any *production* compiler which can be ported with a few thousand lines of code to another architecture. The FPC backend is one of the best written production compiler back ends I know.

It's patchwork in many parts, that destabilized the legacy code.

Well, you didn't come up with clean fixes yet either :)

Reply by email

Michael Schnell
to Michael Van Canneyt: That is only true if the functionality stays the same. Since there is more functionality,…
Michael Van Canneyt wrote
That is only true if the functionality stays the same. Since there is more functionality, it is normal that there are more bugs.

I am positively astonished about the development of the open bug count.

To me it looks like "open bugs divided by features" in fact decreases. :)

Great work of the FPC team !

Thanks !

.-Michael

Reply by email

Graeme Geldenhuys
to Michael Schnell
Michael Schnell wrote
But of course a rewrite would at first result in a huge jump up of open bugs. No idea how long it would take to get it down to the current level.

Not necessarily. If the FPC test suite is run regularly, it should contain/minimize the amount of new bugs introduced [that is obviously very dependent on how complete the FPC test suite is].

Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net:8080/fpgui/

Reply by email

Felipe Monteiro de Carvalho
to Hans-Peter Diettrich: A last note on the NoGlobals branch, and parallel processing in the compiler: I couldn't…
Hans-Peter Diettrich wrote
Now I'll resume my original work on multiple front-ends, this time using a git repository - thanks to Graeme for the FPC and Lazarus repositories :-)

What do you mean with multiple front-ends? One binary which cross-compiles to multiple targets or multiple input languages?

Felipe Monteiro de Carvalho

Reply by email

Hans-Peter Diettrich
to Florian Klaempfl: True, not every type is a class in Object Pascal. ... which has no use. Yes, in an ideal…
> and prevent the use of > multiple back-ends in one binary. ... which has no use.

Lazarus allows to switch targets on the fly, what currently prevents an incorporation of the compiler into the IDE.

For compiler development and debugging purposes it would be very nice, when all targets are covered in one compile.

Show quoted text 7 lines
>> This won't change. A compiler is simply something very interwinded. Your >> problems with cyclic unit dependencies prove it. > These problems only prove poor coding conventions. When speed is favored > over stability and flexibility, Indeed, currently people complain more about FPC's speed than about it's stability.

Looking at "make clean all", nearly half of the time is spent in the cleanup, not in compiling (Windows).

I have no problems with the compilation speed, at least for repeated compilation during editing, where only changed files have to be recompiled.

Show quoted text 7 lines
>> While I agree that we should refactor parts of the compiler, it should >> be done in an evolutionary way. Don't forget, work on 2.0 took 6 years. > And the results of that work are not really pleasing :-( Really? Show me any *production* compiler which can be ported with a few thousand lines of code to another architecture. The FPC backend is one of the best written production compiler back ends I know.

Which "production" compiler back ends have you inspected?

Please note that my criticism is based on the implementation, not on the model - the latter is superb :-) The patchwork results in many open todo's, in the target units and other places.

> It's patchwork in many parts, that destabilized the legacy code. Well, you didn't come up with clean fixes yet either :)

See above and parallel mail - the back ends have low priority on my todo list. Why should I publish branches and patches, when these have no chance to find their way into the trunk?

DoDi

Reply by email

Florian Klaempfl
to Hans-Peter Diettrich: Lazarus allows to switch targets on the fly, what currently prevents an incorporation of…
Hans-Peter Diettrich wrote 9 lines
Florian Klaempfl schrieb: >> and prevent the use of >> multiple back-ends in one binary. > > ... which has no use. Lazarus allows to switch targets on the fly, what currently prevents an incorporation of the compiler into the IDE.

Define a proper compiler API and load the compiler as shared lib. This allows also to work with different compiler versions in the future when the API is stabilized.

For compiler development and debugging purposes it would be very nice, when all targets are covered in one compile.

make fullcycle does this too.

Which "production" compiler back ends have you inspected?

GCC, Watcom, LLVM.

Show quoted text 11 lines
>>> This won't change. A compiler is simply something very interwinded. >>> Your >>> problems with cyclic unit dependencies prove it. >> These problems only prove poor coding conventions. When speed is favored >> over stability and flexibility, > > Indeed, currently people complain more about FPC's speed than about it's > stability. Looking at "make clean all", nearly half of the time is spent in the cleanup, not in compiling (Windows).

rm build-stamp.*
make all
is what I usually do :)

I have no problems with the compilation speed, at least for repeated compilation during editing, where only changed files have to be

recompiled.

Me neither, but other people, see recent discussions.

Show quoted text 12 lines
Please note that my criticism is based on the implementation, not on the model - the latter is superb :-) The patchwork results in many open todo's, in the target units and other places. >> It's patchwork in many parts, that destabilized the legacy code. > > Well, you didn't come up with clean fixes yet either :) See above and parallel mail - the back ends have low priority on my todo list. Why should I publish branches and patches, when these have no chance to find their way into the trunk?

Well, to give them a chance, it's important to discuss them as early as possible.

Reply by email

Jonas Maebe
to Hans-Peter Diettrich: Lazarus allows to switch targets on the fly, what currently prevents an incorporation of…
Hans-Peter Diettrich wrote
Lazarus allows to switch targets on the fly, what currently prevents an incorporation of the compiler into the IDE.

There are more things that prevent that, not in the least that almost any source code error will result in lots of memory leaks from the compiler.

For compiler development and debugging purposes it would be very nice, when all targets are covered in one compile.

It increases the compiler build time, which is not nice. And I personally, as a compiler developer and debugger, think it's very nice that everything is cleanly separated and that it's not possible to have accidental cross-target dependencies, which could result in changes in the constants/types for one target to suddenly impact a completely different target.

Until FPC is developed by perfect programmers that never make any errors, I think that minimising the way in which things can get entangled is the best way.

Jonas

Reply by email

Jonas Maebe
to Ralf A. Quint: Now, one interesting question/stat would rather be: How long do bugs stay open? How long…
Ralf A. Quint wrote
Now, one interesting question/stat would rather be: How long do bugs stay open? How long does it take to resolve the issues of a bug?

Mantis does not keep information about the evolution of that over time, but you can always look at the current average at http://bugs.freepascal.org/summary_page.php (under "Time Stats For Resolved Issues (days)").

Note that the "Average time" is kind of strange: it is only calculated from the already resolved bugs. This means that if you keep bugs older than the average open indefinitely, you get a "better" result than when you start fixing them. In general, it has been slowly increasing over time.

Also, all bug counts and statistics also include feature requests, and bugs for the text mode ide which is seldom worked on anymore.

Jonas

Reply by email

Florian Klaempfl
to Žilvinas Ledas
Žilvinas Ledas wrote 11 lines
On 2010-09-30 12:57, Jonas Maebe wrote: > Mantis does not keep information about the evolution of that over > time, but you can always look at the current average at > http://bugs.freepascal.org/summary_page.php (under "Time Stats For > Resolved Issues (days)"). Not all of us have rights to access these pages. I get: --- Access Denied. [ Click here to proceed ]

Since it causes a lot of DB load, it is disabled for common view. The results are:

Time Stats For Resolved Issues (days)
Longest open issue 0004889
Longest open 2,409.26
Average time 70.32
Total time 573,220.08

Reply by email

Mattias Gärtner
to Jonas Maebe: There are more things that prevent that, not in the least that almost any source code…

Zitat von Jonas Maebe :

Show quoted text 9 lines
On 30 Sep 2010, at 11:29, Hans-Peter Diettrich wrote: > Lazarus allows to switch targets on the fly, what currently > prevents an incorporation of the compiler into the IDE. There are more things that prevent that, not in the least that almost any source code error will result in lots of memory leaks from the compiler.

Ehm, are you saying, that the compiler must be restarted when there were errors, because it does not clean up properly?

Mattias

Reply by email

Jonas Maebe
to Mattias Gärtner
Mattias Gärtner wrote
Ehm, are you saying, that the compiler must be restarted when there were errors, because it does not clean up properly?

As far as allocated memory is concerned: yes. It does free a bunch of stuff when an error occurs, but not everything, and what is not freed depends on the error.

Jonas

Reply by email

Mattias Gärtner
to Jonas Maebe

Zitat von Jonas Maebe :

Show quoted text 9 lines
On 30 Sep 2010, at 13:32, Mattias Gärtner wrote: > Ehm, are you saying, that the compiler must be restarted when there > were errors, because it does not clean up properly? As far as allocated memory is concerned: yes. It does free a bunch of stuff when an error occurs, but not everything, and what is not freed depends on the error.

Ok. Thanks.
And I guess there are currently no plans to fix this, right? So the proper way to integrate FPC is to run it as separate process or in a dyn lib with its own memory manager. Correct, or ? This means, in order to share some caches an IDE must use some IPC/shared memory. Right?

Mattias

Reply by email

Jonas Maebe
to Mattias Gärtner
Mattias Gärtner wrote 13 lines
Zitat von Jonas Maebe : > On 30 Sep 2010, at 13:32, Mattias Gärtner wrote: > >> Ehm, are you saying, that the compiler must be restarted when >> there were errors, because it does not clean up properly? > > As far as allocated memory is concerned: yes. It does free a bunch > of stuff when an error occurs, but not everything, and what is not > freed depends on the error. Ok. Thanks. And I guess there are currently no plans to fix this, right?

No, because it would be lots of work (writing test programs that trigger all possible error conditions and testing/debugging them one by one, or implementing some kind of mark/release system) with no real payoff except if you're an IDE developer that wants to integrate the compiler.

Solving memory leaks that occur during a successful compilation is both easier (you have to compile less different programs to obtain large code coverage) and more important to everyone (memory leaks during a successful compilation can needlessly increase the memory requirements of the compiler).

So the proper way to integrate FPC is to run it as separate process or in a dyn lib with its own memory manager. Correct, or ? This means, in order to share some caches an IDE must use some IPC/ shared memory. Right?

Probably, I haven't really thought about that.

Jonas

Reply by email

Florian Klaempfl
to Mattias Gärtner: Zitat von Jonas Maebe : Ok. Thanks. And I guess there are currently no plans to fix this,…
Mattias Gärtner wrote 14 lines
Zitat von Jonas Maebe : > > On 30 Sep 2010, at 13:32, Mattias Gärtner wrote: > >> Ehm, are you saying, that the compiler must be restarted when there >> were errors, because it does not clean up properly? > > As far as allocated memory is concerned: yes. It does free a bunch of > stuff when an error occurs, but not everything, and what is not freed > depends on the error. Ok. Thanks. And I guess there are currently no plans to fix this, right?

No. But I don't consider it that bad: most of the memory is released even in case of an error. The overlefts shouldn't add up that much.

Reply by email

Mattias Gärtner
to Florian Klaempfl

Zitat von Florian Klaempfl :

Show quoted text 18 lines
Am 30.09.2010 14:15, schrieb Mattias Gärtner: > Zitat von Jonas Maebe : > >> >> On 30 Sep 2010, at 13:32, Mattias Gärtner wrote: >> >>> Ehm, are you saying, that the compiler must be restarted when there >>> were errors, because it does not clean up properly? >> >> As far as allocated memory is concerned: yes. It does free a bunch of >> stuff when an error occurs, but not everything, and what is not freed >> depends on the error. > > Ok. Thanks. > And I guess there are currently no plans to fix this, right? No. But I don't consider it that bad: most of the memory is released even in case of an error. The overlefts shouldn't add up that much.

When it is used for quick syntax check the compiler is invoked several times a minute - several thousand times a day. Is that a problem?

Mattias

Reply by email

Daniël Mantione
to Mattias Gärtner

Op Thu, 30 Sep 2010, schreef Mattias Gärtner:

When it is used for quick syntax check the compiler is invoked several times a minute - several thousand times a day. Is that a problem?

Expect a few kilobytes that are left over at maximum, the compiler is been debugged for memory leaks, however, this is very difficult for all possible error conditions.

If you find a memory leak that you don't like, report a bug, they can be fixed.

Daniël

Reply by email

Hans-Peter Diettrich
to Jonas Maebe: There are more things that prevent that, not in the least that almost any source code…
There are more things that prevent that, not in the least that almost any source code error will result in lots of memory leaks from the compiler.

IMO just such problems can be reduced by moving global variables into classes. When e.g. a single Compiler object holds the references to all other heap objects, an entire cleanup can be performed in the destructors.

This is where the Pascal "singleton" hack (units for classes) differs from true OOP, because units can not be "destroyed". The many constructors and destructors of such compiler singletons (InitCompiler, DoneCompiler...) should be callable (and actually be called) after every compilation.

> For compiler development and debugging purposes it would be very nice, > when all targets are covered in one compile. It increases the compiler build time, which is not nice.

Building an compiler for all targets can be done in e.g. make fullcycle, or in an according .lpi, while the default compiler still can be built for only the specified target. As before, every target has to be included explicitly, by referencing its "root" unit.

Show quoted text 6 lines
And I personally, as a compiler developer and debugger, think it's very nice that everything is cleanly separated and that it's not possible to have accidental cross-target dependencies, which could result in changes in the constants/types for one target to suddenly impact a completely different target.

The target specific types etc. have to be encapsulated, so that they can not be used by accident. This is not hard to manage (still hard to implement ;-), because the conflicting target-specific units and types have to be renamed for "parallel" use. Since this disallows to use target specific types in general compiler code, proper virtualization is enforced by that renaming, so that many of your problems will disappear consequently :-)

Until FPC is developed by perfect programmers that never make any errors, I think that minimising the way in which things can get entangled is the best way.

A good OOP language and development system shall not only *allow* for OO programming, it also should *encourage* the use of OOP. When compiler developers state that their OOP compiler is constructed in an non-OO way, for performance or other reasons, this IMO is only an excuse for not understanding the pros of OOP, or for bad use or implementation of the support for objects and related types (dynamic strings...).

It's possible that the use of OO features, together with spaghetti code, can result in a performance degradation. But OTOH performance can improve as well, when *all* (related) parts of a project cooperate by using OO features.

In detail I still doubt that the use of dynamic strings *everywhere* will really result in an much slower compiler - the opposite may be true as well. It's known that stringhandling in an OO way can result in poor performance (see .NET strings), due to clumsy overloading of the string operators - but such overhead can be reduced by using more compiler magics, instead of general overloading. Also arguments like "FillChar takes a long time", as an argument against using classes (InitInstance), IMO is only a misinterpretation of the profiling information - it might come as well from the page faults, that occur on the first access to new heap objects, and only becomes *visible* in the use of a common (FillChar...) procedure, while otherwise the page faults are added to arbitrary code, that accesses an heap object for the first time.

DoDi

Reply by email

Hans-Peter Diettrich
to Mattias Gärtner: Zitat von Jonas Maebe : Ehm, are you saying, that the compiler must be restarted when…
Show quoted text 6 lines
> There are more things that prevent that, not in the least that almost > any source code error will result in lots of memory leaks from the > compiler. Ehm, are you saying, that the compiler must be restarted when there were errors, because it does not clean up properly?

The current intialization and finalization of global variables is not easily checkable. At least I miss a documentation of all these variables, that specifies which part of the existing code is responsible for their cleanup. No such documentation is required when the global variables are moved into classes, as far as possible, because then the destructor is *definitely* responsible for the proper finalization of all fields of the class.

The same applies to strings, where the use and ownership of copies of static strings can not be determined easily.

The current code is full with nilling of variables, where proper destruction/finalization of possibly existing heap objects might be required. Again a problem with reusing global variables in various contexts, what makes it impossible to assign them to concrete owners.

DoDi

Reply by email

Hans-Peter Diettrich
to Jonas Maebe: No, because it would be lots of work (writing test programs that trigger all possible…
Show quoted text 11 lines
>> As far as allocated memory is concerned: yes. It does free a bunch of >> stuff when an error occurs, but not everything, and what is not freed >> depends on the error. > > Ok. Thanks. > And I guess there are currently no plans to fix this, right? No, because it would be lots of work (writing test programs that trigger all possible error conditions and testing/debugging them one by one, or implementing some kind of mark/release system) with no real payoff except if you're an IDE developer that wants to integrate the compiler.

IMO you simply don't understand the reason for my NoGlobals refactoring, or deny its use for (assumed) performance degradation. Right?

Show quoted text 6 lines
> So the proper way to integrate FPC is to run it as separate process or > in a dyn lib with its own memory manager. Correct, or ? > This means, in order to share some caches an IDE must use some > IPC/shared memory. Right? Probably, I haven't really thought about that.

And this may be were a (possible) performance gain in the compiler can result in an even higher performance degradation, when the compiler is used by other applications. Overall performance may be increased as well, when parts of Make are added to the compiler itself. Then e.g. a simple flag could indicate which files or units can not be used without recompilation, instead of a long-running chain of file removes in advance (make clean).

DoDi

Reply by email

Hans-Peter Diettrich
to Florian Klaempfl: Define a proper compiler API and load the compiler as shared lib. This allows also to…
Show quoted text 9 lines
>>> and prevent the use of >>> multiple back-ends in one binary. >> ... which has no use. > Lazarus allows to switch targets on the fly, what currently prevents an > incorporation of the compiler into the IDE. Define a proper compiler API and load the compiler as shared lib. This allows also to work with different compiler versions in the future when the API is stabilized.

That's easy:

function Compile(const filename, options: string; caches: TCaches):
TMessageList;

What else are you missing?

> For compiler development and debugging purposes it would be very nice, > when all targets are covered in one compile. make fullcycle does this too.

At a very high cost :-(

> Which "production" compiler back ends have you inspected? GCC, Watcom, LLVM.

Which of these claims for "best performance", in favor of "best portability"?

Show quoted text 5 lines
> Why should I publish branches and patches, when these have no > chance to find their way into the trunk? Well, to give them a chance, it's important to discuss them as early as possible.

That's problematic. While the goals are quite clear, the steps to achieve the goals are inpredictable in most cases - everything depends on problems encountered during an implementation attempt. A discussion of such problems requires some familiarity with the details, and with the consequences of possible solutions. Too bad when obvious consequences are not mentioned just-in-time, because some guru has no time for following the discussion(s).

I'd appreciate better ways for providing material for discusson, than branches in the SVN repository. Such branches are hard to remove, if ever, and restarting with a preceding version, when a dead end was hit, also is problematic. Currently I try to provide some patches, based on SVN patches, but developed using a Git repo. I found no solution for the different revisions, that are required as the base of both SVN and Git patches - anybody?

Another solution could be a (non-tracking) Git repo on some public server, where experimental branches can be created and removed freely. Patches for inclusion into the SVN repo can be created from a Git repo, when both share the same working copy. Thanks to Graeme for mentioning this trick :-)

DoDi

Reply by email

Hans-Peter Diettrich
to Florian Klaempfl: Well, and running the regression tests on all targets
> All refactoring steps can be verified immediately, using make all and > compiler/make fullcycle. Well, and running the regression tests on all targets

For what purpose? When both changes to the trunk and branches result in different results, and all that differently again for every target, who can know the "correct" results?

BTW, the tests can be run by everybody, no knowledge about the code details is required for that purpose.

DoDi

Reply by email

Florian Klämpfl
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote 10 lines
Florian Klaempfl schrieb: >> All refactoring steps can be verified immediately, using make all and >> compiler/make fullcycle. > > Well, and running the regression tests on all targets For what purpose? When both changes to the trunk and branches result in different results, and all that differently again for every target, who can know the "correct" results?

As said, they are regression tests. New fails after changes => first fixing needed.

Reply by email

Jonas Maebe
to Hans-Peter Diettrich: IMO you simply don't understand the reason for my NoGlobals refactoring, or deny its use…
Hans-Peter Diettrich wrote 9 lines
Jonas Maebe schrieb: >>> As far as allocated memory is concerned: yes. It does free a bunch of stuff when an error occurs, but not everything, and what is not freed depends on the error. >> >> Ok. Thanks. >> And I guess there are currently no plans to fix this, right? > No, because it would be lots of work (writing test programs that trigger all possible error conditions and testing/debugging them one by one, or implementing some kind of mark/release system) with no real payoff except if you're an IDE developer that wants to integrate the compiler. IMO you simply don't understand the reason for my NoGlobals refactoring

I indeed probably don't, and certainly not in this context. Especially because the memory leaks above are virtually all caused by *local* variables that are not cleaned up properly in case of an error, while on the contrary most if not all global variables are destroyed/freed under all circumstances.

Jonas

Reply by email

Hans-Peter Diettrich
to Felipe Monteiro de Carvalho: On Wed, Sep 29, 2010 at 1:17 AM, Hans-Peter Diettrich What do you mean with multiple…
Show quoted text 5 lines
> Now I'll resume my original work on multiple front-ends, this time using a > git repository - thanks to Graeme for the FPC and Lazarus repositories :-) What do you mean with multiple front-ends? One binary which cross-compiles to multiple targets or multiple input languages?

Multiple input languages. Modula or Oberon for an first try, later followed by C and (eventually) ObjectiveC. The language specific standard libraries are not covered by the front-ends, and solutions must be found for separate implementation and interface files (in Modula and C). This is where the compiler infrastructure (node classes, ppu files) may deserve some extensions, later...

DoDi

Reply by email

Daniël Mantione
to Hans-Peter Diettrich: A last note on the NoGlobals branch, and parallel processing in the compiler: I couldn't…

Op Wed, 29 Sep 2010, schreef Hans-Peter Diettrich:

A last note on the NoGlobals branch, and parallel processing in the compiler:

A few comments:

You seem to be reasoning from theory, and mainly OOP theory. In principle this is good, I have been reasoning from theory in the past as well, and this helped restructuring sections of the compiler, which we have done extensively in the past and I have had my share in this. This improved the robustness of the compiler.

In essence your project was good. There are a few remarks to be made:

* There are more theories (religions?) about how maintainable programs should be made. For example there is a strong group of programmers who strongly believes there should be no exceptions to type checking. You could have started a "refactoring" eliminating typecasts rather than elimination globals. There is functional programming theory. Each theory has its merits in it own way, but it would be wrong to say that turning everything OOP would solve all problems or removing all typecasts will necessarily make our life easier.
* The Pascal language implemented by FPC
is a mixed procedural/OOP language. Procedural programming has its strengths and FPC makes use of the potential to mix procedural and OOP.
* Global variables cause problems with parallelization, but that does not mean the choice for a global variable is a bad idea. Variables like current_module is used so extensively that they are prime candidates to be global. In my opinion you have been following the OOP bible a bit too strict here.
* OOP was your goal. Your goal should have been parallelization, OOP should have been your tool. There are more tools, like threadvars.

It has been said meny times in this discussion: In a compiler there are dependencies between a lot of datastrcutures. Handling this effectively is a challenge. FPC's approach in many places is to put abstract interdependent objects in a single unit, so these objects can use each other wherever they want. We then add functionality in other units that derive from the abstract units. Tsym, Tdef, Tsymtable are in a single unit. All kinds of symbols, definitions, and symbtables have their own unit.

I consider this design a strong one, the problem of cyclic dependencies in the compiler is well controllable. It helps maintenance: I know many C++ projects where all .cpp files over time started to include all .h files. In FPC, if you notice you can't access current_module from the current unit, you know you are doing something wrong.

You seemed to have trouble with this model, rather than embrace it and use it to your advantage, you started to break things apart and change the dependencies. As expected this caused you a dependency nightmare, introducing what you tried to eliminate with the better design: You wanted clear interfaces between certain parts of the compiler, but you did end up breaking interfaces external tools can use, and fixing them became beyond any hope.

The globals unit has its role. Many symbols are there for a good reason. There can be good reason for moving symbols out of it, if you do so, first try to understand why that symbol is there, and avoid changes in unit dependencies at all costs.

Above all: You can get far with theory. FPC has a practical and pragmatic code base but I dare to say it has a theoretically sound base design. New theory can be a solution for practical problems but implementation of it requires of new practical compromises to be made. For performance, memory use or historic reasons, or maybe even because the theory can't catch 100% of the possible situations (there are even some goto statements in the compiler).

Nevertheless, you have gotten a lot of knowledge of the compiler, and this project makes me optimistic you can become a good compiler developer.

Daniël

Reply by email

Hans-Peter Diettrich
to Florian Klämpfl: As said, they are regression tests. New fails after changes => first fixing needed.
Show quoted text 7 lines
>> Well, and running the regression tests on all targets > For what purpose? When both changes to the trunk and branches result in > different results, and all that differently again for every target, who > can know the "correct" results? As said, they are regression tests. New fails after changes => first fixing needed.

We seem to talk about different tests. Where are the regression tests found?

DoDi

Reply by email

Hans-Peter Diettrich
to Daniël Mantione: Op Wed, 29 Sep 2010, schreef Hans-Peter Diettrich: A few comments: You seem to be…
In essence your project was good. There are a few remarks to be made: * There are more theories (religions?) about how maintainable programs should be made.

Right, paradigms are somewhat religious. But as with every religion, I only believe what matches my own experience.

* The Pascal language implemented by FPC is a mixed procedural/OOP language. Procedural programming has its strengths and FPC makes use of the potential to mix procedural and OOP.

Experience tells me that projects have reached a dead end, when they contain enough unmanageable parts which nobody can explain, and which nobody dares to touch any more. Such parts typically reside in procedural code, rarely in OOP code.

Show quoted text 5 lines
* Global variables cause problems with parallelization, but that does not mean the choice for a global variable is a bad idea. Variables like current_module is used so extensively that they are prime candidates to be global. In my opinion you have been following the OOP bible a bit too strict here.

In the concrete case of FPC, the bad use of global variables (for context sensitive purposes) has nothing to do with religion. Current_module is one of the exceptions, which I consider a state variable, eligible for a threadvar. Further variables, which have to be changed together with current_module, are only used for optimizations, and can be replaced by tmodule members.

My (very raw) measurements didn't indicate any noticeable speed penalty, when further variables (even current_scanner) are replaced by indirect references to members of tmodule. Like with source files, I assume that nowadays existing caches (in both hard- and software) invalidate old rules, that the use of shadow and buffer variables can speed up execution a lot. This can be different for other (non-x86) machines, without such sophisticated caching, where the execution time still is predictable from a static analysis of the code (by counting fixed clock cycles per instruction).

* OOP was your goal. Your goal should have been parallelization, OOP should have been your tool. There are more tools, like threadvars.

Threadvars have the same problematic properties like global variables: the must be initialized and switched properly. Every such variable affects the complexity of an application, where it adds a very new dimension, not only a percentage. My experience and design principles are based on automatons and states, so that OOP is not a must, but fits nicely into such a model.

It has been said meny times in this discussion: In a compiler there are dependencies between a lot of datastrcutures. Handling this effectively is a challenge.

Yes and no. The number and polymorphism of data structures is not a problem per se. But...

Show quoted text 6 lines
FPC's approach in many places is to put abstract interdependent objects in a single unit, so these objects can use each other wherever they want. We then add functionality in other units that derive from the abstract units. Tsym, Tdef, Tsymtable are in a single unit. All kinds of symbols, definitions, and symbtables have their own unit.

...the strictly hierarchical OPL unit dependency system requires much coding discipline, and also requires hacks for certain constellations <sigh>.

Show quoted text 5 lines
I consider this design a strong one, the problem of cyclic dependencies in the compiler is well controllable. It helps maintenance: I know many C++ projects where all .cpp files over time started to include all .h files. In FPC, if you notice you can't access current_module from the current unit, you know you are doing something wrong.

ACK.

You seemed to have trouble with this model, rather than embrace it and use it to your advantage, you started to break things apart and change the dependencies. As expected this caused you a dependency nightmare,

Where do you see a dependency nightmare?

introducing what you tried to eliminate with the better design: You wanted clear interfaces between certain parts of the compiler, but you did end up breaking interfaces external tools can use, and fixing them became beyond any hope.

Which interfaces?

When there ever existed something like such an interface, it has been broken since long, as can be seen on the comments and copies in ppudump.

The globals unit has its role. Many symbols are there for a good reason.

Please specify.

When the variables in the globals unit are initialized in other units, which are not included by an external tool, they only can contain garbage.

There can be good reason for moving symbols out of it, if you do so, first try to understand why that symbol is there, and avoid changes in unit dependencies at all costs.

You mean something like copying declarations and procedures into external tools, to bypass the inclusion of unwanted units?

Show quoted text 11 lines
Above all: You can get far with theory. FPC has a practical and pragmatic code base but I dare to say it has a theoretically sound base design. New theory can be a solution for practical problems but implementation of it requires of new practical compromises to be made. For performance, memory use or historic reasons, or maybe even because the theory can't catch 100% of the possible situations (there are even some goto statements in the compiler). Nevertheless, you have gotten a lot of knowledge of the compiler, and this project makes me optimistic you can become a good compiler developer.

:-)

DoDi

Reply by email