Changeset 226725 in webkit for trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
- Timestamp:
- Jan 10, 2018, 11:41:12 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r226667 r226725 52 52 #include "InlineCallFrame.h" 53 53 #include "InterpreterInlines.h" 54 #include "IsoCellSetInlines.h"55 54 #include "JIT.h" 56 55 #include "JITMathIC.h" … … 331 330 , m_reoptimizationRetryCounter(0) 332 331 , m_creationTime(MonotonicTime::now()) 333 { 332 , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this)) 333 , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this)) 334 { 335 m_visitWeaklyHasBeenCalled = false; 336 334 337 ASSERT(heap()->isDeferred()); 335 338 ASSERT(m_scopeRegister.isLocal()); 336 339 337 340 setNumParameters(other.numParameters()); 338 339 vm->heap.codeBlockSet().add(this);340 341 } 341 342 … … 343 344 { 344 345 Base::finishCreation(vm); 345 finishCreationCommon(vm);346 346 347 347 optimizeAfterWarmUp(); … … 355 355 m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables; 356 356 } 357 358 heap()->m_codeBlocks->add(this); 357 359 } 358 360 … … 388 390 , m_reoptimizationRetryCounter(0) 389 391 , m_creationTime(MonotonicTime::now()) 390 { 392 , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this)) 393 , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this)) 394 { 395 m_visitWeaklyHasBeenCalled = false; 396 391 397 ASSERT(heap()->isDeferred()); 392 398 ASSERT(m_scopeRegister.isLocal()); … … 394 400 ASSERT(m_source); 395 401 setNumParameters(unlinkedCodeBlock->numParameters()); 396 397 vm->heap.codeBlockSet().add(this);398 402 } 399 403 … … 410 414 { 411 415 Base::finishCreation(vm); 412 finishCreationCommon(vm);413 416 414 417 auto throwScope = DECLARE_THROW_SCOPE(vm); … … 847 850 dumpBytecode(); 848 851 852 heap()->m_codeBlocks->add(this); 849 853 heap()->reportExtraMemoryAllocated(m_instructions.size() * sizeof(Instruction)); 850 854 … … 852 856 } 853 857 854 void CodeBlock::finishCreationCommon(VM& vm)855 {856 m_ownerEdge.set(vm, this, ExecutableToCodeBlockEdge::create(vm, this));857 }858 859 858 CodeBlock::~CodeBlock() 860 859 { 861 860 VM& vm = *m_poisonedVM; 862 863 vm.heap.codeBlockSet().remove(this);864 865 861 if (UNLIKELY(vm.m_perBytecodeProfiler)) 866 862 vm.m_perBytecodeProfiler->notifyDestruction(this); 867 863 868 if ( !vm.heap.isShuttingDown() &&unlinkedCodeBlock()->didOptimize() == MixedTriState)864 if (unlinkedCodeBlock()->didOptimize() == MixedTriState) 869 865 unlinkedCodeBlock()->setDidOptimize(FalseTriState); 870 866 … … 980 976 } 981 977 978 void CodeBlock::visitWeakly(SlotVisitor& visitor) 979 { 980 ConcurrentJSLocker locker(m_lock); 981 if (m_visitWeaklyHasBeenCalled) 982 return; 983 984 m_visitWeaklyHasBeenCalled = true; 985 986 if (Heap::isMarked(this)) 987 return; 988 989 if (shouldVisitStrongly(locker)) { 990 visitor.appendUnbarriered(this); 991 return; 992 } 993 994 // There are two things that may use unconditional finalizers: inline cache clearing 995 // and jettisoning. The probability of us wanting to do at least one of those things 996 // is probably quite close to 1. So we add one no matter what and when it runs, it 997 // figures out whether it has any work to do. 998 visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get()); 999 1000 if (!JITCode::isOptimizingJIT(jitType())) 1001 return; 1002 1003 // If we jettison ourselves we'll install our alternative, so make sure that it 1004 // survives GC even if we don't. 1005 visitor.append(m_alternative); 1006 1007 // There are two things that we use weak reference harvesters for: DFG fixpoint for 1008 // jettisoning, and trying to find structures that would be live based on some 1009 // inline cache. So it makes sense to register them regardless. 1010 visitor.addWeakReferenceHarvester(m_weakReferenceHarvester.get()); 1011 1012 #if ENABLE(DFG_JIT) 1013 // We get here if we're live in the sense that our owner executable is live, 1014 // but we're not yet live for sure in another sense: we may yet decide that this 1015 // code block should be jettisoned based on its outgoing weak references being 1016 // stale. Set a flag to indicate that we're still assuming that we're dead, and 1017 // perform one round of determining if we're live. The GC may determine, based on 1018 // either us marking additional objects, or by other objects being marked for 1019 // other reasons, that this iteration should run again; it will notify us of this 1020 // decision by calling harvestWeakReferences(). 1021 1022 m_allTransitionsHaveBeenMarked = false; 1023 propagateTransitions(locker, visitor); 1024 1025 m_jitCode->dfgCommon()->livenessHasBeenProved = false; 1026 determineLiveness(locker, visitor); 1027 #endif // ENABLE(DFG_JIT) 1028 } 1029 982 1030 size_t CodeBlock::estimatedSize(JSCell* cell) 983 1031 { … … 994 1042 ASSERT_GC_OBJECT_INHERITS(thisObject, info()); 995 1043 JSCell::visitChildren(thisObject, visitor); 996 visitor.append(thisObject->m_ownerEdge);997 1044 thisObject->visitChildren(visitor); 998 1045 } … … 1001 1048 { 1002 1049 ConcurrentJSLocker locker(m_lock); 1050 // There are two things that may use unconditional finalizers: inline cache clearing 1051 // and jettisoning. The probability of us wanting to do at least one of those things 1052 // is probably quite close to 1. So we add one no matter what and when it runs, it 1053 // figures out whether it has any work to do. 1054 visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get()); 1055 1003 1056 if (CodeBlock* otherBlock = specialOSREntryBlockOrNull()) 1004 1057 visitor.appendUnbarriered(otherBlock); … … 1019 1072 stronglyVisitStrongReferences(locker, visitor); 1020 1073 stronglyVisitWeakReferences(locker, visitor); 1021 1022 VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).add(this); 1074 1075 m_allTransitionsHaveBeenMarked = false; 1076 propagateTransitions(locker, visitor); 1023 1077 } 1024 1078 … … 1111 1165 UNUSED_PARAM(visitor); 1112 1166 1167 if (m_allTransitionsHaveBeenMarked) 1168 return; 1169 1113 1170 VM& vm = *m_poisonedVM; 1114 1171 bool allAreMarkedSoFar = true; 1172 1115 1173 if (jitType() == JITCode::InterpreterThunk) { 1116 1174 const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions(); … … 1129 1187 if (Heap::isMarked(oldStructure)) 1130 1188 visitor.appendUnbarriered(newStructure); 1189 else 1190 allAreMarkedSoFar = false; 1131 1191 break; 1132 1192 } … … 1140 1200 if (JITCode::isJIT(jitType())) { 1141 1201 for (auto iter = m_stubInfos.begin(); !!iter; ++iter) 1142 (*iter)->propagateTransitions(visitor);1202 allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor); 1143 1203 } 1144 1204 #endif // ENABLE(JIT) … … 1148 1208 DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); 1149 1209 for (auto& weakReference : dfgCommon->weakStructureReferences) 1150 weakReference->markIfCheap(visitor);1210 allAreMarkedSoFar &= weakReference->markIfCheap(visitor); 1151 1211 1152 1212 for (auto& transition : dfgCommon->transitions) { … … 1172 1232 1173 1233 visitor.append(transition.m_to); 1174 } 1234 } else 1235 allAreMarkedSoFar = false; 1175 1236 } 1176 1237 } 1177 1238 #endif // ENABLE(DFG_JIT) 1239 1240 if (allAreMarkedSoFar) 1241 m_allTransitionsHaveBeenMarked = true; 1178 1242 } 1179 1243 … … 1183 1247 1184 1248 #if ENABLE(DFG_JIT) 1185 if (Heap::isMarked(this)) 1249 // Check if we have any remaining work to do. 1250 DFG::CommonData* dfgCommon = m_jitCode->dfgCommon(); 1251 if (dfgCommon->livenessHasBeenProved) 1186 1252 return; 1187 1253 1188 // In rare and weird cases, this could be called on a baseline CodeBlock. One that I found was1189 // that we might decide that the CodeBlock should be jettisoned due to old age, so the1190 // isMarked check doesn't protect us.1191 if (!JITCode::isOptimizingJIT(jitType()))1192 return;1193 1194 DFG::CommonData* dfgCommon = m_jitCode->dfgCommon();1195 1254 // Now check all of our weak references. If all of them are live, then we 1196 1255 // have proved liveness and so we scan our strong references. If at end of … … 1221 1280 // All weak references are live. Record this information so we don't 1222 1281 // come back here again, and scan the strong references. 1282 dfgCommon->livenessHasBeenProved = true; 1223 1283 visitor.appendUnbarriered(this); 1224 1284 #endif // ENABLE(DFG_JIT) 1285 } 1286 1287 void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor) 1288 { 1289 codeBlock.propagateTransitions(NoLockingNecessary, visitor); 1290 codeBlock.determineLiveness(NoLockingNecessary, visitor); 1225 1291 } 1226 1292 … … 1356 1422 } 1357 1423 1358 void CodeBlock::finalizeUnconditionally(VM&) 1359 { 1360 updateAllPredictions(); 1361 1362 if (JITCode::couldBeInterpreted(jitType())) 1363 finalizeLLIntInlineCaches(); 1424 void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally() 1425 { 1426 codeBlock.updateAllPredictions(); 1427 1428 if (!Heap::isMarked(&codeBlock)) { 1429 if (codeBlock.shouldJettisonDueToWeakReference()) 1430 codeBlock.jettison(Profiler::JettisonDueToWeakReference); 1431 else 1432 codeBlock.jettison(Profiler::JettisonDueToOldAge); 1433 return; 1434 } 1435 1436 if (JITCode::couldBeInterpreted(codeBlock.jitType())) 1437 codeBlock.finalizeLLIntInlineCaches(); 1364 1438 1365 1439 #if ENABLE(JIT) 1366 if (!!jitCode()) 1367 finalizeBaselineJITInlineCaches(); 1368 #endif 1369 1370 VM::SpaceAndFinalizerSet::finalizerSetFor(*subspace()).remove(this); 1440 if (!!codeBlock.jitCode()) 1441 codeBlock.finalizeBaselineJITInlineCaches(); 1442 #endif 1371 1443 } 1372 1444 … … 1522 1594 1523 1595 visitor.append(m_globalObject); 1524 visitor.append(m_ownerExecutable); // This is extra important since it causes the ExecutableToCodeBlockEdge to be marked.1596 visitor.append(m_ownerExecutable); 1525 1597 visitor.append(m_unlinkedCode); 1526 1598 if (m_rareData) … … 3061 3133 { 3062 3134 #if ENABLE(SIGNAL_BASED_VM_TRAPS) 3135 3063 3136 // This function may be called from a signal handler. We need to be 3064 3137 // careful to not call anything that is not signal handler safe, e.g. … … 3080 3153 if (!JITCode::isOptimizingJIT(jitType())) 3081 3154 return false; 3082 auto& commonData = *m_jitCode->dfgCommon(); 3083 commonData.installVMTrapBreakpoints(this); 3155 m_jitCode->dfgCommon()->installVMTrapBreakpoints(this); 3084 3156 return true; 3085 3157 #else … … 3121 3193 totalSubSize += subIC->codeSize(); 3122 3194 } 3195 3196 return false; 3123 3197 }; 3124 3198 heap()->forEachCodeBlock(countICs);
Note:
See TracChangeset
for help on using the changeset viewer.