Changeset 240447 in webkit for trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
- Timestamp:
- Jan 24, 2019, 1:30:55 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp
r240023 r240447 1216 1216 } 1217 1217 1218 auto forEachEscapee = [&] (auto callback) { 1219 for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { 1220 m_heap = m_heapAtHead[block]; 1221 m_heap.setWantEscapees(); 1222 1223 for (Node* node : *block) { 1224 handleNode( 1225 node, 1226 [] (PromotedHeapLocation, LazyNode) { }, 1227 [] (PromotedHeapLocation) -> Node* { 1228 return nullptr; 1229 }); 1230 auto escapees = m_heap.takeEscapees(); 1231 escapees.removeIf([&] (const auto& entry) { return !m_sinkCandidates.contains(entry.key); }); 1232 callback(escapees, node); 1233 } 1234 1235 m_heap.pruneByLiveness(m_combinedLiveness.liveAtTail[block]); 1236 1237 { 1238 HashMap<Node*, Allocation> escapingOnEdge; 1239 for (const auto& entry : m_heap.allocations()) { 1240 if (entry.value.isEscapedAllocation()) 1241 continue; 1242 1243 bool mustEscape = false; 1244 for (BasicBlock* successorBlock : block->successors()) { 1245 if (!m_heapAtHead[successorBlock].isAllocation(entry.key) 1246 || m_heapAtHead[successorBlock].getAllocation(entry.key).isEscapedAllocation()) 1247 mustEscape = true; 1248 } 1249 1250 if (mustEscape && m_sinkCandidates.contains(entry.key)) 1251 escapingOnEdge.add(entry.key, entry.value); 1252 } 1253 callback(escapingOnEdge, block->terminal()); 1254 } 1255 } 1256 }; 1257 1258 if (m_sinkCandidates.size()) { 1259 // If we're moving an allocation to `where` in the program, we need to ensure 1260 // we can still walk the stack at that point in the program for the 1261 // InlineCallFrame of the original allocation. Certain InlineCallFrames rely on 1262 // data in the stack when taking a stack trace. All allocation sites can do a 1263 // stack walk (we do a stack walk when we GC). Conservatively, we say we're 1264 // still ok to move this allocation if we are moving within the same InlineCallFrame. 1265 // We could be more precise here and do an analysis of stack writes. However, 1266 // this scenario is so rare that we just take the conservative-and-straight-forward 1267 // approach of checking that we're in the same InlineCallFrame. 1268 1269 forEachEscapee([&] (HashMap<Node*, Allocation>& escapees, Node* where) { 1270 for (Node* allocation : escapees.keys()) { 1271 InlineCallFrame* inlineCallFrame = allocation->origin.semantic.inlineCallFrame; 1272 if (!inlineCallFrame) 1273 continue; 1274 if ((inlineCallFrame->isClosureCall || inlineCallFrame->isVarargs()) && inlineCallFrame != where->origin.semantic.inlineCallFrame) 1275 m_sinkCandidates.remove(allocation); 1276 } 1277 }); 1278 } 1279 1218 1280 // Ensure that the set of sink candidates is closed for put operations 1281 // This is (2) as described above. 1219 1282 Vector<Node*> worklist; 1220 1283 worklist.appendRange(m_sinkCandidates.begin(), m_sinkCandidates.end()); … … 1233 1296 dataLog("Candidates: ", listDump(m_sinkCandidates), "\n"); 1234 1297 1235 // Create the materialization nodes 1236 for (BasicBlock* block : m_graph.blocksInNaturalOrder()) { 1237 m_heap = m_heapAtHead[block]; 1238 m_heap.setWantEscapees(); 1239 1240 for (Node* node : *block) { 1241 handleNode( 1242 node, 1243 [] (PromotedHeapLocation, LazyNode) { }, 1244 [] (PromotedHeapLocation) -> Node* { 1245 return nullptr; 1246 }); 1247 auto escapees = m_heap.takeEscapees(); 1248 if (!escapees.isEmpty()) 1249 placeMaterializations(escapees, node); 1250 } 1251 1252 m_heap.pruneByLiveness(m_combinedLiveness.liveAtTail[block]); 1253 1254 { 1255 HashMap<Node*, Allocation> escapingOnEdge; 1256 for (const auto& entry : m_heap.allocations()) { 1257 if (entry.value.isEscapedAllocation()) 1258 continue; 1259 1260 bool mustEscape = false; 1261 for (BasicBlock* successorBlock : block->successors()) { 1262 if (!m_heapAtHead[successorBlock].isAllocation(entry.key) 1263 || m_heapAtHead[successorBlock].getAllocation(entry.key).isEscapedAllocation()) 1264 mustEscape = true; 1265 } 1266 1267 if (mustEscape) 1268 escapingOnEdge.add(entry.key, entry.value); 1269 } 1270 placeMaterializations(WTFMove(escapingOnEdge), block->terminal()); 1271 } 1272 } 1298 1299 // Create the materialization nodes. 1300 forEachEscapee([&] (HashMap<Node*, Allocation>& escapees, Node* where) { 1301 placeMaterializations(WTFMove(escapees), where); 1302 }); 1273 1303 1274 1304 return hasUnescapedReads || !m_sinkCandidates.isEmpty(); … … 1277 1307 void placeMaterializations(HashMap<Node*, Allocation> escapees, Node* where) 1278 1308 { 1279 // We don't create materializations if the escapee is not a1280 // sink candidate1281 escapees.removeIf(1282 [&] (const auto& entry) {1283 return !m_sinkCandidates.contains(entry.key);1284 });1285 if (escapees.isEmpty())1286 return;1287 1288 1309 // First collect the hints that will be needed when the node 1289 1310 // we materialize is still stored into other unescaped sink candidates.
Note:
See TracChangeset
for help on using the changeset viewer.