JDK-8196889 : VS2017 Unable to Instantiate OrderAccess::release_store with an Incomplete Class Within an Inlined Method
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 11
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: windows
  • Submitted: 2018-02-06
  • Updated: 2019-06-20
  • Resolved: 2018-02-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11
11 b03Fixed
Related Reports
Relates :  
Description
abstractInterpreter.cpp
<directory>\open\src\hotspot\share\runtime/orderAccess.inline.hpp(59): error C2027: use of undefined type 'Atomic::StoreImpl<T,D,OrderAccess::PlatformOrderedStore<8,RELEASE_X>,void>'
        with
        [
            T=ClassPathEntry *,
            D=ClassPathEntry *
        ]
<directory>\open\src\hotspot\share\runtime/orderAccess.inline.hpp(59): note: see declaration of 'Atomic::StoreImpl<T,D,OrderAccess::PlatformOrderedStore<8,RELEASE_X>,void>'
        with
        [
            T=ClassPathEntry *,
            D=ClassPathEntry *
        ]
<directory>\open\src\hotspot\share\classfile/classLoader.hpp(57): note: see reference to function template instantiation 'void OrderAccess::release_store<ClassPathEntry*,ClassPathEntry*>(volatile D *,T)' being compiled
        with
        [
            D=ClassPathEntry *,
            T=ClassPathEntry *
        ]
<directory>\open\src\hotspot\share\runtime/orderAccess.inline.hpp(59): error C2027: use of undefined type 'Atomic::StoreImpl<T,D,OrderAccess::PlatformOrderedStore<8,RELEASE_X>,void>'
        with
        [
            T=MethodData *,
            D=MethodData *
        ]
<directory>\open\src\hotspot\share\runtime/orderAccess.inline.hpp(59): note: see declaration of 'Atomic::StoreImpl<T,D,OrderAccess::PlatformOrderedStore<8,RELEASE_X>,void>'
        with
        [
            T=MethodData *,
            D=MethodData *
        ]
<directory>\open\src\hotspot\share\oops/method.hpp(340): note: see reference to function template instantiation 'void OrderAccess::release_store<MethodData*,MethodData*>(volatile D *,T)' being compiled
Comments
The culprit is that IsPointerConvertible is declared private within class Atomic. diff -r 11920d5d14a8 src/hotspot/share/runtime/atomic.hpp --- a/src/hotspot/share/runtime/atomic.hpp Wed Jan 31 17:43:46 2018 -0800 +++ b/src/hotspot/share/runtime/atomic.hpp Tue Feb 13 10:17:58 2018 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,6 +131,7 @@ cmpxchg_memory_order order = memory_order_conservative); private: +WINDOWS_ONLY(public:) // VS2017 warns (C2027) use of undefined type if IsPointerConvertible is declared private // Test whether From is implicitly convertible to To. // From and To must be pointer types. // Note: Provides the limited subset of C++11 std::is_convertible
13-02-2018

Interesting note, pulling the EnableIf construct from the list of template parameters into the operator() method works fine. hg diff runtime/atomic.hpp diff -r 11920d5d14a8 src/hotspot/share/runtime/atomic.hpp --- a/src/hotspot/share/runtime/atomic.hpp Wed Jan 31 17:43:46 2018 -0800 +++ b/src/hotspot/share/runtime/atomic.hpp Mon Feb 12 11:59:42 2018 -0500 @@ -433,14 +433,18 @@ // The new_value must be implicitly convertible to the // destination's type; it must be type-correct to store the // new_value in the destination. template<typename T, typename D, typename PlatformOp> struct Atomic::StoreImpl< T*, D*, - PlatformOp, - typename EnableIf<Atomic::IsPointerConvertible<T*, D*>::value>::type> + PlatformOp /*, + typename EnableIf<Atomic::IsPointerConvertible<T*, D*>::value>::type*/> VALUE_OBJ_CLASS_SPEC { void operator()(T* new_value, D* volatile* dest) const { + STATIC_ASSERT((Atomic::IsPointerConvertible<T*, D*>::value)); + typedef EnableIf<Atomic::IsPointerConvertible<T*, D*>::value>::type localType; // Allow derived to base conversion, and adding cv-qualifiers. D* value = new_value; PlatformOp()(value, dest);
12-02-2018

One example of this issue can be seen in classLoader.hpp class ClassPathEntry : public CHeapObj<mtClass> { private: ClassPathEntry* volatile _next; public: // Next entry in class path ClassPathEntry* next() const { return OrderAccess::load_acquire(&_next); } virtual ~ClassPathEntry() {} void set_next(ClassPathEntry* next) { // may have unlocked readers, so ensure visibility. OrderAccess::release_store(&_next, next); } ... } At the point OrderAccess::release_store is invoked, ClassPathEntry is not a fully defined class which seems to be causing instantiation problems of the function template. One workaround is to pull the inlined "set_next" method out of the class definition into classLoader.cpp. However, this eliminates the benefit of inlining.
06-02-2018