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