[webkit-dev] SharedWorkers alternate design

Jeremy Orlow jorlow at chromium.org
Tue May 26 16:12:15 PDT 2009

The common case is definitely that we know whether we want the proxy (for
IPC) or the implementation at compile time.  In some cases (like Chromium)
this is not known until initialization time.  So the ideal is a clean way to
handle the "not known until initialization" while optimizing for the compile
time case.  Here's a proposal:

For the compile time decision case, do everything the same as it's done in
ResourceRequest:  Have an interface (StorageBackendInterface), a "Base"
class (except in this case we'll have 2 which we'll call
"StorageBackendImpl" and "StorageBackendProxy"), and then the class
everything uses (StorageBackend).  The decision of which base class
StorageBackend should inherit from can be made based on a preprocessor
define.  Everything basically works as Maciej suggested.

For the initialization time decision case, we flip things on their head: we
prepend "virtual" to every method declaration in StorageBackend (via a
define that's either "virtual" or "") and switch the inheritance order so
that StorageBackendImpl/Proxy inherit from StorageBackend.  Now all those
casts we were doing above (i.e. StorageBackendImpl casting itself to
StorageBackend and calling a method) are completely legal type system wise
(because they're casting it to a base class).  Additionally, any calls to
functions that used to be inherited (i.e. StorageBackend making a call to
something in StorageBackendImpl) are ok because it's just doing a virtual
dispatch.  (The key is that every function shared between the StorageBackend
and the Impl/Proxy needs to be declared in the Interface.)

This still seems really ugly and overly complicated.  I'm actually about to
send out code for https://bugs.webkit.org/show_bug.cgi?id=25376 that uses
plain old virtual dispatch and everything runs at exactly the same speed it
used to.  (I made an ad-hoc benchmark so I could double check such things.)
 So....I'm really not sure all of this trickery makes sense for what I'm
working on, but it might be necessary elsewhere.


On Tue, May 26, 2009 at 11:11 AM, Jeremy Orlow <jorlow at chromium.org> wrote:

> Note that Chromium uses the same binary/libraries for the render process
> and the browser process, which means that the decision can't be made in
> compile time for us.
> There might be ways (like what you mentioned) to allow the compiler to skip
> all the virtual stuff for implementations where the decision can be made in
> compile time (the normal case).  I've got some ideas....I'll try to explain
> them when I get a second later this afternoon.
> J
> On Tue, May 26, 2009 at 10:43 AM, Drew Wilson <atwilson at google.com> wrote:
>> Thanks for the explanation, Maciej. I actually looked at ResourceRequest
>> prior to sending my mail, but I wasn't clear what makefile magic was being
>> used to load the correct version of ResourceRequest.h for a given platform.
>> For example, if I look at WebCore/WebCore.vcproj/WebCore.vcproj, I see
>> only two references to ResourceRequest.h: platform/network/curl and
>> platform/network/cf, but clearly we might want to use the chromium/ or win/
>> versions as well. Can someone give me a quick explanation of how the
>> platform-specific version is selected at compile time?
>> Do we have a naming convention for the "default" implementation? I'm
>> expecting there to be two versions of SharedWorkerRepository - the chromium
>> version, and the <everything else> version.
>> -atw
>> On Tue, May 26, 2009 at 10:36 AM, Maciej Stachowiak <mjs at apple.com>wrote:
>>> On May 26, 2009, at 10:21 AM, Darin Adler wrote:
>>>  On May 26, 2009, at 10:16 AM, Drew Wilson wrote:
>>>>  OK, I've got two strong votes for the interface + static factory
>>>>> approach. Any objections from the rest of the WebKit team? If I don't hear
>>>>> any counter proposals, I'll do that.
>>>> I think it's unpleasant to pay run-time cost for a compile-time choice.
>>>> Sure, sometimes the extra cost is no big deal, but sometimes it can be a big
>>>> deal and I see no reason to choose idioms that use virtual functions if
>>>> there are equally good or better ones that don't.
>>>> Are there really no better techniques than abstract base classes and
>>>> virtual functions for this sort of compile-time switch? How about the
>>>> technique used for ResourceRequest and ResourceResponse? Maybe Darin Fisher
>>>> can explain that one.
>>> I agree with Darin's comments here. We've tried hard to avoid using
>>> runtime polymorphism for compile-time choices. Here it's probably not
>>> performance-critical, but it can be avoided.
>>> The ResourceRequestBase / ResourceRequest model (due to Darin Fisher)
>>> seems pretty clean to me. I would like to see more of our classes with
>>> port-specific implementation details move to this style. I think it could
>>> work for SharedWorkerRepository.
>>> The basic idea is this. Let's say you have a class FooBar.
>>> - You define a FooBarBase class that has the cross-platform interface and
>>> data members. But not all the methods are actually implemented in the
>>> cross-platform code. All of its constructors are protected so the class
>>> cannot be instantiated directly.
>>> - Each port subclasses FooBarBase to define FooBar, adding constructors,
>>> platform-specific data members, and any needed platform-specific private
>>> helpers or type conversions.
>>> - Each port implements the methods of FooBarBase that are
>>> platform-specific, freely downcasting to FooBar when needed since we have
>>> guaranteed that every instance of FooBarBase is actually a FooBar.
>>> - Cross-platform code using the class just uses FooBar. The Base class is
>>> an implementation detail.
>>> (Darin F., please correct me if I have not done justice to this
>>> technique.)
>>> Note that this method has no runtime cost - there's no need to use
>>> virtual methods or other forms of runtime indirection. And there's no need
>>> to #ifdef any headers, everything is controlled purely by including the
>>> right platform specific FooBar.h so it can be handled by include paths. It's
>>> a little subtle at first but I think it results in nice, understandable
>>> code.
>>> I think we should document this technique as the preferred way to make
>>> classes with port-specific implementation details and convert more of
>>> WebCore/platform/ to this technique, as well as using it for new classes.
>>> Regards,
>>> Maciej
>> _______________________________________________
>> webkit-dev mailing list
>> webkit-dev at lists.webkit.org
>> http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20090526/db3fa978/attachment.html>

More information about the webkit-dev mailing list