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