blob: f6ed8496eb6bd342146c366c3622600ebca177b9 [file] [log] [blame]
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +00001//===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Implementation of the RemoteTargetExternal class which executes JITed code
11// in a separate process from where it was built.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/Config/config.h"
16
17#include "RemoteTarget.h"
18#include "RemoteTargetExternal.h"
19
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/DataTypes.h"
22#include "llvm/Support/Memory.h"
23#include "llvm/Support/Program.h"
24#include "llvm/Support/raw_ostream.h"
25#include <string>
26
27using namespace llvm;
28
29bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,
30 uint64_t &Address) {
31 SendAllocateSpace(Alignment, Size);
32 Receive(LLI_AllocationResult, Address);
33 return false;
34}
35
36bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) {
37 SendLoadSection(Address, Data, (uint32_t)Size, false);
38 Receive(LLI_LoadComplete);
39 return false;
40}
41
42bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) {
43 SendLoadSection(Address, Data, (uint32_t)Size, true);
44 Receive(LLI_LoadComplete);
45 return false;
46}
47
48bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) {
49 SendExecute(Address);
50
51 Receive(LLI_ExecutionResult, RetVal);
52 return false;
53}
54
55void RemoteTargetExternal::stop() {
56 SendTerminate();
57 Wait();
58}
59
60void RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {
61 int rc;
Matt Arsenaultc44a3ff2013-12-05 19:37:36 +000062 (void)rc;
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +000063 uint32_t MsgType = (uint32_t)LLI_AllocateSpace;
64 rc = WriteBytes(&MsgType, 4);
65 assert(rc == 4 && "Error writing message type.");
66
67 uint32_t DataSize = 8;
68 rc = WriteBytes(&DataSize, 4);
69 assert(rc == 4 && "Error writing data size.");
70
71 rc = WriteBytes(&Alignment, 4);
72 assert(rc == 4 && "Error writing alignment data.");
73
74 rc = WriteBytes(&Size, 4);
75 assert(rc == 4 && "Error writing size data.");
76}
77
78void RemoteTargetExternal::SendLoadSection(uint64_t Addr,
79 const void *Data,
80 uint32_t Size,
81 bool IsCode) {
82 int rc;
83 uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;
84 rc = WriteBytes(&MsgType, 4);
85 assert(rc == 4 && "Error writing message type.");
86
87 uint32_t DataSize = Size + 8;
88 rc = WriteBytes(&DataSize, 4);
89 assert(rc == 4 && "Error writing data size.");
90
91 rc = WriteBytes(&Addr, 8);
92 assert(rc == 8 && "Error writing data.");
93
94 rc = WriteBytes(Data, Size);
95 assert(rc == (int)Size && "Error writing data.");
96}
97
98void RemoteTargetExternal::SendExecute(uint64_t Addr) {
99 int rc;
100 uint32_t MsgType = (uint32_t)LLI_Execute;
101 rc = WriteBytes(&MsgType, 4);
102 assert(rc == 4 && "Error writing message type.");
103
104 uint32_t DataSize = 8;
105 rc = WriteBytes(&DataSize, 4);
106 assert(rc == 4 && "Error writing data size.");
107
108 rc = WriteBytes(&Addr, 8);
109 assert(rc == 8 && "Error writing data.");
110}
111
112void RemoteTargetExternal::SendTerminate() {
113 int rc;
114 uint32_t MsgType = (uint32_t)LLI_Terminate;
115 rc = WriteBytes(&MsgType, 4);
116 assert(rc == 4 && "Error writing message type.");
117
118 // No data or data size is sent with Terminate
119}
120
121
122void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) {
123 int rc;
124 uint32_t MsgType;
125 rc = ReadBytes(&MsgType, 4);
126 assert(rc == 4 && "Error reading message type.");
Andrew Kaylor004e12f2013-10-02 18:00:34 +0000127 assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type.");
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000128
129 uint32_t DataSize;
130 rc = ReadBytes(&DataSize, 4);
131 assert(rc == 4 && "Error reading data size.");
132 assert(DataSize == 0 && "Error: unexpected data size.");
133}
134
135void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) {
136 uint64_t Temp;
137 Receive(ExpectedMsgType, Temp);
138 Data = (int)(int64_t)Temp;
139}
140
141void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Data) {
142 int rc;
143 uint32_t MsgType;
144 rc = ReadBytes(&MsgType, 4);
145 assert(rc == 4 && "Error reading message type.");
Andrew Kaylor004e12f2013-10-02 18:00:34 +0000146 assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type.");
Andrew Kaylorc2ebf3f2013-10-02 17:12:36 +0000147
148 uint32_t DataSize;
149 rc = ReadBytes(&DataSize, 4);
150 assert(rc == 4 && "Error reading data size.");
151 assert(DataSize == 8 && "Error: unexpected data size.");
152
153 rc = ReadBytes(&Data, 8);
154 assert(DataSize == 8 && "Error: unexpected data.");
155}
156
157#ifdef LLVM_ON_UNIX
158#include "Unix/RemoteTargetExternal.inc"
159#endif
160
161#ifdef LLVM_ON_WIN32
162#include "Windows/RemoteTargetExternal.inc"
163#endif