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