"os" - make this a real namespace?
David Holmes
david.holmes at oracle.com
Wed Oct 19 23:59:04 UTC 2016
On 19/10/2016 11:54 PM, Thomas Stüfe wrote:
> Hi David,
>
> my intent was not to attack the existing code, but to ask about the
> original design intentions and possibly come up with ideas to improve
> it. See my further answers inline.
Sure - no problem. It is hard to understand the intent of the design
when the remaining code doesn't even reflect the original design
intentions (nor is there anyone around involved in that!). And there is
always scope to redo this as part of the "big OS code cleanup".
The "exposure" concern is not one that I've heard expressed previously
in relation to the hotspot code.
Cheers,
David
> On Wed, Oct 19, 2016 at 2:19 PM, David Holmes <david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
>
> Hi Thomas,
>
> On 19/10/2016 7:07 PM, Thomas Stüfe wrote:
>
> Hi David!
>
> On Wed, Oct 19, 2016 at 9:02 AM, David Holmes
> <david.holmes at oracle.com <mailto:david.holmes at oracle.com>
> <mailto:david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>>> wrote:
>
> Hi Thomas,
>
> On 19/10/2016 4:10 PM, Thomas Stüfe wrote:
>
> Hi all,
>
> a small question.
>
> I sometimes stumble over the fact that "os" is a class,
> not a
> namespace.
>
>
> ?? AFAIK everything in hotspot is a class not a namespace -
> we don't
> use "namespaces".
>
>
> I meant that it is used as one would use a C++ namespace, not a
> class.
> As far as I see any class derived from AllStatic is actually a
> namespace
> in the sense that it serves as bracket for a number of related
> static
> functions.
>
>
> Okay ... if that is what you mean by a namespace ... I always
> thought namespaces were like packages, a level up from classes.
>
>
> I always used namespace as a common scope for declarations which belong
> together, be that classes, global functions, variables. I always thought
> this is how class "os" is used in the hotspot.
>
> I also use C++ namespace to isolate coding in large projects I do not
> own but where my symbols are, for technical reasons, visible anywhere
> but I want to avoid name clashes. A typical porter headache. E.g. we
> have a namespace "sap" in our coding, just to keep our stuff separate
> from global symbols.
>
>
>
> And that we include the platform dependent additions
> into the
> middle of this class.
>
>
> Build-time specialization. It allows for the os API to
> actually be
> different on different platforms, as opposed to just being
> implemented differently.
>
>
> The "os" API is a shared, platform independent API, so there
> should be
> no difference between platforms. There should be no need for it to
> export platform specifics - its whole intent is to hide those
> specifics.
>
>
> But that is your current design perspective of what the os API
> should be. What it is is something with a very long history and
> which has had to accommodate different things over time. At one
> point a lot of the JDK native code would call into the VM for
> functionality that is now directly implemented in JDK native code.
> There's a lot of historical baggage here.
>
>
> Looking into the various os_<os>.hpp files, I see:
> 1) things where the declaration does differ between oses and
> therefore
> they cannot be called in shared code without #ifdefs (e.g. all <os>
> subclasses).
> 2)Things where the declaration is shared but the implementation
> differs.
> Again, two cases:
> a) Either implementation is not time critical. In that case the
> declaration should live in os.hpp and the implementation should
> live in
> some platform dependent C++ file.
> b) Or implementation is time critical and must be inline, in
> which
> case a separate platform dependent header would be needed.
>
> For (1) and (2b), C++ namespaces would be more convenient. Now,
> you are
> forced to include the platform specific file into the class os{}
> declaration, because there can just be one:
>
> os.hpp
> class os {
> ...
> #include <os_xxx.hpp>
>
> };
>
> . With a namespace, you can add functions to the namespace in
> various
> disjunct places and hence could write:
>
> os.hpp
> namespace os { ... functions ... }
>
> os_xxx.hpp
> namespace os { ... functions ... }
>
> which would be more natural and
>
>
> Yes I can see that as an alternative way to expand the os API.
> Though I still prefer to group functionality in a class.
>
>
> I would argue that the advantage of namespaces here is that the special
> handling of platform specific headers is not needed anymore. Now, when
> reading any os_<os>/<cpu> header, I need to keep in mind that the
> content of this header gets inserted into the middle of a class
> definition. That is just rather exotic and unexpected and tripped me
> over a few times already.
>
>
>
> This has a number of repercussions, like not being able to
> include the
> platform dependent files (os_<os>_<cpu>) directly, not
> being able to
>
>
> I'd call that a feature - they are not intended to be
> standalone APIs.
>
>
> There are a number of useful "os" APIs which I would sometimes like to
> use without the bagage of including the whole os.hpp header. For
> instance, os::malloc(). Normally, I would forward declare them, but this
> is not possible for class functions.
>
>
>
>
> Right now os_<os>.hpp exports the os::<os> api, which one may
> want to
> use separately from "os" because they expose platform dependent APIs
> which are conceptionally lower than the os namespace. At least
> that is
> how I always did interpret the intention behind os::<os>.
>
>
> I wouldn't say lower - they extend the os API with platform specific
> functionality and concepts. The idea is that <os> specific code that
> wants to use OS facilities that are specific to that <os> access
> them through the os::<os> class.
>
>
>
> But actually, because the "Aix" class is part of "os", cannot be
> used
> separately and is exposed to the whole of the VM, I always avoided
> putting anything os::Aix if it could be helped. Hence, for AIX,
> we added
> porting_aix.hpp for AIX specific functions which are not to be used
> outside os/aix/vm. Or mostly just plain left functions to be
> file scope
> static inside os_aix.cpp. So, os::Aix was pretty useless for me
> as a porter.
>
>
> Seems you made a decision that the os::AIX class didn't meet your
> ideas as to how platform specifics should be handled and so went
> with an alternative design. Wouldn't that make it "useless" because
> you chose not to use it?
>
>
> When the AIX port started, the os interface was not well documented. Nor
> was there anyone I could ask because OpenJDK did not yet exist. So I had
> to deduce the intent of the original authors from the code and try to
> fill it with life as best as possible.
>
>
>
> forward declare functions from the "os" namespace (e.g.
> os::malloc) etc. I
> also cannot split implementations from "os" functions to
> different
> implementation files without problems.
>
> It seems to me all compiler nowadays support namespaces,
> would
> it not make sense to convert "os" to a real namespace?
>
>
> Not being a C++ aficionado I'm not sure exactly what that would
> entail - as far as I know we don't use C++ namespaces
> anywhere in
> hotspot.
>
>
> We start using all kinds of modern C++ features. Templates pop
> up all
> over the place. Namespaces in contrast are an old and easily
> understood
> feature. We already use it inside our own port.
>
>
> While we are at it, what is the reason for the "<os>" sub
> classes? e.g.
> os::Bsd, os::Aix etc? It makes integrating patches
> between platforms
> difficult and, to me, does not seem to serve any clear
> purpose.
>
>
> Must admit this arrangement has also had me confused at times. I
> think it is way to add a per-OS helper class for the main os API
> implementation.
>
> If the purpose is to be a very low wrapper around OS
> particularities, it
> makes no sense to have them in the "os" namespace and to
> make
> them visible
> to the shared sections of the VM. E.g. there should be
> no reason
> to access
> "os::Bsd" functions from outside os/bsd/vm, or to access
> "os::Posix"
> functions outside implementations specific for Posix
> platforms.
>
>
> Not sure how you make, for example os::BSD accessible from all
> classes in os/bsd/vm yet not be visible anywhere else ??
>
>
> I think there is no real reason for os::Bsd to exist at all.
> Either we
> have shared functions with platform dependent implementation,
> then they
> should be declared in "os". Or they are completely platform
> specific,
> then they can be moved to a platform specific header outside of "os"
> like we did with porting_aix.hpp.
>
>
> Sure you could do that. But 20 years ago that wasn't how things were
> designed and we have what we have today. As I said a lot of baggage.
>
> Personally I find the nesting of the concrete os API quite natural:
> os::win32 to me is better than unrelated os and win32 classes or
> namespaces.
>
>
> I think there is code structure, and then there is exposure. Both are
> separate things but currently interwoven in the hotspot.
>
> Putting Win32 specifics into os::win32 makes sense. But there is no
> reason to expose os::win32 to shared parts of the VM, considering how
> much the hotspot programmers at Oracle dislike platform specific #ifdefs
> in shared code.
>
> I understand that this is historical? Before namespaces, you had to
> define a class as common bracket, and a class definition must be
> complete to be valid, so os::<OS> is automatically visible everywhere.
> But with namespaces this could be disentangled. We could have a globally
> visible "os" namespace with platform independent shared functions, as
> well as an "os::win32" namespace which is only visible in windows
> specific implementation files.
>
> Kind Regards, Thomas
>
>
> Cheers,
> David
> -----
>
>
> Plus it also needs to potentially be visible from
> os_cpu/bsd_XXX/vm.
>
>
> There is a lot of cleanup in this area slated for the future -
> hopefully Java 10. POSIX refactoring etc.
>
>
> Sure!
>
> Kind Regards, Thomas
>
>
> Cheers,
> David
>
>
> Thanks, and Kind Regards, Thomas
>
>
>
More information about the hotspot-runtime-dev
mailing list