"os" - make this a real namespace?
Thomas Stüfe
thomas.stuefe at gmail.com
Thu Oct 20 07:22:36 UTC 2016
On Thu, Oct 20, 2016 at 1:59 AM, David Holmes <david.holmes at oracle.com>
wrote:
> 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
>
>
When there is time, I may just whip up an example patch. This may be
simpler than talking. I understand this would be something for java10, so
it has to wait until there is at least a repo.
Kind Regards, Thomas
> 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