Changeset 99898 in webkit
- Timestamp:
- Nov 10, 2011 1:59:39 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 added
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r99895 r99898 1 2011-11-10 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should not reparse code that was just parsed 4 https://bugs.webkit.org/show_bug.cgi?id=71977 5 6 Reviewed by Geoff Garen. 7 8 The instruction stream of a code block is now kept around until 9 the next GC. When doing either an optimizing compilation of an 10 executable, or inlining of an executable, we now try to find the 11 already preexisting bytecode. If we find it, we don't have to parse. 12 If we don't find it, we parse as before. Inlining takes the extra 13 step of caching code blocks, so if the same executable gets inlined 14 multiple times into the same caller, then we parse it at most once 15 even if prior to inlining that executable did not have any code 16 blocks with an instruction stream. 17 18 Also fixed a silly bug where the strict mode for various operations 19 was being determined by looking at the machine code block rather 20 than the inlinee. 21 22 To enable the delete-on-next-GC policy, I introduced the notion 23 of an ultra weak finalizer, which anyone can register during 24 tracing. This is thread-safe (for parallel GC) and 25 stop-the-world-safe (so calls to free() are postponed until the 26 world is resumed). This required reusing some facilities previously 27 created for WeakReferenceHarvester, so I created a common utility 28 class. I also retweaked the handling of WeakReferenceHarvesters, 29 since they should be executed during stop-the-world since in the 30 future we may want to allow them to call drain(). 31 32 2% win on SunSpider. 2% win on V8, when run in my harness. Neutral 33 elsewhere. 34 35 * JavaScriptCore.xcodeproj/project.pbxproj: 36 * bytecode/CodeBlock.cpp: 37 (JSC::CodeBlock::CodeBlock): 38 (JSC::CodeBlock::visitAggregate): 39 (JSC::CodeBlock::copyPostParseDataFrom): 40 (JSC::CodeBlock::copyPostParseDataFromAlternative): 41 (JSC::CodeBlock::finalizeUnconditionally): 42 * bytecode/CodeBlock.h: 43 (JSC::CodeBlock::canProduceCopyWithBytecode): 44 (JSC::CodeBlock::discardBytecodeLater): 45 (JSC::CodeBlock::handleBytecodeDiscardingOpportunity): 46 (JSC::GlobalCodeBlock::GlobalCodeBlock): 47 (JSC::ProgramCodeBlock::ProgramCodeBlock): 48 (JSC::EvalCodeBlock::EvalCodeBlock): 49 (JSC::FunctionCodeBlock::FunctionCodeBlock): 50 (JSC::BytecodeDestructionBlocker::BytecodeDestructionBlocker): 51 (JSC::BytecodeDestructionBlocker::~BytecodeDestructionBlocker): 52 * dfg/DFGAssemblyHelpers.h: 53 (JSC::DFG::AssemblyHelpers::strictModeFor): 54 * dfg/DFGByteCodeCache.h: Added. 55 (JSC::DFG::CodeBlockKey::CodeBlockKey): 56 (JSC::DFG::CodeBlockKey::operator==): 57 (JSC::DFG::CodeBlockKey::hash): 58 (JSC::DFG::CodeBlockKey::executable): 59 (JSC::DFG::CodeBlockKey::kind): 60 (JSC::DFG::CodeBlockKey::isHashTableDeletedValue): 61 (JSC::DFG::CodeBlockKeyHash::hash): 62 (JSC::DFG::CodeBlockKeyHash::equal): 63 (JSC::DFG::ByteCodeCache::ByteCodeCache): 64 (JSC::DFG::ByteCodeCache::~ByteCodeCache): 65 (JSC::DFG::ByteCodeCache::get): 66 * dfg/DFGByteCodeParser.cpp: 67 (JSC::DFG::ByteCodeParser::handleInlining): 68 * dfg/DFGJITCodeGenerator32_64.cpp: 69 (JSC::DFG::JITCodeGenerator::cachedPutById): 70 * dfg/DFGJITCodeGenerator64.cpp: 71 (JSC::DFG::JITCodeGenerator::cachedPutById): 72 * dfg/DFGSpeculativeJIT64.cpp: 73 (JSC::DFG::SpeculativeJIT::compile): 74 * heap/Heap.cpp: 75 (JSC::Heap::finalizeUnconditionally): 76 (JSC::Heap::markRoots): 77 (JSC::Heap::collect): 78 * heap/Heap.h: 79 * heap/ListableHandler.h: Added. 80 (JSC::ListableHandler::ListableHandler): 81 (JSC::ListableHandler::~ListableHandler): 82 (JSC::ListableHandler::List::List): 83 (JSC::ListableHandler::List::addNotThreadSafe): 84 (JSC::ListableHandler::List::addThreadSafe): 85 (JSC::ListableHandler::List::hasNext): 86 (JSC::ListableHandler::List::removeNext): 87 * heap/MarkStack.cpp: 88 (JSC::MarkStackThreadSharedData::MarkStackThreadSharedData): 89 (JSC::SlotVisitor::harvestWeakReferences): 90 (JSC::SlotVisitor::finalizeUnconditionally): 91 * heap/MarkStack.h: 92 (JSC::MarkStack::addWeakReferenceHarvester): 93 (JSC::MarkStack::addUnconditionalFinalizer): 94 * heap/SlotVisitor.h: 95 * heap/UnconditionalFinalizer.h: Added. 96 (JSC::UnconditionalFinalizer::~UnconditionalFinalizer): 97 * heap/WeakReferenceHarvester.h: 98 (JSC::WeakReferenceHarvester::WeakReferenceHarvester): 99 (JSC::WeakReferenceHarvester::~WeakReferenceHarvester): 100 * runtime/Executable.cpp: 101 (JSC::EvalExecutable::compileInternal): 102 (JSC::ProgramExecutable::compileInternal): 103 (JSC::FunctionExecutable::baselineCodeBlockFor): 104 (JSC::FunctionExecutable::codeBlockWithBytecodeFor): 105 (JSC::FunctionExecutable::produceCodeBlockFor): 106 (JSC::FunctionExecutable::compileForCallInternal): 107 (JSC::FunctionExecutable::compileForConstructInternal): 108 * runtime/Executable.h: 109 (JSC::FunctionExecutable::profiledCodeBlockFor): 110 1 111 2011-11-10 Gavin Barraclough <barraclough@apple.com> 2 112 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r99787 r99898 55 55 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; }; 56 56 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; }; 57 0F431738146BAC69007E3890 /* ListableHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F431736146BAC65007E3890 /* ListableHandler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 58 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 57 59 0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 58 60 0F620175143FCD370068B77C /* DFGOperands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620171143FCD2F0068B77C /* DFGOperands.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 830 832 0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; }; 831 833 0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; }; 834 0F431736146BAC65007E3890 /* ListableHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ListableHandler.h; sourceTree = "<group>"; }; 835 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGByteCodeCache.h; path = dfg/DFGByteCodeCache.h; sourceTree = "<group>"; }; 836 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnconditionalFinalizer.h; sourceTree = "<group>"; }; 832 837 0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; }; 833 838 0F62016E143FCD2F0068B77C /* DFGAbstractState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractState.h; path = dfg/DFGAbstractState.h; sourceTree = "<group>"; }; … … 1702 1707 isa = PBXGroup; 1703 1708 children = ( 1709 0F5F08CE146C762F000472A9 /* UnconditionalFinalizer.h */, 1710 0F431736146BAC65007E3890 /* ListableHandler.h */, 1704 1711 0FD82F281426CA5A00179C94 /* JettisonedCodeBlocks.cpp */, 1705 1712 0FD82F291426CA5A00179C94 /* JettisonedCodeBlocks.h */, … … 2318 2325 isa = PBXGroup; 2319 2326 children = ( 2327 0F5F08CC146BE602000472A9 /* DFGByteCodeCache.h */, 2320 2328 0FC0979F146B28C700CF2442 /* DFGThunks.cpp */, 2321 2329 0FC097A0146B28C700CF2442 /* DFGThunks.h */, … … 2944 2952 0FC0979C146A772500CF2442 /* DFGCorrectableJumpPoint.h in Headers */, 2945 2953 0FC097A2146B28CC00CF2442 /* DFGThunks.h in Headers */, 2954 0F431738146BAC69007E3890 /* ListableHandler.h in Headers */, 2955 0F5F08CF146C7633000472A9 /* UnconditionalFinalizer.h in Headers */, 2946 2956 ); 2947 2957 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r99810 r99898 1408 1408 } 1409 1409 1410 CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab) 1411 : m_globalObject(other.m_globalObject) 1412 , m_heap(other.m_heap) 1413 , m_numCalleeRegisters(other.m_numCalleeRegisters) 1414 , m_numVars(other.m_numVars) 1415 , m_numCapturedVars(other.m_numCapturedVars) 1416 , m_numParameters(other.m_numParameters) 1417 , m_isConstructor(other.m_isConstructor) 1418 , m_shouldDiscardBytecode(false) 1419 , m_ownerExecutable(*other.m_globalData, other.m_ownerExecutable.get(), other.m_ownerExecutable.get()) 1420 , m_globalData(other.m_globalData) 1421 , m_instructions(other.m_instructions) 1422 , m_instructionCount(other.m_instructionCount) 1423 , m_thisRegister(other.m_thisRegister) 1424 , m_argumentsRegister(other.m_argumentsRegister) 1425 , m_activationRegister(other.m_activationRegister) 1426 , m_needsFullScopeChain(other.m_needsFullScopeChain) 1427 , m_usesEval(other.m_usesEval) 1428 , m_isNumericCompareFunction(other.m_isNumericCompareFunction) 1429 , m_isStrictMode(other.m_isStrictMode) 1430 , m_codeType(other.m_codeType) 1431 , m_source(other.m_source) 1432 , m_sourceOffset(other.m_sourceOffset) 1433 , m_globalResolveInfos(other.m_globalResolveInfos) 1434 , m_jumpTargets(other.m_jumpTargets) 1435 , m_loopTargets(other.m_loopTargets) 1436 , m_identifiers(other.m_identifiers) 1437 , m_constantRegisters(other.m_constantRegisters) 1438 , m_functionDecls(other.m_functionDecls) 1439 , m_functionExprs(other.m_functionExprs) 1440 , m_symbolTable(symTab) 1441 , m_speculativeSuccessCounter(0) 1442 , m_speculativeFailCounter(0) 1443 , m_optimizationDelayCounter(0) 1444 , m_reoptimizationRetryCounter(0) 1445 { 1446 optimizeAfterWarmUp(); 1447 1448 if (other.m_rareData) { 1449 createRareDataIfNecessary(); 1450 1451 m_rareData->m_exceptionHandlers = other.m_rareData->m_exceptionHandlers; 1452 m_rareData->m_regexps = other.m_rareData->m_regexps; 1453 m_rareData->m_constantBuffers = other.m_rareData->m_constantBuffers; 1454 m_rareData->m_immediateSwitchJumpTables = other.m_rareData->m_immediateSwitchJumpTables; 1455 m_rareData->m_characterSwitchJumpTables = other.m_rareData->m_characterSwitchJumpTables; 1456 m_rareData->m_stringSwitchJumpTables = other.m_rareData->m_stringSwitchJumpTables; 1457 m_rareData->m_expressionInfo = other.m_rareData->m_expressionInfo; 1458 m_rareData->m_lineInfo = other.m_rareData->m_lineInfo; 1459 } 1460 } 1461 1410 1462 CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject *globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, SymbolTable* symTab, bool isConstructor, PassOwnPtr<CodeBlock> alternative) 1411 1463 : m_globalObject(globalObject->globalData(), ownerExecutable, globalObject) … … 1415 1467 , m_numParameters(0) 1416 1468 , m_isConstructor(isConstructor) 1469 , m_shouldDiscardBytecode(false) 1417 1470 , m_ownerExecutable(globalObject->globalData(), ownerExecutable, ownerExecutable) 1418 1471 , m_globalData(0) … … 1596 1649 valueProfile(profileIndex)->computeUpdatedPrediction(); 1597 1650 #endif 1651 1652 #if ENABLE(JIT) && !ENABLE(OPCODE_SAMPLING) 1653 // Kill off some bytecode. We can't do it here because we don't want to accidentally 1654 // call into malloc while in stop-the-world GC mode. 1655 if (hasInstructions() && m_shouldDiscardBytecode) 1656 visitor.addUnconditionalFinalizer(this); 1657 #endif 1598 1658 } 1599 1659 … … 1822 1882 } 1823 1883 1824 void CodeBlock::copy DataFrom(CodeBlock* alternative)1884 void CodeBlock::copyPostParseDataFrom(CodeBlock* alternative) 1825 1885 { 1826 1886 if (!alternative) … … 1834 1894 } 1835 1895 1836 void CodeBlock::copy DataFromAlternative()1837 { 1838 copy DataFrom(m_alternative.get());1896 void CodeBlock::copyPostParseDataFromAlternative() 1897 { 1898 copyPostParseDataFrom(m_alternative.get()); 1839 1899 } 1840 1900 … … 1917 1977 } 1918 1978 #endif 1979 1980 void CodeBlock::finalizeUnconditionally() 1981 { 1982 #if ENABLE(OPCODE_SAMPLING) || !ENABLE(JIT) 1983 ASSERT_NOT_REACHED(); 1984 #endif 1985 ASSERT(m_shouldDiscardBytecode); 1986 discardBytecode(); 1987 } 1919 1988 1920 1989 #if ENABLE(VALUE_PROFILER) -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.h
r99810 r99898 46 46 #include "RegExpObject.h" 47 47 #include "UString.h" 48 #include "UnconditionalFinalizer.h" 48 49 #include "ValueProfile.h" 49 50 #include <wtf/FastAllocBase.h> … … 237 238 #endif 238 239 239 class CodeBlock {240 class CodeBlock : public UnconditionalFinalizer { 240 241 WTF_MAKE_FAST_ALLOCATED; 241 242 friend class JIT; 243 public: 244 enum CopyParsedBlockTag { CopyParsedBlock }; 242 245 protected: 246 CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable*); 247 243 248 CodeBlock(ScriptExecutable* ownerExecutable, CodeType, JSGlobalObject*, PassRefPtr<SourceProvider>, unsigned sourceOffset, SymbolTable*, bool isConstructor, PassOwnPtr<CodeBlock> alternative); 244 249 … … 266 271 } 267 272 #endif 273 274 bool canProduceCopyWithBytecode() { return hasInstructions(); } 268 275 269 276 void visitAggregate(SlotVisitor&); … … 444 451 const Vector<Instruction>& instructions() const { return m_instructions->m_instructions; } 445 452 void discardBytecode() { m_instructions.clear(); } 446 453 void discardBytecodeLater() 454 { 455 m_shouldDiscardBytecode = true; 456 } 457 void handleBytecodeDiscardingOpportunity() 458 { 459 if (!!alternative()) 460 discardBytecode(); 461 else 462 discardBytecodeLater(); 463 } 464 447 465 #ifndef NDEBUG 448 466 bool usesOpcode(OpcodeID); … … 809 827 void shrinkToFit(); 810 828 811 void copy DataFrom(CodeBlock* alternative);812 void copy DataFromAlternative();829 void copyPostParseDataFrom(CodeBlock* alternative); 830 void copyPostParseDataFromAlternative(); 813 831 814 832 // Functions for controlling when tiered compilation kicks in. This … … 997 1015 bool m_isConstructor; 998 1016 1017 // This is public because otherwise we would have many friends. 1018 bool m_shouldDiscardBytecode; 1019 1020 protected: 1021 virtual void finalizeUnconditionally(); 1022 999 1023 private: 1000 1024 #if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING) … … 1015 1039 m_rareData = adoptPtr(new RareData); 1016 1040 } 1017 1041 1018 1042 WriteBarrier<ScriptExecutable> m_ownerExecutable; 1019 1043 JSGlobalData* m_globalData; … … 1130 1154 class GlobalCodeBlock : public CodeBlock { 1131 1155 protected: 1156 GlobalCodeBlock(CopyParsedBlockTag, GlobalCodeBlock& other) 1157 : CodeBlock(CopyParsedBlock, other, &m_unsharedSymbolTable) 1158 , m_unsharedSymbolTable(other.m_unsharedSymbolTable) 1159 { 1160 } 1161 1132 1162 GlobalCodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset, PassOwnPtr<CodeBlock> alternative) 1133 1163 : CodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, sourceOffset, &m_unsharedSymbolTable, false, alternative) … … 1141 1171 class ProgramCodeBlock : public GlobalCodeBlock { 1142 1172 public: 1173 ProgramCodeBlock(CopyParsedBlockTag, ProgramCodeBlock& other) 1174 : GlobalCodeBlock(CopyParsedBlock, other) 1175 { 1176 } 1177 1143 1178 ProgramCodeBlock(ProgramExecutable* ownerExecutable, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, PassOwnPtr<CodeBlock> alternative) 1144 1179 : GlobalCodeBlock(ownerExecutable, codeType, globalObject, sourceProvider, 0, alternative) … … 1157 1192 class EvalCodeBlock : public GlobalCodeBlock { 1158 1193 public: 1194 EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other) 1195 : GlobalCodeBlock(CopyParsedBlock, other) 1196 , m_baseScopeDepth(other.m_baseScopeDepth) 1197 , m_variables(other.m_variables) 1198 { 1199 } 1200 1159 1201 EvalCodeBlock(EvalExecutable* ownerExecutable, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth, PassOwnPtr<CodeBlock> alternative) 1160 1202 : GlobalCodeBlock(ownerExecutable, EvalCode, globalObject, sourceProvider, 0, alternative) … … 1188 1230 class FunctionCodeBlock : public CodeBlock { 1189 1231 public: 1232 FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other) 1233 : CodeBlock(CopyParsedBlock, other, other.sharedSymbolTable()) 1234 { 1235 // The fact that we have to do this is yucky, but is necessary because of the 1236 // class hierarchy issues described in the comment block for the main 1237 // constructor, below. 1238 sharedSymbolTable()->ref(); 1239 } 1240 1190 1241 // Rather than using the usual RefCounted::create idiom for SharedSymbolTable we just use new 1191 1242 // as we need to initialise the CodeBlock before we could initialise any RefPtr to hold the shared … … 1208 1259 virtual bool canCompileWithDFG(); 1209 1260 #endif 1261 }; 1262 1263 // Use this if you want to copy a code block and you're paranoid about a GC 1264 // happening. 1265 class BytecodeDestructionBlocker { 1266 public: 1267 BytecodeDestructionBlocker(CodeBlock* codeBlock) 1268 : m_codeBlock(codeBlock) 1269 , m_oldValueOfShouldDiscardBytecode(codeBlock->m_shouldDiscardBytecode) 1270 { 1271 codeBlock->m_shouldDiscardBytecode = false; 1272 } 1273 1274 ~BytecodeDestructionBlocker() 1275 { 1276 m_codeBlock->m_shouldDiscardBytecode = m_oldValueOfShouldDiscardBytecode; 1277 } 1278 1279 private: 1280 CodeBlock* m_codeBlock; 1281 bool m_oldValueOfShouldDiscardBytecode; 1210 1282 }; 1211 1283 -
trunk/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
r99888 r99898 238 238 } 239 239 240 bool strictModeFor(CodeOrigin codeOrigin) 241 { 242 if (!codeOrigin.inlineCallFrame) 243 return codeBlock()->isStrictMode(); 244 return codeOrigin.inlineCallFrame->callee->jsExecutable()->isStrictMode(); 245 } 246 240 247 CodeBlock* baselineCodeBlockFor(const CodeOrigin& codeOrigin) 241 248 { -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r99788 r99898 29 29 #if ENABLE(DFG_JIT) 30 30 31 #include "DFGByteCodeCache.h" 31 32 #include "DFGCapabilities.h" 32 33 #include "CodeBlock.h" … … 842 843 // Mapping between values and constant numbers. 843 844 JSValueMap m_jsValueMap; 845 846 // Cache of code blocks that we've generated bytecode for. 847 ByteCodeCache<canInlineFunctionFor> m_codeBlockCache; 844 848 }; 845 849 … … 957 961 // If we get here then it looks like we should definitely inline this code. Proceed 958 962 // with parsing the code to get bytecode, so that we can then parse the bytecode. 959 // Note that the code block we get here is intended to die after handleInlining() 960 // returns. 961 JSObject* exception; 962 OwnPtr<CodeBlock> codeBlock = executable->produceCodeBlockFor(expectedFunction->scope(), OptimizingCompilation, kind, exception); 963 CodeBlock* codeBlock = m_codeBlockCache.get(CodeBlockKey(executable, kind), expectedFunction->scope()); 963 964 if (!codeBlock) 964 965 return false; 965 ASSERT(!exception); 966 967 // Now that we have the bytecode, check if we really can inline it. This may fail 968 // if the code block contains some nasty opcodes. 969 if (!canInlineFunctionFor(codeBlock.get(), kind)) 970 return false; 966 967 ASSERT(canInlineFunctionFor(codeBlock, kind)); 971 968 972 969 #if DFG_ENABLE(DEBUG_VERBOSE) … … 999 996 } 1000 997 1001 InlineStackEntry inlineStackEntry(this, codeBlock .get(), profiledBlock, m_graph.m_blocks.size() - 1, (VirtualRegister)m_inlineStackTop->remapOperand(callTarget), expectedFunction, (VirtualRegister)m_inlineStackTop->remapOperand(usesResult ? resultOperand : InvalidVirtualRegister), (VirtualRegister)inlineCallFrameStart, kind);998 InlineStackEntry inlineStackEntry(this, codeBlock, profiledBlock, m_graph.m_blocks.size() - 1, (VirtualRegister)m_inlineStackTop->remapOperand(callTarget), expectedFunction, (VirtualRegister)m_inlineStackTop->remapOperand(usesResult ? resultOperand : InvalidVirtualRegister), (VirtualRegister)inlineCallFrameStart, kind); 1002 999 1003 1000 // This is where the actual inlining really happens. -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator32_64.cpp
r99622 r99898 909 909 silentSpillAllRegisters(InvalidGPRReg); 910 910 V_DFGOperation_EJCI optimizedCall; 911 if (m_jit. codeBlock()->isStrictMode()) {911 if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) { 912 912 if (putKind == Direct) 913 913 optimizedCall = operationPutByIdDirectStrictOptimize; -
trunk/Source/JavaScriptCore/dfg/DFGJITCodeGenerator64.cpp
r99622 r99898 838 838 silentSpillAllRegisters(InvalidGPRReg); 839 839 V_DFGOperation_EJCI optimizedCall; 840 if (m_jit. codeBlock()->isStrictMode()) {840 if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) { 841 841 if (putKind == Direct) 842 842 optimizedCall = operationPutByIdDirectStrictOptimize; -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r99765 r99898 1507 1507 flushRegisters(); 1508 1508 1509 callOperation(m_jit. codeBlock()->isStrictMode() ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);1509 callOperation(m_jit.strictModeFor(node.codeOrigin) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR); 1510 1510 1511 1511 noResult(m_compileIndex); -
trunk/Source/JavaScriptCore/heap/Heap.cpp
r99477 r99898 531 531 } 532 532 533 void Heap::finalizeUnconditionalFinalizers() 534 { 535 m_slotVisitor.finalizeUnconditionalFinalizers(); 536 } 537 533 538 inline RegisterFile& Heap::registerFile() 534 539 { … … 695 700 } 696 701 GCCOUNTER(VisitedValueCount, visitor.visitCount()); 702 703 { 704 GCPHASE(HarvestWeakReferences); 705 harvestWeakReferences(); 706 } 707 697 708 visitor.reset(); 698 709 m_sharedData.reset(); … … 782 793 783 794 markRoots(fullGC); 784 785 { 786 GCPHASE(HarvestWeakReferences); 787 harvestWeakReferences(); 795 796 { 797 GCPHASE(FinalizeUnconditionalFinalizers); 798 finalizeUnconditionalFinalizers(); 799 } 800 801 { 802 GCPHASE(FinalizeWeakHandles); 788 803 m_handleHeap.finalizeWeakHandles(); 789 804 m_globalData->smallStrings.finalizeSmallStrings(); 790 805 } 791 806 792 807 JAVASCRIPTCORE_GC_MARKED(); 793 808 -
trunk/Source/JavaScriptCore/heap/Heap.h
r98937 r99898 156 156 void markTempSortVectors(HeapRootVisitor&); 157 157 void harvestWeakReferences(); 158 void finalizeUnconditionalFinalizers(); 158 159 159 160 enum SweepToggle { DoNotSweep, DoSweep }; -
trunk/Source/JavaScriptCore/heap/MarkStack.cpp
r98937 r99898 237 237 , m_numberOfActiveParallelMarkers(0) 238 238 , m_parallelMarkersShouldExit(false) 239 , m_firstWeakReferenceHarvester(0)240 239 { 241 240 #if ENABLE(PARALLEL_GC) … … 451 450 void SlotVisitor::harvestWeakReferences() 452 451 { 453 while (m_shared.m_firstWeakReferenceHarvester) { 454 WeakReferenceHarvester* current = m_shared.m_firstWeakReferenceHarvester; 455 WeakReferenceHarvester* next = reinterpret_cast<WeakReferenceHarvester*>(current->m_nextAndFlag & ~1); 456 current->m_nextAndFlag = 0; 457 m_shared.m_firstWeakReferenceHarvester = next; 458 current->visitWeakReferences(*this); 459 } 452 while (m_shared.m_weakReferenceHarvesters.hasNext()) 453 m_shared.m_weakReferenceHarvesters.removeNext()->visitWeakReferences(*this); 454 } 455 456 void SlotVisitor::finalizeUnconditionalFinalizers() 457 { 458 while (m_shared.m_unconditionalFinalizers.hasNext()) 459 m_shared.m_unconditionalFinalizers.removeNext()->finalizeUnconditionally(); 460 460 } 461 461 -
trunk/Source/JavaScriptCore/heap/MarkStack.h
r98937 r99898 31 31 #include "JSValue.h" 32 32 #include "Register.h" 33 #include "UnconditionalFinalizer.h" 33 34 #include "VTableSpectrum.h" 34 35 #include "WeakReferenceHarvester.h" … … 195 196 HashSet<void*> m_opaqueRoots; 196 197 197 Mutex m_weakReferenceHarvesterLock;198 WeakReferenceHarvester* m_firstWeakReferenceHarvester;198 ListableHandler<WeakReferenceHarvester>::List m_weakReferenceHarvesters; 199 ListableHandler<UnconditionalFinalizer>::List m_unconditionalFinalizers; 199 200 }; 200 201 … … 230 231 void addWeakReferenceHarvester(WeakReferenceHarvester* weakReferenceHarvester) 231 232 { 232 MutexLocker locker(m_shared.m_weakReferenceHarvesterLock); 233 if (weakReferenceHarvester->m_nextAndFlag & 1) 234 return; 235 weakReferenceHarvester->m_nextAndFlag = reinterpret_cast<uintptr_t>(m_shared.m_firstWeakReferenceHarvester) | 1; 236 m_shared.m_firstWeakReferenceHarvester = weakReferenceHarvester; 233 m_shared.m_weakReferenceHarvesters.addThreadSafe(weakReferenceHarvester); 234 } 235 236 void addUnconditionalFinalizer(UnconditionalFinalizer* unconditionalFinalizer) 237 { 238 m_shared.m_unconditionalFinalizers.addThreadSafe(unconditionalFinalizer); 237 239 } 238 240 -
trunk/Source/JavaScriptCore/heap/SlotVisitor.h
r98937 r99898 59 59 60 60 void harvestWeakReferences(); 61 void finalizeUnconditionalFinalizers(); 61 62 62 63 private: -
trunk/Source/JavaScriptCore/heap/WeakReferenceHarvester.h
r98937 r99898 21 21 #define WeakReferenceHarvester_h 22 22 23 #include <stdint.h>23 #include "ListableHandler.h" 24 24 25 25 namespace JSC { … … 29 29 class SlotVisitor; 30 30 31 class WeakReferenceHarvester {31 class WeakReferenceHarvester : public ListableHandler<WeakReferenceHarvester> { 32 32 public: 33 33 virtual void visitWeakReferences(SlotVisitor&) = 0; … … 35 35 protected: 36 36 WeakReferenceHarvester() 37 : m_nextAndFlag(0)38 37 { 39 38 } 40 39 41 40 virtual ~WeakReferenceHarvester() { } 42 43 private:44 friend class MarkStack;45 friend class MarkStackSharedData;46 friend class SlotVisitor;47 48 uintptr_t m_nextAndFlag;49 41 }; 50 42 -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r99374 r99898 157 157 JSGlobalData* globalData = &exec->globalData(); 158 158 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 159 if (!lexicalGlobalObject->evalEnabled()) 160 return throwError(exec, createEvalError(exec, "Eval is disabled")); 161 RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 162 if (!evalNode) { 163 ASSERT(exception); 164 return exception; 165 } 166 recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); 167 168 JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 169 170 OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release(); 171 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 172 m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release())); 173 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 174 if ((exception = generator->generate())) { 175 m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative()); 159 160 if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) { 161 BytecodeDestructionBlocker blocker(m_evalCodeBlock.get()); 162 OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock)); 163 newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release())); 164 m_evalCodeBlock = newCodeBlock.release(); 165 } else { 166 if (!lexicalGlobalObject->evalEnabled()) 167 return throwError(exec, createEvalError(exec, "Eval is disabled")); 168 RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 169 if (!evalNode) { 170 ASSERT(exception); 171 return exception; 172 } 173 recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); 174 175 JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 176 177 OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release(); 178 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 179 m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release())); 180 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 181 if ((exception = generator->generate())) { 182 m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative()); 183 evalNode->destroyData(); 184 return exception; 185 } 186 176 187 evalNode->destroyData(); 177 return exception; 178 } 179 180 evalNode->destroyData(); 181 m_evalCodeBlock->copyDataFromAlternative(); 188 m_evalCodeBlock->copyPostParseDataFromAlternative(); 189 } 182 190 183 191 #if ENABLE(JIT) … … 199 207 #if !ENABLE(OPCODE_SAMPLING) 200 208 if (!BytecodeGenerator::dumpsGeneratedCode()) 201 m_evalCodeBlock-> discardBytecode();209 m_evalCodeBlock->handleBytecodeDiscardingOpportunity(); 202 210 #endif 203 211 m_evalCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr()); … … 291 299 JSGlobalData* globalData = &exec->globalData(); 292 300 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 293 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 294 if (!programNode) { 295 ASSERT(exception); 296 return exception; 297 } 298 recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); 299 300 JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 301 302 OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release(); 303 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 304 m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release())); 305 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 306 if ((exception = generator->generate())) { 307 m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative()); 301 302 if (!!m_programCodeBlock && m_programCodeBlock->canProduceCopyWithBytecode()) { 303 BytecodeDestructionBlocker blocker(m_programCodeBlock.get()); 304 OwnPtr<ProgramCodeBlock> newCodeBlock = adoptPtr(new ProgramCodeBlock(CodeBlock::CopyParsedBlock, *m_programCodeBlock)); 305 newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock.release())); 306 m_programCodeBlock = newCodeBlock.release(); 307 } else { 308 RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); 309 if (!programNode) { 310 ASSERT(exception); 311 return exception; 312 } 313 recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); 314 315 JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); 316 317 OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release(); 318 ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); 319 m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release())); 320 OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); 321 if ((exception = generator->generate())) { 322 m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative()); 323 programNode->destroyData(); 324 return exception; 325 } 326 308 327 programNode->destroyData(); 309 return exception; 310 } 311 312 programNode->destroyData(); 313 m_programCodeBlock->copyDataFromAlternative(); 328 m_programCodeBlock->copyPostParseDataFromAlternative(); 329 } 314 330 315 331 #if ENABLE(JIT) … … 330 346 #if !ENABLE(OPCODE_SAMPLING) 331 347 if (!BytecodeGenerator::dumpsGeneratedCode()) 332 m_programCodeBlock-> discardBytecode();348 m_programCodeBlock->handleBytecodeDiscardingOpportunity(); 333 349 #endif 334 350 m_programCodeBlock->setJITCode(m_jitCodeForCall, MacroAssemblerCodePtr()); … … 389 405 } 390 406 391 CodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind)392 { 393 CodeBlock* result;407 FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind) 408 { 409 FunctionCodeBlock* result; 394 410 if (kind == CodeForCall) 395 411 result = m_codeBlockForCall.get(); … … 401 417 return 0; 402 418 while (result->alternative()) 403 result = result->alternative();419 result = static_cast<FunctionCodeBlock*>(result->alternative()); 404 420 ASSERT(result); 405 421 ASSERT(result->getJITType() == JITCode::BaselineJIT); … … 429 445 } 430 446 447 FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializationKind kind) 448 { 449 FunctionCodeBlock* codeBlock = baselineCodeBlockFor(kind); 450 if (codeBlock->canProduceCopyWithBytecode()) 451 return codeBlock; 452 return 0; 453 } 454 431 455 PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChainNode* scopeChainNode, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception) 432 456 { 457 if (!!codeBlockFor(specializationKind) && codeBlockFor(specializationKind)->canProduceCopyWithBytecode()) { 458 BytecodeDestructionBlocker blocker(codeBlockFor(specializationKind).get()); 459 return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind))); 460 } 461 433 462 exception = 0; 434 463 JSGlobalData* globalData = scopeChainNode->globalData; … … 454 483 return nullptr; 455 484 456 result->copy DataFrom(codeBlockFor(specializationKind).get());485 result->copyPostParseDataFrom(codeBlockFor(specializationKind).get()); 457 486 return result.release(); 458 487 } … … 499 528 #if !ENABLE(OPCODE_SAMPLING) 500 529 if (!BytecodeGenerator::dumpsGeneratedCode()) 501 m_codeBlockForCall-> discardBytecode();530 m_codeBlockForCall->handleBytecodeDiscardingOpportunity(); 502 531 #endif 503 532 … … 562 591 #if !ENABLE(OPCODE_SAMPLING) 563 592 if (!BytecodeGenerator::dumpsGeneratedCode()) 564 m_codeBlockForConstruct-> discardBytecode();593 m_codeBlockForConstruct->handleBytecodeDiscardingOpportunity(); 565 594 #endif 566 595 -
trunk/Source/JavaScriptCore/runtime/Executable.h
r98214 r99898 479 479 } 480 480 481 FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind); 482 481 483 PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception); 482 484 … … 587 589 } 588 590 589 CodeBlock* baselineCodeBlockFor(CodeSpecializationKind);590 591 CodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind)591 FunctionCodeBlock* baselineCodeBlockFor(CodeSpecializationKind); 592 593 FunctionCodeBlock* profiledCodeBlockFor(CodeSpecializationKind kind) 592 594 { 593 595 return baselineCodeBlockFor(kind);
Note: See TracChangeset
for help on using the changeset viewer.