<div dir="ltr">I couldn't reproduce the issue on my local work tree. I have to stop the builder to reproduce.<div><br></div><div>The builder is configured;</div><div>- clang built by gcc-4.8</div><div>- Release w/o Asserts</div><div>- Just-built libc++ and libc++abi</div><div>- -fmodules</div><div><br></div><div>-fmodules might be dubious. I'll investigate in my afternoon.</div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Sep 7, 2017 at 2:32 AM Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Takumi,<div><br></div><div>This looks like a possible standard library bug. Thread 2 is blocked trying to re-lock a recursive mutex, but that should be safe. (Thread 1 is just waiting for data from Thread 2, so it's not interesting here).</div><div><br></div><div>How reproducible is this?</div><div><br></div><div>Cheers,</div><div>Lang.</div><div> </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 6, 2017 at 8:57 AM, Lang Hames <span dir="ltr"><<a href="mailto:lhames@gmail.com" target="_blank">lhames@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Takumi,<div><br></div><div>I'll look in to it now.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div><div class="m_-2684236302260965259HOEnZb"><div class="m_-2684236302260965259h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 6, 2017 at 8:11 AM, NAKAMURA Takumi <span dir="ltr"><<a href="mailto:geek4civic@gmail.com" target="_blank">geek4civic@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Lang, this hangs up to me.<div><br></div><div><a href="http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/1309" target="_blank">http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux/builds/1309</a><br></div><div>(Note, this isn't i686, but x86-64)</div><div><br></div><div>I can reproduce the issue just on this tree with Debug/Release. Do you know how I can investigate further?</div><div><br></div><div>As far as I investigated,</div><div><br></div><div><div>Thread 2 (Thread 0x7ffff6784700 (LWP 44601)):</div><div>#0 __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135</div><div>#1 0x00007ffff7bc6649 in _L_lock_909 () from /lib/x86_64-linux-gnu/libpthread.so.0</div><div>#2 0x00007ffff7bc6470 in __GI___pthread_mutex_lock (mutex=0x294c080 <llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::SerializersMutex>) at ../nptl/pthread_mutex_lock.c:79</div><div>#3 0x00000000010ba243 in __gthread_mutex_lock (__mutex=0x294c080 <llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::SerializersMutex>)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:748</div><div>#4 0x00000000010ba215 in __gthread_recursive_mutex_lock (__mutex=0x294c080 <llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::SerializersMutex>)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/bits/gthr-default.h:810</div><div>#5 0x00000000010d77d5 in std::recursive_mutex::lock (this=0x294c080 <llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::SerializersMutex>)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/mutex:175</div><div>#6 0x00000000010d74d3 in std::lock_guard<std::recursive_mutex>::lock_guard (this=0x7ffff6783888, __m=...) at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/mutex:414</div><div>#7 0x00000000010eb461 in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&) (C=...,</div><div> Err=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x31a25d>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:375</div><div>#8 0x00000000010ebabd in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serializeAsStringError (C=..., EIB=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:415</div><div>#9 0x00000000010eb9b6 in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}::operator()(llvm::ErrorInfoBase const&) const (this=0x7ffff6783af8, EIB=...) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:384</div><div>#10 0x00000000010eb91d in llvm::ErrorHandlerTraits<llvm::Error (&)(llvm::ErrorInfoBase&)>::apply<llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}>(llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}&&, std::unique_ptr<llvm::ErrorInfoBase, std::default_delete<llvm::ErrorInfoBase> >) (</div><div> H=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x31a33f>, E=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/Support/Error.h:752</div><div>#11 0x00000000010eb82b in llvm::handleErrorImpl<llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}>(std::unique_ptr<llvm::ErrorInfoBase, std::default_delete<llvm::ErrorInfoBase> >, llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}&&) (Payload=..., Handler=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x284ec1>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/Support/Error.h:844</div><div>#12 0x00000000010eb740 in llvm::handleErrors<llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}>(llvm::Error, llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&)::{lambda(llvm::ErrorInfoBase const&)#1}&&) (E=...,</div><div> Hs=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x284dec>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/Support/Error.h:873</div><div>#13 0x00000000010eb4d7 in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::serialize(llvm::orc::rpc::RawByteChannel&, llvm::Error&&) (C=...,</div><div> Err=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x31a25d>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:380</div><div>#14 0x00000000010eb41f in llvm::orc::rpc::SequenceSerialization<llvm::orc::rpc::RawByteChannel, llvm::Error>::serialize<llvm::Error>(llvm::orc::rpc::RawByteChannel&, llvm::Error&&) (C=...,</div><div> CArg=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x31a221>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:277</div><div>#15 0x00000000010eb3bf in llvm::orc::rpc::serializeSeq<llvm::orc::rpc::RawByteChannel, llvm::Error>(llvm::orc::rpc::RawByteChannel&, llvm::Error&&) (C=...,</div><div> Args=<unknown type in /home/bb/bootstrap-clang-libcxx-lld-i686-linux/builds/stagen/unittests/ExecutionEngine/Orc/OrcJITTests, CU 0x234b90, DIE 0x239991>)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:319</div><div>#16 0x00000000010eb284 in llvm::orc::rpc::detail::RespondHelper<true>::sendResult<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> (C=..., ResponseId=@0x7fffffffdcd8: 1, SeqNo=0, Err=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:426</div><div>#17 0x00000000010ea480 in llvm::orc::rpc::detail::respond<llvm::Error, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> (C=..., ResponseId=@0x7fffffffdcd8: 1, SeqNo=0, Err=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:489</div><div>#18 0x00000000010be795 in std::function<llvm::Error (llvm::orc::rpc::RawByteChannel&, unsigned int)> llvm::orc::rpc::detail::RPCEndpointBase<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::wrapHandler<llvm::orc::RemoteObjectLayerAPI::RemoveObject, llvm::orc::rpc::detail::MemberFnWrapper<llvm::orc::RemoteObjectServerLayer<(anonymous namespace)::MockObjectLayer, llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> >, llvm::Error, unsigned long> >(llvm::orc::rpc::detail::MemberFnWrapper<llvm::orc::RemoteObjectServerLayer<(anonymous namespace)::MockObjectLayer, llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> >, llvm::Error, unsigned long>)::{lambda(llvm::orc::rpc::RawByteChannel&, unsigned int)#1}::operator()(llvm::orc::rpc::RawByteChannel&, unsigned int) (this=0x2bd0960, Channel=..., SeqNo=0) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1342</div><div>#19 0x00000000010be497 in std::_Function_handler<llvm::Error (llvm::orc::rpc::RawByteChannel&, unsigned int), std::function<llvm::Error (llvm::orc::rpc::RawByteChannel&, unsigned int)> llvm::orc::rpc::detail::RPCEndpointBase<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::wrapHandler<llvm::orc::RemoteObjectLayerAPI::RemoveObject, llvm::orc::rpc::detail::MemberFnWrapper<llvm::orc::RemoteObjectServerLayer<(anonymous namespace)::MockObjectLayer, llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> >, llvm::Error, unsigned long> >(llvm::orc::rpc::detail::MemberFnWrapper<llvm::orc::RemoteObjectServerLayer<(anonymous namespace)::MockObjectLayer, llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> >, llvm::Error, unsigned long>)::{lambda(llvm::orc::rpc::RawByteChannel&, unsigned int)#1}>::_M_invoke(std::_Any_data const&, llvm::orc::rpc::RawByteChannel&, unsigned int) (__functor=..., __args=0, __args=0)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2056</div><div>#20 0x00000000010fbddd in std::function<llvm::Error (llvm::orc::rpc::RawByteChannel&, unsigned int)>::operator()(llvm::orc::rpc::RawByteChannel&, unsigned int) const (this=0x2bd09b8, __args=0, __args=0)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:2471</div><div>#21 0x00000000010f5984 in llvm::orc::rpc::detail::RPCEndpointBase<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::handleOne (this=0x7fffffffdcc8) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1140</div><div>#22 0x00000000010c9782 in (anonymous namespace)::RemoteObjectLayer_RemoveObjectFailure_Test::TestBody()::$_16::operator()() const (this=0x2b66398)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp:309</div><div>#23 0x00000000010c9715 in std::_Bind_simple<(anonymous namespace)::RemoteObjectLayer_RemoveObjectFailure_Test::TestBody()::$_16 ()>::_M_invoke<>(std::_Index_tuple<>) (this=0x2b66398)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1731</div><div>#24 0x00000000010c96e5 in std::_Bind_simple<(anonymous namespace)::RemoteObjectLayer_RemoveObjectFailure_Test::TestBody()::$_16 ()>::operator()() (this=0x2b66398)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/functional:1720</div><div>#25 0x00000000010c95a9 in std::thread::_Impl<std::_Bind_simple<(anonymous namespace)::RemoteObjectLayer_RemoveObjectFailure_Test::TestBody()::$_16 ()> >::_M_run() (this=0x2b66380)</div><div> at /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:115</div><div>#26 0x00007ffff6e15a40 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>) at ../../../../../src/libstdc++-v3/src/c++11/thread.cc:84</div><div>#27 0x00007ffff7bc4184 in start_thread (arg=0x7ffff6784700) at pthread_create.c:312</div><div>#28 0x00007ffff6882ffd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111</div><div><br></div><div>Thread 1 (Thread 0x7ffff7fe8780 (LWP 44597)):</div><div>#0 pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185</div><div>#1 0x00007ffff6e124bc in __gthread_cond_wait (__mutex=<optimized out>, __cond=<optimized out>) at /build/buildd/gcc-4.8-4.8.4/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:864</div><div>#2 std::condition_variable::wait (this=<optimized out>, __lock=...) at ../../../../../src/libstdc++-v3/src/c++11/condition_variable.cc:52</div><div>#3 0x00000000010e109d in llvm::QueueChannel::readBytes (this=0x2b5d920, Dst=0x7fffffffd718 "", Size=8) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h:90</div><div>#4 0x00000000010d8bc4 in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, unsigned long, unsigned long, void>::deserialize (C=..., V=@0x7fffffffd718: 0)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h:105</div><div>#5 0x00000000010d8b74 in llvm::orc::rpc::SequenceSerialization<llvm::orc::rpc::RawByteChannel, unsigned long>::deserialize<unsigned long> (C=..., CArg=@0x7fffffffd718: 0)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:284</div><div>#6 0x00000000010d8b44 in llvm::orc::rpc::deserializeSeq<llvm::orc::rpc::RawByteChannel, unsigned long> (C=..., Args=@0x7fffffffd718: 0)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:325</div><div>#7 0x00000000010d8a57 in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, std::string, std::string, void>::deserialize (C=..., S=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RawByteChannel.h:174</div><div>#8 0x00000000010d8a14 in llvm::orc::rpc::SequenceSerialization<llvm::orc::rpc::RawByteChannel, std::string>::deserialize<std::string> (C=..., CArg=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:284</div><div>#9 0x00000000010d88f4 in llvm::orc::rpc::deserializeSeq<llvm::orc::rpc::RawByteChannel, std::string> (C=..., Args=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:325</div><div>#10 0x00000000010f997f in llvm::orc::rpc::SerializationTraits<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::Error, void>::deserialize (C=..., Err=...)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCSerialization.h:393</div><div>#11 0x000000000110ed4d in llvm::orc::rpc::detail::ResponseHandlerImpl<llvm::orc::rpc::RawByteChannel, llvm::Error, llvm::orc::rpc::detail::ResultTraits<llvm::Error>::ErrorReturnType llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::callB<llvm::orc::RemoteObjectLayerAPI::RemoveObject, unsigned long, llvm::Error>(unsigned long const&)::{lambda(llvm::Error)#1}>::handleResponse(llvm::orc::rpc::RawByteChannel&) (</div><div> this=0x2b80950, C=...) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:808</div><div>#12 0x00000000010fbc25 in llvm::orc::rpc::detail::RPCEndpointBase<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::handleResponse (this=0x7fffffffdee0, SeqNo=0) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1262</div><div>#13 0x00000000010f5916 in llvm::orc::rpc::detail::RPCEndpointBase<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>, llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::handleOne (this=0x7fffffffdee0) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1137</div><div>#14 0x000000000110e280 in llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int>::callB<llvm::orc::RemoteObjectLayerAPI::RemoveObject, unsigned long, llvm::Error> (this=0x7fffffffdee0,</div><div> Args=@0x7fffffffda30: 1) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1588</div><div>#15 0x000000000110d0aa in llvm::orc::RemoteObjectClientLayer<llvm::orc::rpc::SingleThreadedRPCEndpoint<llvm::orc::rpc::RawByteChannel, unsigned int, unsigned int> >::removeObject (this=0x7fffffffde38, H=1)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h:317</div><div>#16 0x00000000010c7bda in (anonymous namespace)::RemoteObjectLayer_RemoveObjectFailure_Test::TestBody (this=0x2b519c0)</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp:315</div><div>#17 0x00000000019e58ce in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void> (object=0x2b519c0, method=&virtual testing::Test::TestBody(), location=0x3e1861 "the test body")</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2402</div><div>#18 0x00000000019d7012 in testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void> (object=0x2b519c0, method=&virtual testing::Test::TestBody(), location=0x3e1861 "the test body")</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2455</div><div>#19 0x00000000019c53e6 in testing::Test::Run (this=0x2b519c0) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2474</div><div>#20 0x00000000019c5c2d in testing::TestInfo::Run (this=0x2b33550) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2656</div><div>#21 0x00000000019c617c in testing::TestCase::Run (this=0x2b32f00) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2774</div><div>#22 0x00000000019cb6b1 in testing::internal::UnitTestImpl::RunAllTests (this=0x2b31210) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:4649</div><div>#23 0x00000000019e7f0e in testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x2b31210,</div><div> method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x19cb3d0 <testing::internal::UnitTestImpl::RunAllTests()>, location=0x3e1fdc "auxiliary test code (environments or event listeners)")</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2402</div><div>#24 0x00000000019d8a22 in testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (object=0x2b31210,</div><div> method=(bool (testing::internal::UnitTestImpl::*)(testing::internal::UnitTestImpl * const)) 0x19cb3d0 <testing::internal::UnitTestImpl::RunAllTests()>, location=0x3e1fdc "auxiliary test code (environments or event listeners)")</div><div> at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:2455</div><div>#25 0x00000000019cb3a2 in testing::UnitTest::Run (this=0x2b1be30 <testing::UnitTest::GetInstance()::instance>) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:4257</div><div>#26 0x00000000019bdcb1 in RUN_ALL_TESTS () at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h:2233</div><div>#27 0x00000000019bdc41 in main (argc=1, argv=0x7fffffffe618) at /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/UnitTestMain/TestMain.cpp:51</div></div><div><br></div><div><br></div></div><div class="m_-2684236302260965259m_-3452541299801939580HOEnZb"><div class="m_-2684236302260965259m_-3452541299801939580h5"><br><div class="gmail_quote"><div dir="ltr">On Tue, Sep 5, 2017 at 12:35 PM Lang Hames via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Mon Sep 4 20:34:09 2017<br>
New Revision: 312511<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=312511&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=312511&view=rev</a><br>
Log:<br>
[ORC] Add a pair of ORC layers that forward object-layer operations via RPC.<br>
<br>
This patch introduces RemoteObjectClientLayer and RemoteObjectServerLayer,<br>
which can be used to forward ORC object-layer operations from a JIT stack in<br>
the client to a JIT stack (consisting only of object-layers) in the server.<br>
<br>
This is a new way to support remote-JITing in LLVM. The previous approach<br>
(supported by OrcRemoteTargetClient and OrcRemoteTargetServer) used a<br>
remote-mapping memory manager that sat "beneath" the JIT stack and sent<br>
fully-relocated binary blobs to the server. The main advantage of the new<br>
approach is that relocatable objects can be cached on the server and re-used<br>
(if the code that they represent hasn't changed), whereas fully-relocated blobs<br>
can not (since the addresses they have been permanently bound to will change<br>
from run to run).<br>
<br>
<br>
Added:<br>
llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h<br>
llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp<br>
Modified:<br>
llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h<br>
llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h<br>
llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h<br>
llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp<br>
llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h?rev=312511&r1=312510&r2=312511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h?rev=312511&r1=312510&r2=312511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/JITSymbol.h Mon Sep 4 20:34:09 2017<br>
@@ -89,9 +89,15 @@ public:<br>
/// @brief Implicitly convert to the underlying flags type.<br>
operator UnderlyingType&() { return Flags; }<br>
<br>
+ /// @brief Implicitly convert to the underlying flags type.<br>
+ operator const UnderlyingType&() const { return Flags; }<br>
+<br>
/// @brief Return a reference to the target-specific flags.<br>
TargetFlagsType& getTargetFlags() { return TargetFlags; }<br>
<br>
+ /// @brief Return a reference to the target-specific flags.<br>
+ const TargetFlagsType& getTargetFlags() const { return TargetFlags; }<br>
+<br>
/// Construct a JITSymbolFlags value based on the flags of the given global<br>
/// value.<br>
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV);<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h?rev=312511&r1=312510&r2=312511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h?rev=312511&r1=312510&r2=312511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcError.h Mon Sep 4 20:34:09 2017<br>
@@ -33,7 +33,8 @@ enum class OrcErrorCode : int {<br>
RPCResponseAbandoned,<br>
UnexpectedRPCCall,<br>
UnexpectedRPCResponse,<br>
- UnknownErrorCodeFromRemote<br>
+ UnknownErrorCodeFromRemote,<br>
+ UnknownResourceHandle<br>
};<br>
<br>
std::error_code orcError(OrcErrorCode ErrCode);<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h?rev=312511&r1=312510&r2=312511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h?rev=312511&r1=312510&r2=312511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h Mon Sep 4 20:34:09 2017<br>
@@ -25,6 +25,37 @@ namespace orc {<br>
<br>
namespace remote {<br>
<br>
+/// Template error for missing resources.<br>
+template <typename ResourceIdT><br>
+class ResourceNotFound<br>
+ : public ErrorInfo<ResourceNotFound<ResourceIdT>> {<br>
+public:<br>
+ static char ID;<br>
+<br>
+ ResourceNotFound(ResourceIdT ResourceId,<br>
+ std::string ResourceDescription = "")<br>
+ : ResourceId(std::move(ResourceId)),<br>
+ ResourceDescription(std::move(ResourceDescription)) {}<br>
+<br>
+ std::error_code convertToErrorCode() const override {<br>
+ return orcError(OrcErrorCode::UnknownResourceHandle);<br>
+ }<br>
+<br>
+ void log(raw_ostream &OS) const override {<br>
+ OS << (ResourceDescription.empty()<br>
+ ? "Remote resource with id "<br>
+ : ResourceDescription)<br>
+ << " " << ResourceId << " not found";<br>
+ }<br>
+<br>
+private:<br>
+ ResourceIdT ResourceId;<br>
+ std::string ResourceDescription;<br>
+};<br>
+<br>
+template <typename ResourceIdT><br>
+char ResourceNotFound<ResourceIdT>::ID = 0;<br>
+<br>
class DirectBufferWriter {<br>
public:<br>
DirectBufferWriter() = default;<br>
@@ -45,6 +76,32 @@ private:<br>
<br>
namespace rpc {<br>
<br>
+template <><br>
+class RPCTypeName<JITSymbolFlags> {<br>
+public:<br>
+ static const char *getName() { return "JITSymbolFlags"; }<br>
+};<br>
+<br>
+template <typename ChannelT><br>
+class SerializationTraits<ChannelT, JITSymbolFlags> {<br>
+public:<br>
+<br>
+ static Error serialize(ChannelT &C, const JITSymbolFlags &Flags) {<br>
+ return serializeSeq(C, static_cast<JITSymbolFlags::UnderlyingType>(Flags),<br>
+ Flags.getTargetFlags());<br>
+ }<br>
+<br>
+ static Error deserialize(ChannelT &C, JITSymbolFlags &Flags) {<br>
+ JITSymbolFlags::UnderlyingType JITFlags;<br>
+ JITSymbolFlags::TargetFlagsType TargetFlags;<br>
+ if (auto Err = deserializeSeq(C, JITFlags, TargetFlags))<br>
+ return Err;<br>
+ Flags = JITSymbolFlags(static_cast<JITSymbolFlags::FlagNames>(JITFlags),<br>
+ TargetFlags);<br>
+ return Error::success();<br>
+ }<br>
+};<br>
+<br>
template <> class RPCTypeName<remote::DirectBufferWriter> {<br>
public:<br>
static const char *getName() { return "DirectBufferWriter"; }<br>
<br>
Added: llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h?rev=312511&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h?rev=312511&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h (added)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h Mon Sep 4 20:34:09 2017<br>
@@ -0,0 +1,498 @@<br>
+//===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- C++ -*-===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// Forwards objects to a remote object layer via RPC.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H<br>
+#define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H<br>
+<br>
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"<br>
+#include "llvm/Object/ObjectFile.h"<br>
+#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"<br>
+#include <map><br>
+<br>
+namespace llvm {<br>
+namespace orc {<br>
+<br>
+/// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer.<br>
+class RemoteObjectLayerAPI {<br>
+public:<br>
+<br>
+ using ObjHandleT = remote::ResourceIdMgr::ResourceId;<br>
+<br>
+protected:<br>
+<br>
+ using RemoteSymbolId = remote::ResourceIdMgr::ResourceId;<br>
+ using RemoteSymbol = std::pair<RemoteSymbolId, JITSymbolFlags>;<br>
+<br>
+public:<br>
+<br>
+ using BadSymbolHandleError = remote::ResourceNotFound<RemoteSymbolId>;<br>
+ using BadObjectHandleError = remote::ResourceNotFound<ObjHandleT>;<br>
+<br>
+protected:<br>
+<br>
+ static const ObjHandleT InvalidObjectHandleId = 0;<br>
+ static const RemoteSymbolId NullSymbolId = 0;<br>
+<br>
+ class AddObject<br>
+ : public rpc::Function<AddObject, Expected<ObjHandleT>(std::string)> {<br>
+ public:<br>
+ static const char *getName() { return "AddObject"; }<br>
+ };<br>
+<br>
+ class RemoveObject<br>
+ : public rpc::Function<RemoveObject, Error(ObjHandleT)> {<br>
+ public:<br>
+ static const char *getName() { return "RemoveObject"; }<br>
+ };<br>
+<br>
+ class FindSymbol<br>
+ : public rpc::Function<FindSymbol, Expected<RemoteSymbol>(std::string,<br>
+ bool)> {<br>
+ public:<br>
+ static const char *getName() { return "FindSymbol"; }<br>
+ };<br>
+<br>
+ class FindSymbolIn<br>
+ : public rpc::Function<FindSymbolIn,<br>
+ Expected<RemoteSymbol>(ObjHandleT, std::string,<br>
+ bool)> {<br>
+ public:<br>
+ static const char *getName() { return "FindSymbolIn"; }<br>
+ };<br>
+<br>
+ class EmitAndFinalize<br>
+ : public rpc::Function<EmitAndFinalize,<br>
+ Error(ObjHandleT)> {<br>
+ public:<br>
+ static const char *getName() { return "EmitAndFinalize"; }<br>
+ };<br>
+<br>
+ class Lookup<br>
+ : public rpc::Function<Lookup,<br>
+ Expected<RemoteSymbol>(ObjHandleT, std::string)> {<br>
+ public:<br>
+ static const char *getName() { return "Lookup"; }<br>
+ };<br>
+<br>
+ class LookupInLogicalDylib<br>
+ : public rpc::Function<LookupInLogicalDylib,<br>
+ Expected<RemoteSymbol>(ObjHandleT, std::string)> {<br>
+ public:<br>
+ static const char *getName() { return "LookupInLogicalDylib"; }<br>
+ };<br>
+<br>
+ class ReleaseRemoteSymbol<br>
+ : public rpc::Function<ReleaseRemoteSymbol, Error(RemoteSymbolId)> {<br>
+ public:<br>
+ static const char *getName() { return "ReleaseRemoteSymbol"; }<br>
+ };<br>
+<br>
+ class MaterializeRemoteSymbol<br>
+ : public rpc::Function<MaterializeRemoteSymbol,<br>
+ Expected<JITTargetAddress>(RemoteSymbolId)> {<br>
+ public:<br>
+ static const char *getName() { return "MaterializeRemoteSymbol"; }<br>
+ };<br>
+};<br>
+<br>
+/// Base class containing common utilities for RemoteObjectClientLayer and<br>
+/// RemoteObjectServerLayer.<br>
+template <typename RPCEndpoint><br>
+class RemoteObjectLayer : public RemoteObjectLayerAPI {<br>
+public:<br>
+<br>
+ RemoteObjectLayer(RPCEndpoint &Remote,<br>
+ std::function<void(Error)> ReportError)<br>
+ : Remote(Remote), ReportError(std::move(ReportError)),<br>
+ SymbolIdMgr(NullSymbolId + 1) {<br>
+ using ThisT = RemoteObjectLayer<RPCEndpoint>;<br>
+ Remote.template addHandler<ReleaseRemoteSymbol>(<br>
+ *this, &ThisT::handleReleaseRemoteSymbol);<br>
+ Remote.template addHandler<MaterializeRemoteSymbol>(<br>
+ *this, &ThisT::handleMaterializeRemoteSymbol);<br>
+ }<br>
+<br>
+protected:<br>
+<br>
+ class RemoteSymbolMaterializer {<br>
+ public:<br>
+<br>
+ RemoteSymbolMaterializer(RemoteObjectLayer &C,<br>
+ RemoteSymbolId Id)<br>
+ : C(C), Id(Id) {}<br>
+<br>
+ RemoteSymbolMaterializer(const RemoteSymbolMaterializer &Other)<br>
+ : C(Other.C), Id(Other.Id) {<br>
+ // FIXME: This is a horrible, auto_ptr-style, copy-as-move operation.<br>
+ // It should be removed as soon as LLVM has C++14's generalized<br>
+ // lambda capture (at which point the materializer can be moved<br>
+ // into the lambda in remoteToJITSymbol below).<br>
+ const_cast<RemoteSymbolMaterializer&>(Other).Id = 0;<br>
+ }<br>
+<br>
+ RemoteSymbolMaterializer&<br>
+ operator=(const RemoteSymbolMaterializer&) = delete;<br>
+<br>
+ ~RemoteSymbolMaterializer() {<br>
+ if (Id)<br>
+ C.releaseRemoteSymbol(Id);<br>
+ }<br>
+<br>
+ Expected<JITTargetAddress> materialize() {<br>
+ auto Addr = C.materializeRemoteSymbol(Id);<br>
+ Id = 0;<br>
+ return Addr;<br>
+ }<br>
+<br>
+ private:<br>
+ RemoteObjectLayer &C;<br>
+ RemoteSymbolId Id;<br>
+ };<br>
+<br>
+ RemoteSymbol nullRemoteSymbol() {<br>
+ return RemoteSymbol(0, JITSymbolFlags());<br>
+ }<br>
+<br>
+ // Creates a StringError that contains a copy of Err's log message, then<br>
+ // sends that StringError to ReportError.<br>
+ //<br>
+ // This allows us to locally log error messages for errors that will actually<br>
+ // be delivered to the remote.<br>
+ Error teeLog(Error Err) {<br>
+ return handleErrors(std::move(Err),<br>
+ [this](std::unique_ptr<ErrorInfoBase> EIB) {<br>
+ ReportError(make_error<StringError>(<br>
+ EIB->message(),<br>
+ EIB->convertToErrorCode()));<br>
+ return Error(std::move(EIB));<br>
+ });<br>
+ }<br>
+<br>
+ Error badRemoteSymbolIdError(RemoteSymbolId Id) {<br>
+ return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");<br>
+ }<br>
+<br>
+ Error badObjectHandleError(ObjHandleT H) {<br>
+ return make_error<RemoteObjectLayerAPI::BadObjectHandleError>(<br>
+ H, "Bad object handle");<br>
+ }<br>
+<br>
+ Expected<RemoteSymbol> jitSymbolToRemote(JITSymbol Sym) {<br>
+ if (Sym) {<br>
+ auto Id = SymbolIdMgr.getNext();<br>
+ auto Flags = Sym.getFlags();<br>
+ assert(!InUseSymbols.count(Id) && "Symbol id already in use");<br>
+ InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));<br>
+ return RemoteSymbol(Id, Flags);<br>
+ } else if (auto Err = Sym.takeError())<br>
+ return teeLog(std::move(Err));<br>
+ // else...<br>
+ return nullRemoteSymbol();<br>
+ }<br>
+<br>
+ JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {<br>
+ if (RemoteSymOrErr) {<br>
+ auto &RemoteSym = *RemoteSymOrErr;<br>
+ RemoteSymbolMaterializer RSM(*this, RemoteSym.first);<br>
+ auto Sym =<br>
+ JITSymbol([RSM]() mutable { return RSM.materialize(); },<br>
+ RemoteSym.second);<br>
+ return Sym;<br>
+ } else<br>
+ return RemoteSymOrErr.takeError();<br>
+ }<br>
+<br>
+ template <typename Func, typename... ArgTs><br>
+ using CallBResult = decltype(foldRemoteERror(<br>
+ std::declval<RPCEndpoint>()<br>
+ .template callB<Func>(<br>
+ std::declval<const ArgTs&>()...)));<br>
+<br>
+ /// API checked callB function.<br>
+ template <typename Func, typename... ArgTs><br>
+ CallBResult<Func> callB(const ArgTs &... Args) {<br>
+ return foldRemoteError(Remote.template callB<Func>(Args...));<br>
+ }<br>
+<br>
+ RPCEndpoint &Remote;<br>
+ std::function<void(Error)> ReportError;<br>
+<br>
+private:<br>
+<br>
+ void releaseRemoteSymbol(RemoteSymbolId Id) {<br>
+ if (auto Err = Remote.template callB<ReleaseRemoteSymbol>(Id))<br>
+ ReportError(std::move(Err));<br>
+ }<br>
+<br>
+ Expected<JITTargetAddress> materializeRemoteSymbol(RemoteSymbolId Id) {<br>
+ return Remote.template callB<MaterializeRemoteSymbol>(Id);<br>
+ }<br>
+<br>
+ Error handleReleaseRemoteSymbol(RemoteSymbolId Id) {<br>
+ auto SI = InUseSymbols.find(Id);<br>
+ if (SI != InUseSymbols.end()) {<br>
+ InUseSymbols.erase(SI);<br>
+ return Error::success();<br>
+ } else<br>
+ return teeLog(badRemoteSymbolIdError(Id));<br>
+ }<br>
+<br>
+ Expected<JITTargetAddress> handleMaterializeRemoteSymbol(RemoteSymbolId Id) {<br>
+ auto SI = InUseSymbols.find(Id);<br>
+ if (SI != InUseSymbols.end()) {<br>
+ auto AddrOrErr = SI->second.getAddress();<br>
+ InUseSymbols.erase(SI);<br>
+ SymbolIdMgr.release(Id);<br>
+ if (AddrOrErr)<br>
+ return *AddrOrErr;<br>
+ else<br>
+ return teeLog(AddrOrErr.takeError());<br>
+ } else {<br>
+ return teeLog(badRemoteSymbolIdError(Id));<br>
+ }<br>
+ }<br>
+<br>
+ remote::ResourceIdMgr SymbolIdMgr;<br>
+ std::map<RemoteSymbolId, JITSymbol> InUseSymbols;<br>
+};<br>
+<br>
+template <typename RPCEndpoint><br>
+class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {<br>
+private:<br>
+<br>
+ using AddObject = RemoteObjectLayerAPI::AddObject;<br>
+ using RemoveObject = RemoteObjectLayerAPI::RemoveObject;<br>
+ using FindSymbol = RemoteObjectLayerAPI::FindSymbol;<br>
+ using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;<br>
+ using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;<br>
+ using Lookup = RemoteObjectLayerAPI::Lookup;<br>
+ using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;<br>
+<br>
+ using RemoteObjectLayer<RPCEndpoint>::teeLog;<br>
+ using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;<br>
+ using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;<br>
+<br>
+public:<br>
+<br>
+ using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;<br>
+ using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;<br>
+<br>
+ using ObjectPtr =<br>
+ std::shared_ptr<object::OwningBinary<object::ObjectFile>>;<br>
+<br>
+ RemoteObjectClientLayer(RPCEndpoint &Remote,<br>
+ std::function<void(Error)> ReportError)<br>
+ : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {<br>
+ using ThisT = RemoteObjectClientLayer<RPCEndpoint>;<br>
+ Remote.template addHandler<Lookup>(*this, &ThisT::lookup);<br>
+ Remote.template addHandler<LookupInLogicalDylib>(<br>
+ *this, &ThisT::lookupInLogicalDylib);<br>
+ }<br>
+<br>
+ Expected<ObjHandleT><br>
+ addObject(ObjectPtr Object, std::shared_ptr<JITSymbolResolver> Resolver) {<br>
+ StringRef ObjBuffer = Object->getBinary()->getData();<br>
+ if (auto HandleOrErr =<br>
+ this->Remote.template callB<AddObject>(ObjBuffer)) {<br>
+ auto &Handle = *HandleOrErr;<br>
+ // FIXME: Return an error for this:<br>
+ assert(!Resolvers.count(Handle) && "Handle already in use?");<br>
+ Resolvers[Handle] = std::move(Resolver);<br>
+ return Handle;<br>
+ } else<br>
+ return HandleOrErr.takeError();<br>
+ }<br>
+<br>
+ Error removeObject(ObjHandleT H) {<br>
+ return this->Remote.template callB<RemoveObject>(H);<br>
+ }<br>
+<br>
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {<br>
+ return remoteToJITSymbol(<br>
+ this->Remote.template callB<FindSymbol>(Name,<br>
+ ExportedSymbolsOnly));<br>
+ }<br>
+<br>
+ JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {<br>
+ return remoteToJITSymbol(<br>
+ this->Remote.template callB<FindSymbolIn>(H, Name,<br>
+ ExportedSymbolsOnly));<br>
+ }<br>
+<br>
+ Error emitAndFinalize(ObjHandleT H) {<br>
+ return this->Remote.template callB<EmitAndFinalize>(H);<br>
+ }<br>
+<br>
+private:<br>
+<br>
+ Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {<br>
+ auto RI = Resolvers.find(H);<br>
+ if (RI != Resolvers.end()) {<br>
+ return this->jitSymbolToRemote(RI->second->findSymbol(Name));<br>
+ } else<br>
+ return teeLog(badObjectHandleError(H));<br>
+ }<br>
+<br>
+ Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,<br>
+ const std::string &Name) {<br>
+ auto RI = Resolvers.find(H);<br>
+ if (RI != Resolvers.end())<br>
+ return this->jitSymbolToRemote(<br>
+ RI->second->findSymbolInLogicalDylib(Name));<br>
+ else<br>
+ return teeLog(badObjectHandleError(H));<br>
+ }<br>
+<br>
+ std::map<remote::ResourceIdMgr::ResourceId,<br>
+ std::shared_ptr<JITSymbolResolver>> Resolvers;<br>
+};<br>
+<br>
+template <typename BaseLayerT, typename RPCEndpoint><br>
+class RemoteObjectServerLayer : public RemoteObjectLayer<RPCEndpoint> {<br>
+private:<br>
+<br>
+ using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;<br>
+ using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;<br>
+<br>
+ using AddObject = RemoteObjectLayerAPI::AddObject;<br>
+ using RemoveObject = RemoteObjectLayerAPI::RemoveObject;<br>
+ using FindSymbol = RemoteObjectLayerAPI::FindSymbol;<br>
+ using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;<br>
+ using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;<br>
+ using Lookup = RemoteObjectLayerAPI::Lookup;<br>
+ using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;<br>
+<br>
+ using RemoteObjectLayer<RPCEndpoint>::teeLog;<br>
+ using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;<br>
+ using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;<br>
+<br>
+public:<br>
+<br>
+ RemoteObjectServerLayer(BaseLayerT &BaseLayer,<br>
+ RPCEndpoint &Remote,<br>
+ std::function<void(Error)> ReportError)<br>
+ : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),<br>
+ BaseLayer(BaseLayer), HandleIdMgr(1) {<br>
+ using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;<br>
+<br>
+ Remote.template addHandler<AddObject>(*this, &ThisT::addObject);<br>
+ Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);<br>
+ Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);<br>
+ Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);<br>
+ Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);<br>
+ }<br>
+<br>
+private:<br>
+<br>
+ class StringMemoryBuffer : public MemoryBuffer {<br>
+ public:<br>
+ StringMemoryBuffer(std::string Buffer)<br>
+ : Buffer(std::move(Buffer)) {<br>
+ init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(),<br>
+ false);<br>
+ }<br>
+<br>
+ BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }<br>
+ private:<br>
+ std::string Buffer;<br>
+ };<br>
+<br>
+ JITSymbol lookup(ObjHandleT Id, const std::string &Name) {<br>
+ return remoteToJITSymbol(<br>
+ this->Remote.template callB<Lookup>(Id, Name));<br>
+ }<br>
+<br>
+ JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) {<br>
+ return remoteToJITSymbol(<br>
+ this->Remote.template callB<LookupInLogicalDylib>(Id, Name));<br>
+ }<br>
+<br>
+ Expected<ObjHandleT> addObject(std::string ObjBuffer) {<br>
+ auto Buffer = llvm::make_unique<StringMemoryBuffer>(std::move(ObjBuffer));<br>
+ if (auto ObjectOrErr =<br>
+ object::ObjectFile::createObjectFile(Buffer->getMemBufferRef())) {<br>
+ auto Object =<br>
+ std::make_shared<object::OwningBinary<object::ObjectFile>>(<br>
+ std::move(*ObjectOrErr), std::move(Buffer));<br>
+<br>
+ auto Id = HandleIdMgr.getNext();<br>
+ assert(!BaseLayerHandles.count(Id) && "Id already in use?");<br>
+<br>
+ auto Resolver =<br>
+ createLambdaResolver(<br>
+ [this, Id](const std::string &Name) { return lookup(Id, Name); },<br>
+ [this, Id](const std::string &Name) {<br>
+ return lookupInLogicalDylib(Id, Name);<br>
+ });<br>
+<br>
+ if (auto HandleOrErr =<br>
+ BaseLayer.addObject(std::move(Object), std::move(Resolver))) {<br>
+ BaseLayerHandles[Id] = std::move(*HandleOrErr);<br>
+ return Id;<br>
+ } else<br>
+ return teeLog(HandleOrErr.takeError());<br>
+ } else<br>
+ return teeLog(ObjectOrErr.takeError());<br>
+ }<br>
+<br>
+ Error removeObject(ObjHandleT H) {<br>
+ auto HI = BaseLayerHandles.find(H);<br>
+ if (HI != BaseLayerHandles.end()) {<br>
+ if (auto Err = BaseLayer.removeObject(HI->second))<br>
+ return teeLog(std::move(Err));<br>
+ return Error::success();<br>
+ } else<br>
+ return teeLog(badObjectHandleError(H));<br>
+ }<br>
+<br>
+ Expected<RemoteSymbol> findSymbol(const std::string &Name,<br>
+ bool ExportedSymbolsOnly) {<br>
+ if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))<br>
+ return this->jitSymbolToRemote(std::move(Sym));<br>
+ else if (auto Err = Sym.takeError())<br>
+ return teeLog(std::move(Err));<br>
+ return this->nullRemoteSymbol();<br>
+ }<br>
+<br>
+ Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,<br>
+ bool ExportedSymbolsOnly) {<br>
+ auto HI = BaseLayerHandles.find(H);<br>
+ if (HI != BaseLayerHandles.end()) {<br>
+ if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))<br>
+ return this->jitSymbolToRemote(std::move(Sym));<br>
+ else if (auto Err = Sym.takeError())<br>
+ return teeLog(std::move(Err));<br>
+ return this->nullRemoteSymbol();<br>
+ } else<br>
+ return teeLog(badObjectHandleError(H));<br>
+ }<br>
+<br>
+ Error emitAndFinalize(ObjHandleT H) {<br>
+ auto HI = BaseLayerHandles.find(H);<br>
+ if (HI != BaseLayerHandles.end()) {<br>
+ if (auto Err = BaseLayer.emitAndFinalize(HI->second))<br>
+ return teeLog(std::move(Err));<br>
+ return Error::success();<br>
+ } else<br>
+ return teeLog(badObjectHandleError(H));<br>
+ }<br>
+<br>
+ BaseLayerT &BaseLayer;<br>
+ remote::ResourceIdMgr HandleIdMgr;<br>
+ std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;<br>
+};<br>
+<br>
+} // end namespace orc<br>
+} // end namespace llvm<br>
+<br>
+#endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp?rev=312511&r1=312510&r2=312511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp?rev=312511&r1=312510&r2=312511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcError.cpp Mon Sep 4 20:34:09 2017<br>
@@ -54,6 +54,8 @@ public:<br>
case OrcErrorCode::UnknownErrorCodeFromRemote:<br>
return "Unknown error returned from remote RPC function "<br>
"(Use StringError to get error message)";<br>
+ case OrcErrorCode::UnknownResourceHandle:<br>
+ return "Unknown resource handle";<br>
}<br>
llvm_unreachable("Unhandled error code");<br>
}<br>
<br>
Modified: llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=312511&r1=312510&r2=312511&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt?rev=312511&r1=312510&r2=312511&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/CMakeLists.txt Mon Sep 4 20:34:09 2017<br>
@@ -18,6 +18,7 @@ add_llvm_unittest(OrcJITTests<br>
OrcCAPITest.cpp<br>
OrcTestCommon.cpp<br>
QueueChannel.cpp<br>
+ RemoteObjectLayerTest.cpp<br>
RPCUtilsTest.cpp<br>
RTDyldObjectLinkingLayerTest.cpp<br>
)<br>
<br>
Added: llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp?rev=312511&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp?rev=312511&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp (added)<br>
+++ llvm/trunk/unittests/ExecutionEngine/Orc/RemoteObjectLayerTest.cpp Mon Sep 4 20:34:09 2017<br>
@@ -0,0 +1,576 @@<br>
+//===---------------------- RemoteObjectLayerTest.cpp ---------------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ExecutionEngine/Orc/CompileUtils.h"<br>
+#include "llvm/ExecutionEngine/Orc/NullResolver.h"<br>
+#include "llvm/ExecutionEngine/Orc/RemoteObjectLayer.h"<br>
+#include "OrcTestCommon.h"<br>
+#include "QueueChannel.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace llvm;<br>
+using namespace llvm::orc;<br>
+<br>
+namespace {<br>
+<br>
+class MockObjectLayer {<br>
+public:<br>
+<br>
+ using ObjHandleT = uint64_t;<br>
+<br>
+ using ObjectPtr =<br>
+ std::shared_ptr<object::OwningBinary<object::ObjectFile>>;<br>
+<br>
+ using LookupFn = std::function<JITSymbol(StringRef, bool)>;<br>
+ using SymbolLookupTable = std::map<ObjHandleT, LookupFn>;<br>
+<br>
+ using AddObjectFtor =<br>
+ std::function<Expected<ObjHandleT>(ObjectPtr, SymbolLookupTable&)>;<br>
+<br>
+ class ObjectNotFound : public remote::ResourceNotFound<ObjHandleT> {<br>
+ public:<br>
+ ObjectNotFound(ObjHandleT H) : ResourceNotFound(H, "Object handle") {}<br>
+ };<br>
+<br>
+ MockObjectLayer(AddObjectFtor AddObject)<br>
+ : AddObject(std::move(AddObject)) {}<br>
+<br>
+ Expected<ObjHandleT> addObject(ObjectPtr Obj,<br>
+ std::shared_ptr<JITSymbolResolver> Resolver) {<br>
+ return AddObject(Obj, SymTab);<br>
+ }<br>
+<br>
+ Error removeObject(ObjHandleT H) {<br>
+ if (SymTab.count(H))<br>
+ return Error::success();<br>
+ else<br>
+ return make_error<ObjectNotFound>(H);<br>
+ }<br>
+<br>
+ JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {<br>
+ for (auto KV : SymTab) {<br>
+ if (auto Sym = KV.second(Name, ExportedSymbolsOnly))<br>
+ return Sym;<br>
+ else if (auto Err = Sym.takeError())<br>
+ return std::move(Err);<br>
+ }<br>
+ return JITSymbol(nullptr);<br>
+ }<br>
+<br>
+ JITSymbol findSymbolIn(ObjHandleT H, StringRef Name,<br>
+ bool ExportedSymbolsOnly) {<br>
+ auto LI = SymTab.find(H);<br>
+ if (LI != SymTab.end())<br>
+ return LI->second(Name, ExportedSymbolsOnly);<br>
+ else<br>
+ return make_error<ObjectNotFound>(H);<br>
+ }<br>
+<br>
+ Error emitAndFinalize(ObjHandleT H) {<br>
+ if (SymTab.count(H))<br>
+ return Error::success();<br>
+ else<br>
+ return make_error<ObjectNotFound>(H);<br>
+ }<br>
+<br>
+private:<br>
+ AddObjectFtor AddObject;<br>
+ SymbolLookupTable SymTab;<br>
+};<br>
+<br>
+using RPCEndpoint = rpc::SingleThreadedRPCEndpoint<rpc::RawByteChannel>;<br>
+<br>
+MockObjectLayer::ObjectPtr createTestObject() {<br>
+ OrcNativeTarget::initialize();<br>
+ auto TM = std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget());<br>
+<br>
+ if (!TM)<br>
+ return nullptr;<br>
+<br>
+ LLVMContext Ctx;<br>
+ ModuleBuilder MB(Ctx, TM->getTargetTriple().str(), "TestModule");<br>
+ MB.getModule()->setDataLayout(TM->createDataLayout());<br>
+ auto *Main = MB.createFunctionDecl<void(int, char**)>("main");<br>
+ Main->getBasicBlockList().push_back(BasicBlock::Create(Ctx));<br>
+ IRBuilder<> B(&Main->back());<br>
+ B.CreateRet(ConstantInt::getSigned(Type::getInt32Ty(Ctx), 42));<br>
+<br>
+ SimpleCompiler IRCompiler(*TM);<br>
+ return std::make_shared<object::OwningBinary<object::ObjectFile>>(<br>
+ IRCompiler(*MB.getModule()));<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, AddObject) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ logAllUnhandledErrors(std::move(Err), llvm::errs(), "");<br>
+ };<br>
+<br>
+ // Copy the bytes out of the test object: the copy will be used to verify<br>
+ // that the original is correctly transmitted over RPC to the mock layer.<br>
+ StringRef ObjBytes = TestObject->getBinary()->getData();<br>
+ std::vector<char> ObjContents(ObjBytes.size());<br>
+ std::copy(ObjBytes.begin(), ObjBytes.end(), ObjContents.begin());<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+ MockObjectLayer BaseLayer(<br>
+ [&ObjContents](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+<br>
+ // Check that the received object file content matches the original.<br>
+ StringRef RPCObjContents = Obj->getBinary()->getData();<br>
+ EXPECT_EQ(RPCObjContents.size(), ObjContents.size())<br>
+ << "RPC'd object file has incorrect size";<br>
+ EXPECT_TRUE(std::equal(RPCObjContents.begin(), RPCObjContents.end(),<br>
+ ObjContents.begin()))<br>
+ << "RPC'd object file content does not match original content";<br>
+<br>
+ return 1;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, AddObjectFailure) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")<br>
+ << "Expected error string to be \"AddObjectFailure - Test Message\"";<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab)<br>
+ -> Expected<MockObjectLayer::ObjHandleT> {<br>
+ return make_error<StringError>("AddObjectFailure - Test Message",<br>
+ inconvertibleErrorCode());<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto HandleOrErr =<br>
+ Client.addObject(std::move(TestObject), std::make_shared<NullResolver>());<br>
+<br>
+ EXPECT_FALSE(HandleOrErr) << "Expected error from addObject";<br>
+<br>
+ auto ErrMsg = toString(HandleOrErr.takeError());<br>
+ EXPECT_EQ(ErrMsg, "AddObjectFailure - Test Message")<br>
+ << "Expected error string to be \"AddObjectFailure - Test Message\"";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+<br>
+TEST(RemoteObjectLayer, RemoveObject) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ logAllUnhandledErrors(std::move(Err), llvm::errs(), "");<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ SymTab[1] = MockObjectLayer::LookupFn();<br>
+ return 1;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto H = cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ cantFail(Client.removeObject(H));<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, RemoveObjectFailure) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Object handle 42 not found")<br>
+ << "Expected error string to be \"Object handle 42 not found\"";<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ // AddObject lambda does not update symbol table, so removeObject will treat<br>
+ // this as a bad object handle.<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ return 42;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto H = cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ auto Err = Client.removeObject(H);<br>
+ EXPECT_TRUE(!!Err) << "Expected error from removeObject";<br>
+<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Object handle 42 not found")<br>
+ << "Expected error string to be \"Object handle 42 not found\"";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, FindSymbol) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")<br>
+ << "Expected error string to be \"Object handle 42 not found\"";<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ // AddObject lambda does not update symbol table, so removeObject will treat<br>
+ // this as a bad object handle.<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ SymTab[42] =<br>
+ [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {<br>
+ if (Name == "foobar")<br>
+ return JITSymbol(0x12348765, JITSymbolFlags::Exported);<br>
+ return make_error<JITSymbolNotFound>(Name);<br>
+ };<br>
+ return 42;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ auto Sym1 = Client.findSymbol("foobar", true);<br>
+<br>
+ EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";<br>
+ EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)<br>
+ << "Symbol 'foobar' does not return the correct address";<br>
+<br>
+ auto Sym2 = Client.findSymbol("barbaz", true);<br>
+ EXPECT_FALSE(!!Sym2) << "Symbol 'barbaz' should not be findable";<br>
+ auto Err = Sym2.takeError();<br>
+ EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")<br>
+ << "Expected symbol-not-found error for Sym2";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, FindSymbolIn) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")<br>
+ << "Expected error string to be \"Object handle 42 not found\"";<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ // AddObject lambda does not update symbol table, so removeObject will treat<br>
+ // this as a bad object handle.<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ SymTab[42] =<br>
+ [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {<br>
+ if (Name == "foobar")<br>
+ return JITSymbol(0x12348765, JITSymbolFlags::Exported);<br>
+ return make_error<JITSymbolNotFound>(Name);<br>
+ };<br>
+ // Dummy symbol table entry - this should not be visible to<br>
+ // findSymbolIn.<br>
+ SymTab[43] =<br>
+ [](StringRef Name, bool ExportedSymbolsOnly) -> JITSymbol {<br>
+ if (Name == "barbaz")<br>
+ return JITSymbol(0xdeadbeef, JITSymbolFlags::Exported);<br>
+ return make_error<JITSymbolNotFound>(Name);<br>
+ };<br>
+<br>
+ return 42;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto H = cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ auto Sym1 = Client.findSymbolIn(H, "foobar", true);<br>
+<br>
+ EXPECT_TRUE(!!Sym1) << "Symbol 'foobar' should be findable";<br>
+ EXPECT_EQ(cantFail(Sym1.getAddress()), 0x12348765ULL)<br>
+ << "Symbol 'foobar' does not return the correct address";<br>
+<br>
+ auto Sym2 = Client.findSymbolIn(H, "barbaz", true);<br>
+ EXPECT_FALSE(!!Sym2) << "Symbol 'barbaz' should not be findable";<br>
+ auto Err = Sym2.takeError();<br>
+ EXPECT_TRUE(!!Err) << "Sym2 should contain an error value";<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Could not find symbol 'barbaz'")<br>
+ << "Expected symbol-not-found error for Sym2";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, EmitAndFinalize) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ logAllUnhandledErrors(std::move(Err), llvm::errs(), "");<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ SymTab[1] = MockObjectLayer::LookupFn();<br>
+ return 1;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto H = cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ auto Err = Client.emitAndFinalize(H);<br>
+ EXPECT_FALSE(!!Err) << "emitAndFinalize should work";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+TEST(RemoteObjectLayer, EmitAndFinalizeFailure) {<br>
+ llvm::orc::rpc::registerStringError<rpc::RawByteChannel>();<br>
+ auto TestObject = createTestObject();<br>
+ if (!TestObject)<br>
+ return;<br>
+<br>
+ auto Channels = createPairedQueueChannels();<br>
+<br>
+ auto ReportError =<br>
+ [](Error Err) {<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Object handle 1 not found")<br>
+ << "Expected bad handle error";<br>
+ };<br>
+<br>
+ RPCEndpoint ClientEP(*Channels.first, true);<br>
+ RemoteObjectClientLayer<RPCEndpoint> Client(ClientEP, ReportError);<br>
+<br>
+ RPCEndpoint ServerEP(*Channels.second, true);<br>
+<br>
+ MockObjectLayer BaseLayer(<br>
+ [](MockObjectLayer::ObjectPtr Obj,<br>
+ MockObjectLayer::SymbolLookupTable &SymTab) {<br>
+ return 1;<br>
+ });<br>
+ RemoteObjectServerLayer<MockObjectLayer, RPCEndpoint> Server(BaseLayer,<br>
+ ServerEP,<br>
+ ReportError);<br>
+<br>
+ bool Finished = false;<br>
+ ServerEP.addHandler<remote::utils::TerminateSession>(<br>
+ [&]() { Finished = true; }<br>
+ );<br>
+<br>
+ auto ServerThread =<br>
+ std::thread([&]() {<br>
+ while (!Finished)<br>
+ cantFail(ServerEP.handleOne());<br>
+ });<br>
+<br>
+ auto H = cantFail(Client.addObject(std::move(TestObject),<br>
+ std::make_shared<NullResolver>()));<br>
+<br>
+ auto Err = Client.emitAndFinalize(H);<br>
+ EXPECT_TRUE(!!Err) << "emitAndFinalize should work";<br>
+<br>
+ auto ErrMsg = toString(std::move(Err));<br>
+ EXPECT_EQ(ErrMsg, "Object handle 1 not found")<br>
+ << "emitAndFinalize returned incorrect error";<br>
+<br>
+ cantFail(ClientEP.callB<remote::utils::TerminateSession>());<br>
+ ServerThread.join();<br>
+}<br>
+<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</blockquote></div>