Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: src/WasmTranslator.cpp

Issue 1938643002: Subzero, WASM: stop writing uninitialized data to .o file. Add timers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make sanitizeAddress private. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« runtime/wasm-runtime.cpp ('K') | « src/IceTimerTree.def ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===// 1 //===- subzero/src/WasmTranslator.cpp - WASM to Subzero Translation -------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 LOG(out << "Buffer(" << Count << ")\n"); 269 LOG(out << "Buffer(" << Count << ")\n");
270 return Func->allocateArrayOf<Node>(Count); 270 return Func->allocateArrayOf<Node>(Count);
271 } 271 }
272 272
273 Node Error() { llvm::report_fatal_error("Error"); } 273 Node Error() { llvm::report_fatal_error("Error"); }
274 Node Start(uint32_t Params) { 274 Node Start(uint32_t Params) {
275 LOG(out << "Start(" << Params << ") = "); 275 LOG(out << "Start(" << Params << ") = ");
276 auto *Entry = Func->getEntryNode(); 276 auto *Entry = Func->getEntryNode();
277 assert(Entry); 277 assert(Entry);
278 LOG(out << Node(Entry) << "\n"); 278 LOG(out << Node(Entry) << "\n");
279
280 // Load the WasmMemory address to make it available everywhere else in the
281 // function.
282 auto *WasmMemoryPtr =
283 Ctx->getConstantExternSym(Ctx->getGlobalString("WASM_MEMORY"));
284 assert(!WasmMemory);
Jim Stichnoth 2016/05/02 16:04:07 assert(WasmMemory == nullptr);
Eric Holk 2016/05/02 17:42:37 Done.
285 auto *WasmMemoryV = makeVariable(getPointerType());
286 Entry->appendInst(InstLoad::create(Func, WasmMemoryV, WasmMemoryPtr));
287 WasmMemory = WasmMemoryV;
288
279 return OperandNode(Entry); 289 return OperandNode(Entry);
280 } 290 }
281 Node Param(uint32_t Index, wasm::LocalType Type) { 291 Node Param(uint32_t Index, wasm::LocalType Type) {
282 LOG(out << "Param(" << Index << ") = "); 292 LOG(out << "Param(" << Index << ") = ");
283 auto *Arg = makeVariable(toIceType(Type)); 293 auto *Arg = makeVariable(toIceType(Type));
284 assert(Index == NextArg); 294 assert(Index == NextArg);
285 Func->addArg(Arg); 295 Func->addArg(Arg);
286 ++NextArg; 296 ++NextArg;
287 LOG(out << Node(Arg) << "\n"); 297 LOG(out << Node(Arg) << "\n");
288 return OperandNode(Arg); 298 return OperandNode(Arg);
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 Node LoadGlobal(uint32_t Index) { 1165 Node LoadGlobal(uint32_t Index) {
1156 (void)Index; 1166 (void)Index;
1157 llvm::report_fatal_error("LoadGlobal"); 1167 llvm::report_fatal_error("LoadGlobal");
1158 } 1168 }
1159 Node StoreGlobal(uint32_t Index, Node Val) { 1169 Node StoreGlobal(uint32_t Index, Node Val) {
1160 (void)Index; 1170 (void)Index;
1161 (void)Val; 1171 (void)Val;
1162 llvm::report_fatal_error("StoreGlobal"); 1172 llvm::report_fatal_error("StoreGlobal");
1163 } 1173 }
1164 1174
1165 Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
Eric Holk 2016/04/29 22:37:42 This function is just moved down lower to make it
1166 SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;
1167
1168 bool ConstZeroBase = false;
1169
1170 // first, add the index and the offset together.
1171 if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
1172 uint32_t RealOffset = Offset + ConstBase->getValue();
1173 if (RealOffset >= MemSize) {
1174 // We've proven this will always be an out of bounds access, so insert
1175 // an unconditional trap.
1176 Control()->appendInst(InstUnreachable::create(Func));
1177 // It doesn't matter what we return here, so return something that will
1178 // allow the rest of code generation to happen.
1179 //
1180 // We might be tempted to just abort translation here, but out of bounds
1181 // memory access is a runtime trap, not a compile error.
1182 return Ctx->getConstantZero(getPointerType());
1183 }
1184 Base = Ctx->getConstantInt32(RealOffset);
1185 ConstZeroBase = (0 == RealOffset);
1186 } else if (0 != Offset) {
1187 auto *Addr = makeVariable(Ice::getPointerType());
1188 auto *OffsetConstant = Ctx->getConstantInt32(Offset);
1189 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
1190 Addr, Base, OffsetConstant));
1191
1192 Base = Addr;
1193 }
1194
1195 // Do the bounds check.
1196 //
1197 // TODO (eholk): Add a command line argument to control whether bounds
1198 // checks are inserted, and maybe add a way to duplicate bounds checks to
1199 // get a better sense of the overhead.
1200 if (!llvm::dyn_cast<ConstantInteger32>(Base)) {
1201 // TODO (eholk): creating a new basic block on every memory access is
1202 // terrible (see https://goo.gl/Zj7DTr). Try adding a new instruction that
1203 // encapsulates this "abort if false" pattern.
1204 auto *CheckPassed = Func->makeNode();
1205 auto *CheckFailed = getBoundsFailTarget();
1206
1207 auto *Check = makeVariable(IceType_i1);
1208 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Ult, Check, Base,
1209 Ctx->getConstantInt32(MemSize)));
1210 Control()->appendInst(
1211 InstBr::create(Func, Check, CheckPassed, CheckFailed));
1212
1213 *ControlPtr = OperandNode(CheckPassed);
1214 }
1215
1216 Ice::Operand *RealAddr = nullptr;
1217 auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY"));
1218 if (!ConstZeroBase) {
1219 auto RealAddrV = Func->makeVariable(Ice::getPointerType());
1220 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
1221 RealAddrV, Base, MemBase));
1222
1223 RealAddr = RealAddrV;
1224 } else {
1225 RealAddr = MemBase;
1226 }
1227 return RealAddr;
1228 }
1229
1230 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index, 1175 Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index,
1231 uint32_t Offset) { 1176 uint32_t Offset) {
1232 LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset 1177 LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset
1233 << "]) = "); 1178 << "]) = ");
1234 1179
1235 auto *RealAddr = sanitizeAddress(Index, Offset); 1180 auto *RealAddr = sanitizeAddress(Index, Offset);
1236 1181
1237 auto *LoadResult = makeVariable(toIceType(MemType)); 1182 auto *LoadResult = makeVariable(toIceType(MemType));
1238 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr)); 1183 Control()->appendInst(InstLoad::create(Func, LoadResult, RealAddr));
1239 1184
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 GlobalContext *Ctx; 1256 GlobalContext *Ctx;
1312 1257
1313 CfgNode *BoundsFailTarget = nullptr; 1258 CfgNode *BoundsFailTarget = nullptr;
1314 CfgNode *IndirectFailTarget = nullptr; 1259 CfgNode *IndirectFailTarget = nullptr;
1315 1260
1316 SizeT NextArg = 0; 1261 SizeT NextArg = 0;
1317 1262
1318 CfgUnorderedMap<Operand *, InstPhi *> PhiMap; 1263 CfgUnorderedMap<Operand *, InstPhi *> PhiMap;
1319 CfgUnorderedMap<Operand *, CfgNode *> DefNodeMap; 1264 CfgUnorderedMap<Operand *, CfgNode *> DefNodeMap;
1320 1265
1266 Operand *WasmMemory = nullptr;
1267
1321 InstPhi *getDefiningInst(Operand *Op) const { 1268 InstPhi *getDefiningInst(Operand *Op) const {
1322 const auto &Iter = PhiMap.find(Op); 1269 const auto &Iter = PhiMap.find(Op);
1323 if (Iter == PhiMap.end()) { 1270 if (Iter == PhiMap.end()) {
1324 return nullptr; 1271 return nullptr;
1325 } 1272 }
1326 return Iter->second; 1273 return Iter->second;
1327 } 1274 }
1328 1275
1329 void setDefiningInst(Operand *Op, InstPhi *Phi) { 1276 void setDefiningInst(Operand *Op, InstPhi *Phi) {
1330 LOG(out << "\n== setDefiningInst(" << Op << ", " << Phi << ") ==\n"); 1277 LOG(out << "\n== setDefiningInst(" << Op << ", " << Phi << ") ==\n");
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 IndirectFailTarget->appendInst(InstCall::create( 1318 IndirectFailTarget->appendInst(InstCall::create(
1372 Func, 0, nullptr, 1319 Func, 0, nullptr,
1373 Ctx->getConstantExternSym(Ctx->getGlobalString("__Sz_indirect_fail")), 1320 Ctx->getConstantExternSym(Ctx->getGlobalString("__Sz_indirect_fail")),
1374 false)); 1321 false));
1375 IndirectFailTarget->appendInst(InstUnreachable::create(Func)); 1322 IndirectFailTarget->appendInst(InstUnreachable::create(Func));
1376 } 1323 }
1377 1324
1378 return IndirectFailTarget; 1325 return IndirectFailTarget;
1379 } 1326 }
1380 1327
1328 Operand *getWasmMemory() {
1329 assert(WasmMemory);
Jim Stichnoth 2016/05/02 16:04:07 assert(WasmMemory != nullptr); I think we're pret
Eric Holk 2016/05/02 17:42:37 Done.
1330 return WasmMemory;
1331 }
1332
1333 Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
1334 SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;
1335
1336 bool ConstZeroBase = false;
1337
1338 // first, add the index and the offset together.
1339 if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
1340 uint32_t RealOffset = Offset + ConstBase->getValue();
1341 if (RealOffset >= MemSize) {
1342 // We've proven this will always be an out of bounds access, so insert
1343 // an unconditional trap.
1344 Control()->appendInst(InstUnreachable::create(Func));
1345 // It doesn't matter what we return here, so return something that will
1346 // allow the rest of code generation to happen.
1347 //
1348 // We might be tempted to just abort translation here, but out of bounds
1349 // memory access is a runtime trap, not a compile error.
1350 return Ctx->getConstantZero(getPointerType());
1351 }
1352 Base = Ctx->getConstantInt32(RealOffset);
1353 ConstZeroBase = (0 == RealOffset);
1354 } else if (0 != Offset) {
1355 auto *Addr = makeVariable(Ice::getPointerType());
1356 auto *OffsetConstant = Ctx->getConstantInt32(Offset);
1357 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
1358 Addr, Base, OffsetConstant));
1359
1360 Base = Addr;
1361 }
1362
1363 // Do the bounds check.
1364 //
1365 // TODO (eholk): Add a command line argument to control whether bounds
1366 // checks are inserted, and maybe add a way to duplicate bounds checks to
1367 // get a better sense of the overhead.
1368 if (!llvm::dyn_cast<ConstantInteger32>(Base)) {
1369 // TODO (eholk): creating a new basic block on every memory access is
1370 // terrible (see https://goo.gl/Zj7DTr). Try adding a new instruction that
1371 // encapsulates this "abort if false" pattern.
1372 auto *CheckPassed = Func->makeNode();
1373 auto *CheckFailed = getBoundsFailTarget();
1374
1375 auto *Check = makeVariable(IceType_i1);
1376 Control()->appendInst(InstIcmp::create(Func, InstIcmp::Ult, Check, Base,
1377 Ctx->getConstantInt32(MemSize)));
1378 Control()->appendInst(
1379 InstBr::create(Func, Check, CheckPassed, CheckFailed));
1380
1381 *ControlPtr = OperandNode(CheckPassed);
1382 }
1383
1384 Ice::Operand *RealAddr = nullptr;
1385 auto MemBase = getWasmMemory();
1386 if (!ConstZeroBase) {
1387 auto RealAddrV = Func->makeVariable(Ice::getPointerType());
1388 Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
1389 RealAddrV, Base, MemBase));
1390
1391 RealAddr = RealAddrV;
1392 } else {
1393 RealAddr = MemBase;
1394 }
1395 return RealAddr;
1396 }
1397
1381 template <typename F = std::function<void(Ostream &)>> void log(F Fn) const { 1398 template <typename F = std::function<void(Ostream &)>> void log(F Fn) const {
1382 if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_Wasm)) { 1399 if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_Wasm)) {
1383 Fn(Ctx->getStrDump()); 1400 Fn(Ctx->getStrDump());
1384 Ctx->getStrDump().flush(); 1401 Ctx->getStrDump().flush();
1385 } 1402 }
1386 } 1403 }
1387 }; 1404 };
1388 1405
1389 std::unique_ptr<Cfg> WasmTranslator::translateFunction(Zone *Zone, 1406 std::unique_ptr<Cfg> WasmTranslator::translateFunction(Zone *Zone,
1390 FunctionBody &Body) { 1407 FunctionBody &Body) {
1391 OstreamLocker L1(Ctx); 1408 OstreamLocker L1(Ctx);
1392 auto Func = Cfg::create(Ctx, getNextSequenceNumber()); 1409 auto Func = Cfg::create(Ctx, getNextSequenceNumber());
1410 TimerMarker T(TimerStack::TT_wasmGenIce, Func.get());
1393 Ice::CfgLocalAllocatorScope L2(Func.get()); 1411 Ice::CfgLocalAllocatorScope L2(Func.get());
1394 1412
1395 // TODO(eholk): parse the function signature... 1413 // TODO(eholk): parse the function signature...
1396 1414
1397 Func->setEntryNode(Func->makeNode()); 1415 Func->setEntryNode(Func->makeNode());
1398 1416
1399 IceBuilder Builder(Func.get()); 1417 IceBuilder Builder(Func.get());
1400 SR_WasmDecoder<OperandNode, IceBuilder> Decoder(Zone, &Builder, Body); 1418 SR_WasmDecoder<OperandNode, IceBuilder> Decoder(Zone, &Builder, Body);
1401 1419
1402 LOG(out << getFlags().getDefaultGlobalPrefix() << "\n"); 1420 LOG(out << getFlags().getDefaultGlobalPrefix() << "\n");
1403 Decoder.Decode(); 1421 Decoder.Decode();
1404 1422
1405 // We don't always know where the incoming branches are in phi nodes, so this 1423 // We don't always know where the incoming branches are in phi nodes, so this
1406 // function finds them. 1424 // function finds them.
1407 Func->fixPhiNodes(); 1425 Func->fixPhiNodes();
1408 1426
1409 Func->computeInOutEdges(); 1427 Func->computeInOutEdges();
1410 1428
1411 return Func; 1429 return Func;
1412 } 1430 }
1413 1431
1414 constexpr SizeT InitialBufferSize = 16 << 10; // 16KB 1432 constexpr SizeT InitialBufferSize = 16 << 10; // 16KB
1415 1433
1416 WasmTranslator::WasmTranslator(GlobalContext *Ctx) 1434 WasmTranslator::WasmTranslator(GlobalContext *Ctx)
1417 : Translator(Ctx), Buffer(InitialBufferSize) {} 1435 : Translator(Ctx), Buffer(InitialBufferSize) {}
1418 1436
1419 void WasmTranslator::translate( 1437 void WasmTranslator::translate(
1420 const std::string &IRFilename, 1438 const std::string &IRFilename,
1421 std::unique_ptr<llvm::DataStreamer> InputStream) { 1439 std::unique_ptr<llvm::DataStreamer> InputStream) {
1440 TimerMarker T(TimerStack::TT_wasm, Ctx);
1441
1422 LOG(out << "Initializing v8/wasm stuff..." 1442 LOG(out << "Initializing v8/wasm stuff..."
1423 << "\n"); 1443 << "\n");
1424 Zone Zone; 1444 Zone Zone;
1425 ZoneScope _(&Zone); 1445 ZoneScope _(&Zone);
1426 1446
1427 SizeT BytesRead = 0; 1447 SizeT BytesRead = 0;
1428 while (true) { 1448 while (true) {
1429 BytesRead += 1449 BytesRead +=
1430 InputStream->GetBytes(&Buffer[BytesRead], Buffer.size() - BytesRead); 1450 InputStream->GetBytes(&Buffer[BytesRead], Buffer.size() - BytesRead);
1431 LOG(out << "Read " << BytesRead << " bytes" 1451 LOG(out << "Read " << BytesRead << " bytes"
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 Body.module = &ModuleEnv; 1546 Body.module = &ModuleEnv;
1527 1547
1528 LOG(out << "Translating " << IRFilename << "\n"); 1548 LOG(out << "Translating " << IRFilename << "\n");
1529 1549
1530 { 1550 {
1531 unique_ptr<VariableDeclarationList> Globals = 1551 unique_ptr<VariableDeclarationList> Globals =
1532 makeUnique<VariableDeclarationList>(); 1552 makeUnique<VariableDeclarationList>();
1533 1553
1534 // Global variables, etc go here. 1554 // Global variables, etc go here.
1535 auto *WasmMemory = VariableDeclaration::createExternal(Globals.get()); 1555 auto *WasmMemory = VariableDeclaration::createExternal(Globals.get());
1536 WasmMemory->setName(Ctx->getGlobalString("WASM_MEMORY")); 1556 WasmMemory->setName(Ctx->getGlobalString("WASM_DATA_INIT"));
1537 1557
1538 // Fill in the segments 1558 // Fill in the segments
1539 SizeT WritePtr = 0; 1559 SizeT WritePtr = 0;
1540 for (const auto Seg : Module->data_segments) { 1560 for (const auto Seg : Module->data_segments) {
1541 // fill in gaps with zero. 1561 // fill in gaps with zero.
1542 if (Seg.dest_addr > WritePtr) { 1562 if (Seg.dest_addr > WritePtr) {
1543 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create( 1563 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
1544 Globals.get(), Seg.dest_addr - WritePtr)); 1564 Globals.get(), Seg.dest_addr - WritePtr));
1545 WritePtr = Seg.dest_addr; 1565 WritePtr = Seg.dest_addr;
1546 } 1566 }
1547 1567
1548 // Add the data 1568 // Add the data
1549 WasmMemory->addInitializer(VariableDeclaration::DataInitializer::create( 1569 WasmMemory->addInitializer(VariableDeclaration::DataInitializer::create(
1550 Globals.get(), reinterpret_cast<const char *>(Module->module_start) + 1570 Globals.get(), reinterpret_cast<const char *>(Module->module_start) +
1551 Seg.source_offset, 1571 Seg.source_offset,
1552 Seg.source_size)); 1572 Seg.source_size));
1553 1573
1554 WritePtr += Seg.source_size; 1574 WritePtr += Seg.source_size;
1555 } 1575 }
1556 1576
1557 // Save the size of the initialized data in a global variable so the runtime 1577 // Save the size of the initialized data in a global variable so the runtime
1558 // can use it to determine the initial heap break. 1578 // can use it to determine the initial heap break.
1559 auto *GlobalDataSize = VariableDeclaration::createExternal(Globals.get()); 1579 auto *GlobalDataSize = VariableDeclaration::createExternal(Globals.get());
1560 GlobalDataSize->setName(Ctx->getGlobalString("WASM_DATA_SIZE")); 1580 GlobalDataSize->setName(Ctx->getGlobalString("WASM_DATA_SIZE"));
1561 GlobalDataSize->addInitializer(VariableDeclaration::DataInitializer::create( 1581 GlobalDataSize->addInitializer(VariableDeclaration::DataInitializer::create(
1562 Globals.get(), reinterpret_cast<const char *>(&WritePtr), 1582 Globals.get(), reinterpret_cast<const char *>(&WritePtr),
1563 sizeof(WritePtr))); 1583 sizeof(WritePtr)));
1564 1584
1565 // Pad the rest with zeros
1566 SizeT DataSize = Module->min_mem_pages * WASM_PAGE_SIZE;
1567 if (WritePtr < DataSize) {
1568 WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
1569 Globals.get(), DataSize - WritePtr));
1570 }
1571
1572 // Save the number of pages for the runtime 1585 // Save the number of pages for the runtime
1573 auto *GlobalNumPages = VariableDeclaration::createExternal(Globals.get()); 1586 auto *GlobalNumPages = VariableDeclaration::createExternal(Globals.get());
1574 GlobalNumPages->setName(Ctx->getGlobalString("WASM_NUM_PAGES")); 1587 GlobalNumPages->setName(Ctx->getGlobalString("WASM_NUM_PAGES"));
1575 GlobalNumPages->addInitializer(VariableDeclaration::DataInitializer::create( 1588 GlobalNumPages->addInitializer(VariableDeclaration::DataInitializer::create(
1576 Globals.get(), reinterpret_cast<const char *>(&Module->min_mem_pages), 1589 Globals.get(), reinterpret_cast<const char *>(&Module->min_mem_pages),
1577 sizeof(Module->min_mem_pages))); 1590 sizeof(Module->min_mem_pages)));
1578 1591
1579 Globals->push_back(WasmMemory); 1592 Globals->push_back(WasmMemory);
1580 Globals->push_back(GlobalDataSize); 1593 Globals->push_back(GlobalDataSize);
1581 Globals->push_back(GlobalNumPages); 1594 Globals->push_back(GlobalNumPages);
1582 1595
1583 lowerGlobals(std::move(Globals)); 1596 lowerGlobals(std::move(Globals));
1584 } 1597 }
1585 1598
1586 // Translate each function. 1599 // Translate each function.
1587 for (const auto Fn : Module->functions) { 1600 for (const auto Fn : Module->functions) {
1588 const auto FnName = getFunctionName(Module, Fn.func_index); 1601 const auto FnName = getFunctionName(Module, Fn.func_index);
1589 1602
1590 LOG(out << " " << Fn.func_index << ": " << FnName << "..."); 1603 LOG(out << " " << Fn.func_index << ": " << FnName << "...");
1591 1604
1592 Body.sig = Fn.sig; 1605 Body.sig = Fn.sig;
1593 Body.base = Buffer.data(); 1606 Body.base = Buffer.data();
1594 Body.start = Buffer.data() + Fn.code_start_offset; 1607 Body.start = Buffer.data() + Fn.code_start_offset;
1595 Body.end = Buffer.data() + Fn.code_end_offset; 1608 Body.end = Buffer.data() + Fn.code_end_offset;
1596 1609
1597 auto Func = translateFunction(&Zone, Body); 1610 std::unique_ptr<Cfg> Func = nullptr;
1598 Func->setFunctionName(Ctx->getGlobalString(FnName)); 1611 {
1599 1612 TimerMarker T_func(getContext(), FnName);
1613 Func = translateFunction(&Zone, Body);
1614 Func->setFunctionName(Ctx->getGlobalString(FnName));
1615 }
1600 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func))); 1616 Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func)));
1601 LOG(out << "done.\n"); 1617 LOG(out << "done.\n");
1602 } 1618 }
1603 1619
1604 return; 1620 return;
1605 } 1621 }
1606 1622
1607 #endif // ALLOW_WASM 1623 #endif // ALLOW_WASM
OLDNEW
« runtime/wasm-runtime.cpp ('K') | « src/IceTimerTree.def ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698