Type checking

2010-03-17 Thread Andrew Cowie
In a previous thread about sealing accessors and how that means more
type checking,

On Wed, 2010-03-17 at 17:10 +, Emmanuele Bassi wrote: 
> this might be the kick in the arse needed to get type checking down to a
> minimal cost

We have observed in the past that the type checking calls are 2-3% of
program run time [that needs to be verified with the current stack, of
course, but we've seen reports like that on the GTK lists within the
last few years]. That's a lot :|

I've often wondered about it, because on the one hand we have 

void
gtk_button_set_label (GtkButton   *button,
  const gchar *label)
{
  g_return_if_fail (GTK_IS_BUTTON (button));

in gtk/gtkbutton.c which after wading through several macros ends up as
a call to g_type_check_instance() in glib/gtype.c with some if/else
blocks around it.

Meanwhile most of the time (in C anyway) people call 

gtk_button_set_label(GTK_BUTTON(button), "Hello World");

which ends up as a call to g_type_check_instance_cast() which does most
of the same stuff as g_type_check_instance() does.

I'm aware of this partly because in java-gnome's generated code we ended
up casting to the public types directly (wasn't my idea, it's what I
inherited, and lo it works):

GtkButton* button;
...
button = (GtkButton*) user_data;
gtk_button_set_label(button, "Hello World");

and it's been working for us because a) we have correct type information
so we're casting the right thing anyway, and b) because the first thing
the functions we are calling do is check the type of the inbound
pointer.

So I'm wondering: can we [C, GTK] do away with one of the code paths
entirely? It'd be nice to do away with the checks in the internal
accessors, of course, but that isn't going to happen because the
internal code is now using the public accessors.

So maybe we can at least not check in the cast macros?

Again, I haven't profiled a C only applcation in a while, so this may be
out of date. Someone with a GUI heavy C app would need to check. But
this used to be really expensive for C apps. And meanwhile we're using
GTK for some years now without using the cast macros at all, and things
are working. So that's at least a datapoint.

AfC
Sydney


-- 
Andrew Frederick Cowie

Operational Dynamics is an operations and engineering consultancy
focusing on IT strategy, organizational architecture, systems
review, and effective procedures for change management: enabling
successful deployment of mission critical information technology in
enterprises, worldwide.

http://www.operationaldynamics.com/

Sydney   New York   Toronto   London


signature.asc
Description: This is a digitally signed message part
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-17 Thread Martyn Russell

On 17/03/10 22:03, Andrew Cowie wrote:

in gtk/gtkbutton.c which after wading through several macros ends up as
a call to g_type_check_instance() in glib/gtype.c with some if/else
blocks around it.


[snip]


So I'm wondering: can we [C, GTK] do away with one of the code paths
entirely? It'd be nice to do away with the checks in the internal
accessors, of course, but that isn't going to happen because the
internal code is now using the public accessors.

So maybe we can at least not check in the cast macros?

Again, I haven't profiled a C only applcation in a while, so this may be
out of date. Someone with a GUI heavy C app would need to check. But
this used to be really expensive for C apps. And meanwhile we're using
GTK for some years now without using the cast macros at all, and things
are working. So that's at least a datapoint.


Isn't this why we have G_DISABLE_CAST_CHECKS ?

--
Regards,
Martyn
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-17 Thread Emmanuele Bassi
On Thu, 2010-03-18 at 09:03 +1100, Andrew Cowie wrote:

> I've often wondered about it, because on the one hand we have 
> 
> void
> gtk_button_set_label (GtkButton   *button,
> const gchar *label)
> {
>   g_return_if_fail (GTK_IS_BUTTON (button));
> 
> in gtk/gtkbutton.c which after wading through several macros ends up as
> a call to g_type_check_instance() in glib/gtype.c with some if/else
> blocks around it.

the G_TYPE_CHECK_INSTANCE_TYPE() macro won't be disabled - ever. the
only way to disable that particular type check is to compile with
-DG_DISABLE_CHECKS, which disables g_return_*() -- and you don't really
want to do that.

> Meanwhile most of the time (in C anyway) people call 
> 
> gtk_button_set_label(GTK_BUTTON(button), "Hello World");

which can be disabled by using -DG_DISABLE_CAST_CHECKS, resulting in:

  #define GTK_BUTTON(obj)   ((GtkButton *) (obj))

a plain, unchecked C cast.

> and it's been working for us because a) we have correct type information
> so we're casting the right thing anyway, and b) because the first thing
> the functions we are calling do is check the type of the inbound
> pointer.

that's something only a binding could do - but only certain bindings can
actually offer this degree of type checking. for most dynamic languages
out there, the actual type check should be deferred to GObject.

> So maybe we can at least not check in the cast macros?

again, -DG_DISABLE_CAST_CHECKS does that.

surrendering type checking in a run-time type system is giving up the
little slice of safety it guarantees. we do type checking on both ends
because we don't know what's been fed to the public API; private API
should not have type checks (but they should assert() if the internal
state is screwed). a stop gap solution is to avoid doing crazy stuff
like:

  static void
  my_blah_widget_init (MyBlahWidget *widget)
  {
gtk_widget_set_foo (GTK_WIDGET (widget), TRUE);
gtk_widget_set_bar (GTK_WIDGET (widget), FALSE);
gtk_widget_set_baz (GTK_WIDGET (widget), 42);
  }

and do one since cast instead:

  static void
  my_blah_widget_init (MyBlahWidget *widget)
  {
GtkWidget *w = GTK_WIDGET (widget);

gtk_widget_set_foo (w, TRUE);
gtk_widget_set_bar (w, FALSE);
gtk_widget_set_baz (w, 42);
  }

the real solution, though obviously more involved, is to make type
checking faster; it's a common operation, so shaving 50% off would
result in an overall benefit for everyone. the recent fixes Alexander
wrote and that went into making type checks on interfaces an O(1)
operation are a step in the right direction, especially for libraries
that use interfaces a lot.

ciao,
 Emmanuele.

-- 
W: http://www.emmanuelebassi.name
B: http://blogs.gnome.org/ebassi

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-17 Thread Colomban Wendling
Martyn Russell a écrit :
> On 17/03/10 22:03, Andrew Cowie wrote:
>> in gtk/gtkbutton.c which after wading through several macros ends up as
>> a call to g_type_check_instance() in glib/gtype.c with some if/else
>> blocks around it.
> 
> [snip]
> 
>> So I'm wondering: can we [C, GTK] do away with one of the code paths
>> entirely? It'd be nice to do away with the checks in the internal
>> accessors, of course, but that isn't going to happen because the
>> internal code is now using the public accessors.
>>
>> So maybe we can at least not check in the cast macros?
>>
>> Again, I haven't profiled a C only applcation in a while, so this may be
>> out of date. Someone with a GUI heavy C app would need to check. But
>> this used to be really expensive for C apps. And meanwhile we're using
>> GTK for some years now without using the cast macros at all, and things
>> are working. So that's at least a datapoint.
> 
> Isn't this why we have G_DISABLE_CAST_CHECKS ?
> 
And G_DISABLE_CHECKS for g_return*s.

If enabling them really worth it in terms of performances, builders
(users, distributors, etc) may want to do so.
But if G_DISABLE_CAST_CHECKS does only affect the program that is built
with (it changes only the internal casts), G_DISABLE_CHECKS have more
impact: the functions would no longer check their arguments, even when
called from applications.

So I think that using G_DISABLE_CAST_CHECKS may be a good idea if it
have an impact on performances, but G_DISABLE_CHECKS is more
questionable, and should probably not be the default.


My 2 cents..
Colomban W.

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-17 Thread Kalle Vahlman
2010/3/18 Emmanuele Bassi :
> On Thu, 2010-03-18 at 09:03 +1100, Andrew Cowie wrote:
>
>> I've often wondered about it, because on the one hand we have
>>
>>         void
>>         gtk_button_set_label (GtkButton   *button,
>>                             const gchar *label)
>>         {
>>           g_return_if_fail (GTK_IS_BUTTON (button));
>>
>> in gtk/gtkbutton.c which after wading through several macros ends up as
>> a call to g_type_check_instance() in glib/gtype.c with some if/else
>> blocks around it.
>
> the G_TYPE_CHECK_INSTANCE_TYPE() macro won't be disabled - ever. the
> only way to disable that particular type check is to compile with
> -DG_DISABLE_CHECKS, which disables g_return_*() -- and you don't really
> want to do that.

That's actually "you can't really do that", disabling checks (or to be
exact, using --disable-debug) would be nice enough for eg. embedded
systems, but since applications (and libraries) tend to regularly feed
invalid arguments to libraries and trust the library to handle it all
you get from it is crashing applications. Even gio was broken wrt
this: https://bugzilla.gnome.org/show_bug.cgi?id=593856

It's kind of a sad situation. :(

-- 
Kalle Vahlman, z...@iki.fi
Powered by http://movial.com
Interesting stuff at http://sandbox.movial.com
See also http://syslog.movial.fi
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-18 Thread Emmanuele Bassi
On Thu, 2010-03-18 at 07:30 +0200, Kalle Vahlman wrote:

> > the G_TYPE_CHECK_INSTANCE_TYPE() macro won't be disabled - ever. the
> > only way to disable that particular type check is to compile with
> > -DG_DISABLE_CHECKS, which disables g_return_*() -- and you don't really
> > want to do that.
> 
> That's actually "you can't really do that", disabling checks (or to be
> exact, using --disable-debug) would be nice enough for eg. embedded
> systems, but since applications (and libraries) tend to regularly feed
> invalid arguments to libraries and trust the library to handle it all
> you get from it is crashing applications. Even gio was broken wrt
> this: https://bugzilla.gnome.org/show_bug.cgi?id=593856
> 
> It's kind of a sad situation. :(

that's different: --disable-debug (or --enable-debug=no) also adds
-DG_DISABLE_ASSERT which you really, *really* don't want to do.

using --enable-debug=minimum (which disables cast checks) and manually
adding -DG_DISABLE_CHECKS to the CPPFLAGS should be enough for embedded
environments.

CAVEAT: I'm not advocating package maintainers on embedded systems to
use --enable-debug=no *ever*, unless:

  • they audit all the code compiled beforehand
  • they come up with numbers that demonstrate the advantages of
disabling the type checking layer against the potential failures

in all other cases, running with --enable-debug=no is Just Plain Wrong™.
been there, done that.

ciao,
 Emmanuele.

-- 
W: http://www.emmanuelebassi.name
B: http://blogs.gnome.org/ebassi

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Type checking

2010-03-18 Thread Dan Winship
On 03/17/2010 07:40 PM, Emmanuele Bassi wrote:
> a stop gap solution is to avoid doing crazy stuff
> like:
> 
>   static void
>   my_blah_widget_init (MyBlahWidget *widget)
>   {
> gtk_widget_set_foo (GTK_WIDGET (widget), TRUE);
> gtk_widget_set_bar (GTK_WIDGET (widget), FALSE);
> gtk_widget_set_baz (GTK_WIDGET (widget), 42);
>   }
> 
> and do one since cast instead:
> 
>   static void
>   my_blah_widget_init (MyBlahWidget *widget)
>   {
> GtkWidget *w = GTK_WIDGET (widget);
> 
> gtk_widget_set_foo (w, TRUE);
> gtk_widget_set_bar (w, FALSE);
> gtk_widget_set_baz (w, 42);
>   }

https://bugzilla.gnome.org/show_bug.cgi?id=567256 has a very small patch
that makes it so that:

if (MY_IS_BLAH_WIDGET (widget)) {
MyBlahWidget *mbw = MY_BLAH_WIDGET (widget);

only does a single type check (if you compile with optimization, and
my_blah_widget_get_type() is marked G_GNUC_CONST). I thought it would
fix your case too, but it doesn't, because theoretically
gtk_widget_set_foo() might cause @widget to stop being a widget, so it
needs to typecheck it again...

Pretty sure we could fix this too though, by changing _G_TYPE_CIT to use
"g_type_is_a (_inst->g_class->g_type, __t)" instead of
"g_type_check_instance_is_a (__inst, __t)". Except that instead of
g_type_is_a(), it would have to be a new method that does exactly the
same thing as g_type_is_a(), but is G_GNUC_PURE (and is therefore only
safe to call in cases where you know the type's hierarchy isn't going to
change in the future).

(Marking _get_type() methods G_GNUC_CONST makes it tricky to forcibly
initialize a type, but https://bugzilla.gnome.org/show_bug.cgi?id=605976
has a patch to add "g_type_ensure()" to hide the complexity.)

Of course, this doesn't help Andrew's original case, where the is_a and
the cast are in separate functions...

-- Dan
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list