Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Hans-Peter Diettrich

Paul Ishenin schrieb:

For some reason the visibility is completely ignored here. I can add a 
class helper to the strict private or even move it to another unit - it 
is always visible.


IMO class helper methods always should become visible as part of the 
class, regardless of where they are declared.


From the Delphi wiki:

"You can define and associate multiple helpers with a single type. 
However, only zero or one helper applies in any specific location in 
source code. The helper defined in the nearest scope will apply. Class 
or record helper scope is determined in the normal Delphi fashion (for 
example, right to left in the unit's uses clause)."


I.e. a single Helper reference (field) in the class definition is 
sufficient. This field cannot be persistent, instead it has to be 
initialized for every use case: whenever a helper is found in the 
compiled unit, or in one of its used units, it overwrites the Helper 
reference. Adding the helper elements to the class STB is not a valid 
solution, because another helper can become active at any time, during 
compilation.


The ancestors of the Helper class must be searched as well.


Also:

"Note that the class helper function MyFunc is called, because the class 
helper takes precedence over the actual class type."


That's bad, because this disallows to treat the helper like an ancestor, 
accessible in all derived classes :-(


Interesting questions:

1) Unit A defines an class helper for TFoo, then uses in the 
implementation section unit B, which also defines an helper for TFoo. 
According to the above rules the helper in A should become inaccessible 
and useless then.


2) Similarly multiple class helpers can be defined in the implementation 
section, which are used in the immediately following code, until the 
next helper declaration.


3) What about derived classes? Since derived classes are compiled 
independently, they never will use a reintroduced method in an class helper.


4) When class helpers are evaluated at compile time, according to the 
static object types (like properties are), then they could be handled 
just like the well known typecast hack:


type TMyFoo = class(TFoo)
  
  end;

with following casts of every TFoo reference into TMyFoo.
But TFoo derived types must be handled in the same way, so that I see no 
way around an extended search inside the TFoo STB.


5) What's the meaning of the "ancestor list"? IMO interfaces cannot be 
added by an class helper, and multiple inheritance is quite unlikely. 
Will the ancestor list allow to override interface *implementations*?


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 09:03, Hans-Peter Diettrich wrote:

Paul Ishenin schrieb:


For some reason the visibility is completely ignored here. I can add a
class helper to the strict private or even move it to another unit -
it is always visible.


IMO class helper methods always should become visible as part of the
class, regardless of where they are declared.

 From the Delphi wiki:

"You can define and associate multiple helpers with a single type.
However, only zero or one helper applies in any specific location in
source code. The helper defined in the nearest scope will apply. Class
or record helper scope is determined in the normal Delphi fashion (for
example, right to left in the unit's uses clause)."

I.e. a single Helper reference (field) in the class definition is
sufficient. This field cannot be persistent, instead it has to be
initialized for every use case: whenever a helper is found in the
compiled unit, or in one of its used units, it overwrites the Helper
reference. Adding the helper elements to the class STB is not a valid
solution, because another helper can become active at any time, during
compilation.

The ancestors of the Helper class must be searched as well.



Sorry, I don't understand what you want to tell here.

I personally expect a class helper that is defined inside a private 
section of a class not to be available in another unit like I can't 
access a field or another type defined in there as well.




Also:

"Note that the class helper function MyFunc is called, because the class
helper takes precedence over the actual class type."

That's bad, because this disallows to treat the helper like an ancestor,
accessible in all derived classes :-(



If you want to have a class helper available in a derived class there is 
only one way to do this:


 source begin 
type
  TFoo = class
  end;

  TFooHelper = class helper for TFoo
  end; // this helper only applies to variables of type TFoo

  TBar = class(TFoo)
  end; // No methods of TFooHelper are available for variables of this type

  TBarHelper = class helper(TFooHelper) for TBar
  end; // now all methods of TFooHelper (that aren't overriden by 
TBarHelper) are available for all variables of type TBar as well

 source end 


Interesting questions:

1) Unit A defines an class helper for TFoo, then uses in the
implementation section unit B, which also defines an helper for TFoo.
According to the above rules the helper in A should become inaccessible
and useless then.



This is indeed something that I need to test. And I hope that Delphi 
behaves the way you described (because that would be the consistent 
behavior)



2) Similarly multiple class helpers can be defined in the implementation
section, which are used in the immediately following code, until the
next helper declaration.



Needs to be tested as well, but I hope so.


3) What about derived classes? Since derived classes are compiled
independently, they never will use a reintroduced method in an class
helper.



This is correct. The following does not work in Delphi:

 source begin 
type
  TStringsHelper = class helper for TStrings
procedure Test;
  end;

var
  s: TStringList;
begin
  s.Test; // this won't work
  TStrings(s).Test // but this does
end;
 source end 


4) When class helpers are evaluated at compile time, according to the
static object types (like properties are), then they could be handled
just like the well known typecast hack:

type TMyFoo = class(TFoo)

end;

with following casts of every TFoo reference into TMyFoo.
But TFoo derived types must be handled in the same way, so that I see no
way around an extended search inside the TFoo STB.



Technically class helpers ARE classes that derive from the extended 
class (here: TFoo). But there are no casts of TFoo references. When 
searching for a symbol in a class the last class helper in scope for 
that class is searched first and then the symbol is searched in the 
class itself.



5) What's the meaning of the "ancestor list"? IMO interfaces cannot be
added by an class helper, and multiple inheritance is quite unlikely.
Will the ancestor list allow to override interface *implementations*?


I don't know how you come to interfaces now. But basically from the 
outside class helpers seem to support multiple inheritance, but 
technically they don't. It works like this:


* the extended class is the real parent of the class helper class
* if the class helper has a parent ( e.g. class helper(TFooHelper) for 
TFoo ) this parent is referenced in a mostly unimportant "helperparent" 
field of tobjectdef and only used when searching for a symbol.
At the end the pseudo parent of a class helper tells the compiler to 
search the symbol table of that class helper as well.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 04:30, Paul Ishenin wrote:

30.01.2011 5:22, Sven Barth wrote:

Ok, I have now implemented a set of flags in TSymtable of which one is
set when the (global-,static-)symtable contains a class helper (I
haven't refactored b_needs_init_final yet).

Here are the new results with the search for class helpers enabled
(only two runs this time):

Run 1:
real 2m22.980s
user 0m47.140s
sys 0m4.333s

Run 2:
real 2m15.362s
user 0m47.274s
sys 0m4.140s


Imo it works much better now.


Only one minute slower in the complete run instead of four. I let you 
guys decide whether this is good enough ^^


How often is the compiler compiled completly during a make cycle?

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

30.01.2011 15:45, Sven Barth wrote:

Imo it works much better now.

Only one minute slower in the complete run instead of four. I let you 
guys decide whether this is good enough ^^

2m22.980s -
2m15.362s =
0m7.xxxs - were is a minute?


How often is the compiler compiled completly during a make cycle?

3 times.

Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 09:55, Paul Ishenin wrote:

30.01.2011 15:45, Sven Barth wrote:

Imo it works much better now.

Only one minute slower in the complete run instead of four. I let you
guys decide whether this is good enough ^^

2m22.980s -
2m15.362s =
0m7.xxxs - were is a minute?


That was two runs of the same compiler. I've run it twice, to be sure 
that the workload of the PC doesn't influence the result to much.


The timing of the compiler without class helper search is the one in the 
older mail:



Run 1:
real1m7.982s
user0m46.024s
sys0m4.390s

Run 2:
real1m8.619s
user0m46.104s
sys0m4.513s

Run 3:
real1m10.078s
user0m46.290s
sys0m4.333s



How often is the compiler compiled completly during a make cycle?

3 times.


The first run is done by the starting compiler, right (2.4.2 in my 
case)? So this would mean that roughly half a minute is added by the 
2.5.1 compilers using the class helper search (I'll need to verify this 
assumption of course).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 29.01.2011 23:22, Sven Barth wrote:

Ok, I have now implemented a set of flags in TSymtable of which one is
set when the (global-,static-)symtable contains a class helper (I
haven't refactored b_needs_init_final yet).


I have commited the changes now as well (I was too tired yesterday), so 
please fell free to critize them (especially the ones in ppudump) as I 
need to build on on these changes regarding b_needs_init_final (or 
should this wait until everything is merged back to trunk?).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

30.01.2011 16:22, Sven Barth wrote:
I have commited the changes now as well (I was too tired yesterday), 
so please fell free to critize them (especially the ones in ppudump) 
as I need to build on on these changes regarding b_needs_init_final 
(or should this wait until everything is merged back to trunk?).

b_needs_init_final should wait I think.

Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

30.01.2011 16:22, Sven Barth wrote:
I have commited the changes now as well (I was too tired yesterday), 
so please fell free to critize them (especially the ones in ppudump).

Why do you need ibsymtableoptions ?

Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 11:30, Paul Ishenin wrote:

30.01.2011 16:22, Sven Barth wrote:

I have commited the changes now as well (I was too tired yesterday),
so please fell free to critize them (especially the ones in ppudump).

Why do you need ibsymtableoptions ?


tstoredsymtable stores only definitions and symbols in its own entries, 
so I felt that its more save to add a new entry instead of having a set 
floating around in the nirvana of the ppu.
Also this can be extended later e.g. for Delphi attributes where 
everything seems to be able to carry an attribute (I've seen a variable 
with an attribute already, though I don't know whether this example 
really works/compiles).


And the real reason why I added it: I had problems when I only stored 
the set (the "more save" from above), but this could be related to the 
missing "inherited ppuwrite" call in tabstractlocaldef (which I 
discovered after I had added the entry).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Jonas Maebe

On 30 Jan 2011, at 09:45, Sven Barth wrote:

> Only one minute slower in the complete run instead of four. I let you guys 
> decide whether this is good enough ^^

It's still a lot of overhead.

An alternative solution could be to add a hashtable (tfphaslist) to tmodule 
whose entries are hashed on the qualified class names (unit$classname, since 
different units can contain classes with the same name). The value of such an 
entry would a tfpobjectlist of class helpers, with the last entry the one that 
is actually used. This list has to be updated whenever a symtablestack.push/pop 
is performed (you would probably have to wrap those calls, since the 
symtablestack itself is a fairly low level thing and I don't think it is 
supposed to know anything about tobjectdefs).

The reason for having a list of class helpers rather than only the current 
class helper, is because you would also have to remove class helpers again when 
its symtable is removed from the symtable stack, and this way you wouldn't have 
to search all previous symtables on the stack to see whether they also 
contained a class helper (simply remove all class helpers from the list whose 
owner=symtablestack.top).

Of course, this won't be free either since you have to scan all pushed 
symtables for class helpers, and when popping them you have to go through all 
hashtable items to remove the appropriate ones. I don't know whether overall it 
will be faster or slower than your current approach.

The reason the hashtable would have to be kept per module rather than simply 
adding the list of class helpers in scope to the tabstractrecorddef of the 
relevant record/class, is that in the latter case you would get into trouble 
whenever you switch from parsing one unit to another (which happens a lot while 
parsing uses-clauses). The reason is that you would have to save/restore the 
current class helpers in scope for every abstractrecorddef that has been loaded 
whenever you switched units.


Jonas

PS: the fact that you can have classes with the same name in different units is 
something that requires special handling in any case. In Objective-C, there is 
a global class name space (so all classes with the same name are the same class 
according to the run time), but you probably need different class helper name 
mangling in the case of Object Pascal to prevent false 
collisions.___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Florian Klämpfl
Am 29.01.2011 23:22, schrieb Sven Barth:
> 
> Here are the new results with the search for class helpers enabled (only
> two runs this time):
> 
> Run 1:
> real2m22.980s
> user0m47.140s
> sys0m4.333s
> 
> Run 2:
> real2m15.362s
> user0m47.274s
> sys0m4.140s

With which times are those comparable?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Florian Klämpfl
Am 30.01.2011 09:45, schrieb Sven Barth:
> On 30.01.2011 04:30, Paul Ishenin wrote:
>> 30.01.2011 5:22, Sven Barth wrote:
>>> Ok, I have now implemented a set of flags in TSymtable of which one is
>>> set when the (global-,static-)symtable contains a class helper (I
>>> haven't refactored b_needs_init_final yet).
>>>
>>> Here are the new results with the search for class helpers enabled
>>> (only two runs this time):
>>>
>>> Run 1:
>>> real 2m22.980s
>>> user 0m47.140s
>>> sys 0m4.333s
>>>
>>> Run 2:
>>> real 2m15.362s
>>> user 0m47.274s
>>> sys 0m4.140s
>>
>> Imo it works much better now.
> 
> Only one minute slower in the complete run instead of four. 

Now I understand the timings :) Actually two times slower, right?

> I let you
> guys decide whether this is good enough ^^

Actually I think anything about a ten percent slower compiler will
people make cry ... And as far as I understand, for projects with a lot
of units it will be even worse, right?

> 
> How often is the compiler compiled completly during a make cycle?

2-4 times iirc.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 12:13, Florian Klämpfl wrote:

Am 30.01.2011 09:45, schrieb Sven Barth:

On 30.01.2011 04:30, Paul Ishenin wrote:

30.01.2011 5:22, Sven Barth wrote:

Ok, I have now implemented a set of flags in TSymtable of which one is
set when the (global-,static-)symtable contains a class helper (I
haven't refactored b_needs_init_final yet).

Here are the new results with the search for class helpers enabled
(only two runs this time):

Run 1:
real 2m22.980s
user 0m47.140s
sys 0m4.333s

Run 2:
real 2m15.362s
user 0m47.274s
sys 0m4.140s


Imo it works much better now.


Only one minute slower in the complete run instead of four.


Now I understand the timings :) Actually two times slower, right?



I was a bit bad with explaining my profile results ^^

The complete "make cycle" is two times slower, yes.


I let you
guys decide whether this is good enough ^^


Actually I think anything about a ten percent slower compiler will
people make cry ... And as far as I understand, for projects with a lot
of units it will be even worse, right?



A huge number of units is not the main cause. The main problem is many 
units included in the uses clause. A project could have thousand units, 
but if every unit only used two or three you might not even notice much 
(a very hypothetic scenario, but to show you where the problem is). 
That's why I used the compiler as a testcase (though Lazarus might be a 
good candidate as well...)


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 12:06, Jonas Maebe wrote:


On 30 Jan 2011, at 09:45, Sven Barth wrote:


Only one minute slower in the complete run instead of four. I let you guys 
decide whether this is good enough ^^


It's still a lot of overhead.



Yes and that's why I'm thankful for every suggestion I can get (like 
your one).



An alternative solution could be to add a hashtable (tfphaslist) to tmodule 
whose entries are hashed on the qualified class names (unit$classname, since 
different units can contain classes with the same name). The value of such an 
entry would a tfpobjectlist of class helpers, with the last entry the one that 
is actually used. This list has to be updated whenever a symtablestack.push/pop 
is performed (you would probably have to wrap those calls, since the 
symtablestack itself is a fairly low level thing and I don't think it is 
supposed to know anything about tobjectdefs).

The reason for having a list of class helpers rather than only the current 
class helper, is because you would also have to remove class helpers again when 
its symtable is removed from the symtable stack, and this way you wouldn't have 
to search all previous symtables on the stack to see whether they also 
contained a class helper (simply remove all class helpers from the list whose 
owner=symtablestack.top).

Of course, this won't be free either since you have to scan all pushed 
symtables for class helpers, and when popping them you have to go through all 
hashtable items to remove the appropriate ones. I don't know whether overall it 
will be faster or slower than your current approach.



The need to scan all pushed symtables can be reduced by keeping the flag 
I introduced and using it for this purpose.



The reason the hashtable would have to be kept per module rather than simply 
adding the list of class helpers in scope to the tabstractrecorddef of the 
relevant record/class, is that in the latter case you would get into trouble 
whenever you switch from parsing one unit to another (which happens a lot while 
parsing uses-clauses). The reason is that you would have to save/restore the 
current class helpers in scope for every abstractrecorddef that has been loaded 
whenever you switched units.




Thank you for your suggestion. I'll try to implement this to see whether 
it helps.



PS: the fact that you can have classes with the same name in different units is 
something that requires special handling in any case. In Objective-C, there is 
a global class name space (so all classes with the same name are the same class 
according to the run time), but you probably need different class helper name 
mangling in the case of Object Pascal to prevent false collisions.


While I understand the difference between namespaces in case of 
Objective-C and Object Pascal, I don't understand why I should pay 
attention to the mangling of class helpers. I might be missing a small 
puzzle piece here, so would you please explain this?


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

30.01.2011 15:45, Sven Barth wrote:
Only one minute slower in the complete run instead of four. I let you 
guys decide whether this is good enough ^^


How often is the compiler compiled completly during a make cycle?

I still see an ability to optimize your implementation.

  procedure update_unit_symtable_options;
 var
   st: tsymtable;
 begin
   st:=owner;
   while not(st.symtabletype in [globalsymtable,staticsymtable]) do
 st:=st.defowner.owner;
   if objecttype in [odt_classhelper,odt_objccategory] then
 include(st.tableoptions,sto_has_classhelper);
 end;

remove "if objecttype in [odt_classhelper,odt_objccategory] then" from 
this routine to outside - so you will not need to scan owners in the 
loop for all object types.


Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Martin Schreiber
On Sunday, 30. January 2011 12.13:21 Florian Klämpfl wrote:
>
> Actually I think anything about a ten percent slower compiler will
> people make cry ... And as far as I understand, for projects with a lot
> of units it will be even worse, right?
>
I cry if FPC doesn't compile at least ten percent *faster* than the previous 
release...

Martin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Florian Klämpfl
Am 30.01.2011 12:37, schrieb Martin Schreiber:
> On Sunday, 30. January 2011 12.13:21 Florian Klämpfl wrote:
>>
>> Actually I think anything about a ten percent slower compiler will
>> people make cry ... And as far as I understand, for projects with a lot
>> of units it will be even worse, right?
>>
> I cry if FPC doesn't compile at least ten percent *faster* than the previous 
> release...

Sven, see ;)?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Jonas Maebe

On 30 Jan 2011, at 12:37, Martin Schreiber wrote:

> I cry if FPC doesn't compile at least ten percent *faster* than the previous 
> release...

At least on Mac OS X/i386, we are pretty close to that currently as far as 
compiling the compiler with itself is concerned:

* Compiling it with 2.4.2:
user0m7.663s
sys 0m0.545s

user0m7.540s
sys 0m0.535s

user0m7.527s
sys 0m0.532s

* Compiling it with 2.5.1:

user0m6.972s
sys 0m0.451s

user0m6.967s
sys 0m0.456s

user0m6.966s
sys 0m0.456s

The reason I'm specifically mentioning the used platform is that there's one 
new Mac OS X/i386-specific optimization in 2.5.1 (more efficient PIC 
trampolines, and PIC is enabled by default on that platform), although I cannot 
imagine that it would be completely (or even largely) responsible for an 8% 
speedup.


Jonas___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 13:11, Florian Klämpfl wrote:

Am 30.01.2011 12:37, schrieb Martin Schreiber:

On Sunday, 30. January 2011 12.13:21 Florian Klämpfl wrote:


Actually I think anything about a ten percent slower compiler will
people make cry ... And as far as I understand, for projects with a lot
of units it will be even worse, right?


I cry if FPC doesn't compile at least ten percent *faster* than the previous
release...


Sven, see ;)?


Indeed... :)

Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 12:36, Paul Ishenin wrote:

30.01.2011 15:45, Sven Barth wrote:

Only one minute slower in the complete run instead of four. I let you
guys decide whether this is good enough ^^

How often is the compiler compiled completly during a make cycle?

I still see an ability to optimize your implementation.

procedure update_unit_symtable_options;
var
st: tsymtable;
begin
st:=owner;
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
st:=st.defowner.owner;
if objecttype in [odt_classhelper,odt_objccategory] then
include(st.tableoptions,sto_has_classhelper);
end;

remove "if objecttype in [odt_classhelper,odt_objccategory] then" from
this routine to outside - so you will not need to scan owners in the
loop for all object types.


Sorry, but I don't understand your intention here.
The if-clause is only run after the global- or staticsymtable this class 
belongs to is reached. Or do you mean something completly different?


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Marco van de Voort
In our previous episode, Sven Barth said:
> >>>
> >>> Actually I think anything about a ten percent slower compiler will
> >>> people make cry ... And as far as I understand, for projects with a lot
> >>> of units it will be even worse, right?
> >>>
> >> I cry if FPC doesn't compile at least ten percent *faster* than the 
> >> previous
> >> release...
> >
> > Sven, see ;)?
> 
> Indeed... :)

Don't forget to keep a reign on memory too :-)
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


[fpc-devel] 2.5.1 doesn't build today

2011-01-30 Thread Thaddy

current trunk doesn't build. fails on pxlib
- make clean
- make all
- make zipinstall
Platform i-386-win32
OS XP sp3
Bootstrap 2.4.2
---
make[3]: Entering directory `C:/FPC/2.5.1/packages/pxlib'
make all LINKSMART=1 CREATESMART=1
make[4]: Entering directory `C:/FPC/2.5.1/packages/pxlib'
C:/FPC/2.5.1/compiler/ppc386.exe -XX -CX -Ur -Xs -O2 -n 
-FuC:/FPC/2.5.1/rtl/units/i386-win32 -FE. -F

Uunits/i386-win32 -di386 -dRELEASE src/pxlib.pp
make: Interrupt/Exception caught (code = 0xc005, addr = 0x7c90100b)
make[3]: *** [fpc_smart] Error 255
make[3]: Leaving directory `C:/FPC/2.5.1/packages/pxlib'
make[2]: *** [pxlib_smart] Error 2
make[2]: Leaving directory `C:/FPC/2.5.1/packages'
make[1]: *** [packages_smart] Error 2
make[1]: Leaving directory `C:/FPC/2.5.1'
make: *** [build-stamp.i386-win32] Error 2
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

30.01.2011 19:41, Sven Barth wrote:


procedure update_unit_symtable_options;
var
st: tsymtable;
begin
st:=owner;
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
st:=st.defowner.owner;
if objecttype in [odt_classhelper,odt_objccategory] then
include(st.tableoptions,sto_has_classhelper);
end;

remove "if objecttype in [odt_classhelper,odt_objccategory] then" from
this routine to outside - so you will not need to scan owners in the
loop for all object types.

I still see an ability to optimize your implementation.

Sorry, but I don't understand your intention here.

procedure update_unit_symtable_options;
var
st: tsymtable;
begin
st:=owner;
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
st:=st.defowner.owner;
include(st.tableoptions,sto_has_classhelper);
end;

if objecttype in [odt_classhelper,odt_objccategory] then
   update_unit_symtable_options;

This will work faster because loop and the function call will run not 
for all object types.


Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Sven Barth

On 30.01.2011 15:10, Paul Ishenin wrote:

30.01.2011 19:41, Sven Barth wrote:


procedure update_unit_symtable_options;
var
st: tsymtable;
begin
st:=owner;
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
st:=st.defowner.owner;
if objecttype in [odt_classhelper,odt_objccategory] then
include(st.tableoptions,sto_has_classhelper);
end;

remove "if objecttype in [odt_classhelper,odt_objccategory] then" from
this routine to outside - so you will not need to scan owners in the
loop for all object types.

I still see an ability to optimize your implementation.

Sorry, but I don't understand your intention here.

procedure update_unit_symtable_options;
var
st: tsymtable;
begin
st:=owner;
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
st:=st.defowner.owner;
include(st.tableoptions,sto_has_classhelper);
end;

if objecttype in [odt_classhelper,odt_objccategory] then
update_unit_symtable_options;

This will work faster because loop and the function call will run not
for all object types.


Now I understand. Thanks for clarification.

I've done that change.

Timings without that change:

Run 1:

real1m3.461s
user0m45.957s
sys 0m4.590s

Run 2:

real1m10.777s
user0m46.204s
sys 0m4.696s

Run 3:

real1m11.596s
user0m46.690s
sys 0m4.406s

Timings with that change:

Run 1:

real1m8.919s
user0m46.597s
sys 0m4.166s

Run 2:

real1m9.359s
user0m46.524s
sys 0m4.380s

Run 3:

real1m8.342s
user0m46.294s
sys 0m4.490s

Doesn't change much. For comparison timings without the search for class 
helpers (if-clause in symtable.pas/searchsym_in_class disabled):


Run 1:

real1m5.040s
user0m46.050s
sys 0m4.163s

Run 2:

real1m4.008s
user0m45.784s
sys 0m4.343s

Run 3:

real1m6.074s
user0m45.714s
sys 0m4.546s


It seems that I should have rerun the profiling without class helper 
search as well after I added the flag yesterday...


I'll nevertheless try to implement Jonas' suggestion to see whether this 
improves timing a bit more (and maybe the flags can be used to optimize 
the speed for other types of searches a bit more, like Paul suggested :D )


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Paul Ishenin

31.01.2011 0:26, Sven Barth wrote:

Timings without that change:

Run 1:

real1m3.461s
user0m45.957s
sys0m4.590s

Timings with that change:

Run 1:

real1m8.919s
user0m46.597s
sys0m4.166s


But previously you gave 2 minutes values.

Best regards,
Paul Ishenin
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Hans-Peter Diettrich

Sven Barth schrieb:


Sorry, I don't understand what you want to tell here.


Sorry2, I'll retry.

I personally expect a class helper that is defined inside a private 
section of a class not to be available in another unit like I can't 
access a field or another type defined in there as well.


Delphi allows for *at most* one active class helper, determined by the 
unit search order, just like every other ambiguous identifier is 
resolved. If you don't want an class helper used in other units, simply 
move it to the implementation section.


Hiding an class helper in a private section of a class IMO is not the 
right way, and the result may be compiler specific.



If you want to have a class helper available in a derived class there is 
only one way to do this:

[...]

Okay, now I understand the use of one ancestor, but still not the use of 
a list of ancestors.




3) What about derived classes? Since derived classes are compiled
independently, they never will use a reintroduced method in an class
helper.



This is correct. The following does not work in Delphi:

 source begin 
type
  TStringsHelper = class helper for TStrings
procedure Test;
  end;

var
  s: TStringList;
begin
  s.Test; // this won't work
  TStrings(s).Test // but this does
end;
 source end 


This looks very much like my #4.


4) When class helpers are evaluated at compile time, according to the
static object types (like properties are), then they could be handled
just like the well known typecast hack:

type TMyFoo = class(TFoo)

end;

with following casts of every TFoo reference into TMyFoo.
But TFoo derived types must be handled in the same way, so that I see no
way around an extended search inside the TFoo STB.



Technically class helpers ARE classes that derive from the extended 
class (here: TFoo). But there are no casts of TFoo references. When 
searching for a symbol in a class the last class helper in scope for 
that class is searched first and then the symbol is searched in the 
class itself.


Then one possible implementation could hide the extended class (TFoo), 
and use the helper class STB instead. This were the implementation of an 
implicit type cast. The symtable stack has to be built or modified 
accordingly, so that searching continues in the proper class ancestors.




5) What's the meaning of the "ancestor list"? IMO interfaces cannot be
added by an class helper, and multiple inheritance is quite unlikely.
Will the ancestor list allow to override interface *implementations*?


I don't know how you come to interfaces now.


This is the normal use of a *list* of ancestors. The first ancestor 
denotes the parent class, all others denote interfaces.


But basically from the 
outside class helpers seem to support multiple inheritance, but 
technically they don't. It works like this:


* the extended class is the real parent of the class helper class
* if the class helper has a parent ( e.g. class helper(TFooHelper) for 
TFoo ) this parent is referenced in a mostly unimportant "helperparent" 
field of tobjectdef and only used when searching for a symbol.
At the end the pseudo parent of a class helper tells the compiler to 
search the symbol table of that class helper as well.


See above.

I'd push the extended class onto the symtable stack, then the class 
helper parents, and finally the class helper itself, and use that stack 
whenever a reference to a class with a helper class is encounterd.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Hans-Peter Diettrich

Jonas Maebe schrieb:


An alternative solution could be to add a hashtable (tfphaslist) to
tmodule whose entries are hashed on the qualified class names
(unit$classname, since different units can contain classes with the
same name). The value of such an entry would a tfpobjectlist of class
helpers, with the last entry the one that is actually used. This list
has to be updated whenever a symtablestack.push/pop is performed (you
would probably have to wrap those calls, since the symtablestack
itself is a fairly low level thing and I don't think it is supposed
to know anything about tobjectdefs).


IIRC a class symtable is pushed onto the symtable stack, whenever a 
qualifier is encountered (e.g. "TFoo."). Regardless of the 
implementation, this makes the symbol search start in TFoo and continue 
in its ancestors, before the remainder of the stack is searched. It 
should be possible to extend that mechanism, adding eventual class 
helpers to the search order.


Removal of such a qualified scope, with all contained ancestors, also 
must have been implemented already, and should not deserve much changing.




Of course, this won't be free either since you have to scan all
pushed symtables for class helpers, and when popping them you have to
go through all hashtable items to remove the appropriate ones. I
don't know whether overall it will be faster or slower than your
current approach.


Is the hashtable *really* rebuilt with every push and pop of another 
symtable? It would be much easier to have a hashtable per symtable, that 
deserves no further modifications. When all hashtables use the same hash 
algorithm, a hash value must be computed only once, and then can be used 
for lookup in every STB on the stack.


DoDi

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Thaddy

On 31-1-2011 2:06, Hans-Peter Diettrich wrote:

Jonas Maebe schrieb:


Is the hashtable *really* rebuilt with every push and pop of another 
symtable? It would be much easier to have a hashtable per symtable, 
that deserves no further modifications. When all hashtables use the 
same hash algorithm, a hash value must be computed only once, and then 
can be used for lookup in every STB on the stack.


DoDi

 CRC's are also hashes. isn't that used?

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel


Re: [fpc-devel] Status report for "class helpers"

2011-01-30 Thread Burkhard Carstens
Am Montag, 31. Januar 2011 00:57 schrieb Paul Ishenin:
> 31.01.2011 0:26, Sven Barth wrote:
> > Timings without that change:
> >
> > Run 1:
> >
> > real1m3.461s
> > user0m45.957s
> > sys0m4.590s
> >
> > Timings with that change:
> >
> > Run 1:
> >
> > real1m8.919s
> > user0m46.597s
> > sys0m4.166s
>
> But previously you gave 2 minutes values.
>
AFAIK, the "real" time is pretty meaningless. It just says how much time 
passed between prg start and prg end.
The "user" time is the interesting one. It says how much processor time 
the prg used actually doing something instead of waiting to be sheduled 
by the OS. That's why a multithreaded app on a multi-core can have 
higher user time than real time.

regards
 Burkhard

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel