[llvm] r312511 - [ORC] Add a pair of ORC layers that forward object-layer operations via RPC.
NAKAMURA Takumi via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 7 17:44:02 PDT 2017
Yes, at least, r312758 is failing. See
http://bb.pgr.jp/builders/bootstrap-clang-libcxx-lld-i686-linux
On Fri, Sep 8, 2017 at 9:40 AM Lang Hames <lhames at gmail.com> wrote:
> That's interesting. There was another modules bug with my patch (which has
> since been fixed), but I wouldn't necessarily have expected it to be
> connected to this.
>
> Is it still reproducing on the builder?
>
> Cheers,
> Lang.
>
> On Wed, Sep 6, 2017 at 3:58 PM, NAKAMURA Takumi <geek4civic at gmail.com>
> wrote:
>
>> I couldn't reproduce the issue on my local work tree. I have to stop the
>> builder to reproduce.
>>
>> The builder is configured;
>> - clang built by gcc-4.8
>> - Release w/o Asserts
>> - Just-built libc++ and libc++abi
>> - -fmodules
>>
>> -fmodules might be dubious. I'll investigate in my afternoon.
>>
>> On Thu, Sep 7, 2017 at 2:32 AM Lang Hames <lhames at gmail.com> wrote:
>>
>>> 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/linux/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::SerializationTraits<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-libcxx-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::SerializationTraits<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::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
>>>>> #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> >) (
>>>>> H=<unknown type in
>>>>> /home/bb/bootstrap-clang-libcxx-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::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>)
>>>>> 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-libcxx-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::SerializationTraits<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-libcxx-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::SequenceSerialization<llvm::orc::rpc::RawByteChannel,
>>>>> llvm::Error>::serialize<llvm::Error>(llvm::orc::rpc::RawByteChannel&,
>>>>> llvm::Error&&) (C=...,
>>>>> CArg=<unknown type in
>>>>> /home/bb/bootstrap-clang-libcxx-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-libcxx-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::RespondHelper<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::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
>>>>> #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)
>>>>> 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::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
>>>>> #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++-v3/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/linux/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/build/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-libcxx-lld-i686-linux/llvm-project/llvm/unittests/ExecutionEngine/Orc/QueueChannel.h:90
>>>>> #4 0x00000000010d8bc4 in
>>>>> llvm::orc::rpc::SerializationTraits<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::SequenceSerialization<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::SerializationTraits<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::SequenceSerialization<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::SerializationTraits<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::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&)
>>>>> (
>>>>> this=0x2b80950, C=...) at
>>>>> /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:808
>>>>> #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
>>>>> #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
>>>>> #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,
>>>>> Args=@0x7fffffffda30: 1) at
>>>>> /home/bb/bootstrap-clang-libcxx-lld-i686-linux/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPCUtils.h:1588
>>>>> #15 0x000000000110d0aa in
>>>>> llvm::orc::RemoteObjectClientLayer<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::HandleSehExceptionsInMethodIfSupported<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::HandleExceptionsInMethodIfSupported<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-libcxx-lld-i686-linux/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc:4649
>>>>> #23 0x00000000019e7f0e in
>>>>> testing::internal::HandleSehExceptionsInMethodIfSupported<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::HandleExceptionsInMethodIfSupported<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/OrcRemoteTargetRPCAPI.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::UnderlyingType>(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<JITSymbolFlags::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<RemoteSymbolId>;
>>>>>> + 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::string,
>>>>>> + 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::LookupInLogicalDylib;
>>>>>> +
>>>>>> + 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::LookupInLogicalDylib;
>>>>>> +
>>>>>> + 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<StringMemoryBuffer>(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/ExecutionEngine/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/ExecutionEngine/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/RemoteObjectLayerTest.cpp
>>>>>> URL:
>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/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/20170908/784792d5/attachment-0001.html>
More information about the llvm-commits
mailing list