[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
Wed Sep 6 15:58:31 PDT 2017


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/20170906/57844248/attachment-0001.html>


More information about the llvm-commits mailing list