Diff
Added: trunk/JSTests/stress/create-promise-finalize.js (0 => 249668)
--- trunk/JSTests/stress/create-promise-finalize.js (rev 0)
+++ trunk/JSTests/stress/create-promise-finalize.js 2019-09-09 21:38:17 UTC (rev 249668)
@@ -0,0 +1,9 @@
+function foo() {
+ class P extends Promise {}
+ new P(()=>{});
+}
+
+foo();
+drainMicrotasks();
+gc();
+foo();
Modified: trunk/Source/_javascript_Core/ChangeLog (249667 => 249668)
--- trunk/Source/_javascript_Core/ChangeLog 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-09-09 21:38:17 UTC (rev 249668)
@@ -1,3 +1,39 @@
+2019-09-09 Yusuke Suzuki <ysuz...@apple.com>
+
+ [JSC] Use metadata table to iterate specific bytecode metadata instead of propertyAccessInstructions vector
+ https://bugs.webkit.org/show_bug.cgi?id=201613
+
+ Reviewed by Mark Lam.
+
+ We do not need to maintain propertyAccessInstructions vector to access metadata tied to a specific bytecode opcode
+ since we have MetadataTable::forEach<Op> feature. This removes propertyAccessInstructions entirely, and fixes the
+ issue that `op_create_promise` missed propertyAccessInstructions registration (a name "propertyAccessInstructions" is
+ misleading, it is like "instructions-requires-llint-finalize").
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::propagateTransitions):
+ (JSC::CodeBlock::finalizeLLIntInlineCaches):
+ * bytecode/UnlinkedCodeBlock.cpp:
+ (JSC::UnlinkedCodeBlock::applyModification):
+ (JSC::UnlinkedCodeBlock::shrinkToFit):
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedCodeBlock::addPropertyAccessInstruction): Deleted.
+ (JSC::UnlinkedCodeBlock::numberOfPropertyAccessInstructions const): Deleted.
+ (JSC::UnlinkedCodeBlock::propertyAccessInstructions const): Deleted.
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitResolveScope):
+ (JSC::BytecodeGenerator::emitGetFromScope):
+ (JSC::BytecodeGenerator::emitPutToScope):
+ (JSC::BytecodeGenerator::emitGetById):
+ (JSC::BytecodeGenerator::emitDirectGetById):
+ (JSC::BytecodeGenerator::emitPutById):
+ (JSC::BytecodeGenerator::emitDirectPutById):
+ (JSC::BytecodeGenerator::emitCreateThis):
+ (JSC::BytecodeGenerator::emitToThis):
+ * runtime/CachedTypes.cpp:
+ (JSC::CachedCodeBlock<CodeBlockType>::decode const):
+ (JSC::CachedCodeBlock<CodeBlockType>::encode):
+
2019-09-07 Keith Miller <keith_mil...@apple.com>
OSR entry into wasm misses some contexts
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (249667 => 249668)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2019-09-09 21:38:17 UTC (rev 249668)
@@ -1088,16 +1088,12 @@
VM& vm = *m_vm;
if (jitType() == JITType::InterpreterThunk) {
- const Vector<InstructionStream::Offset>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
- const InstructionStream& instructionStream = instructions();
- for (size_t i = 0; i < propertyAccessInstructions.size(); ++i) {
- auto instruction = instructionStream.at(propertyAccessInstructions[i]);
- if (instruction->is<OpPutById>()) {
- auto& metadata = instruction->as<OpPutById>().metadata(this);
+ if (m_metadata) {
+ m_metadata->forEach<OpPutById>([&] (auto& metadata) {
StructureID oldStructureID = metadata.m_oldStructureID;
StructureID newStructureID = metadata.m_newStructureID;
if (!oldStructureID || !newStructureID)
- continue;
+ return;
Structure* oldStructure =
vm.heap.structureIDTable().get(oldStructureID);
Structure* newStructure =
@@ -1104,8 +1100,7 @@
vm.heap.structureIDTable().get(newStructureID);
if (vm.heap.isMarked(oldStructure))
visitor.appendUnbarriered(newStructure);
- continue;
- }
+ });
}
}
@@ -1206,50 +1201,33 @@
void CodeBlock::finalizeLLIntInlineCaches()
{
VM& vm = *m_vm;
- const Vector<InstructionStream::Offset>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
- auto handleGetPutFromScope = [&] (auto& metadata) {
- GetPutInfo getPutInfo = metadata.m_getPutInfo;
- if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks
- || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
- return;
- WriteBarrierBase<Structure>& structure = metadata.m_structure;
- if (!structure || vm.heap.isMarked(structure.get()))
- return;
- if (Options::verboseOSR())
- dataLogF("Clearing scope access with structure %p.\n", structure.get());
- structure.clear();
- };
+ if (m_metadata) {
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=166418
+ // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution.
- const InstructionStream& instructionStream = instructions();
- for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
- const auto curInstruction = instructionStream.at(propertyAccessInstructions[i]);
- switch (curInstruction->opcodeID()) {
- case op_get_by_id: {
- auto& metadata = curInstruction->as<OpGetById>().metadata(this);
+ m_metadata->forEach<OpGetById>([&] (auto& metadata) {
if (metadata.m_modeMetadata.mode != GetByIdMode::Default)
- break;
+ return;
StructureID oldStructureID = metadata.m_modeMetadata.defaultMode.structureID;
if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
- break;
+ return;
if (Options::verboseOSR())
dataLogF("Clearing LLInt property access.\n");
LLIntPrototypeLoadAdaptiveStructureWatchpoint::clearLLIntGetByIdCache(metadata);
- break;
- }
- case op_get_by_id_direct: {
- auto& metadata = curInstruction->as<OpGetByIdDirect>().metadata(this);
+ });
+
+ m_metadata->forEach<OpGetByIdDirect>([&] (auto& metadata) {
StructureID oldStructureID = metadata.m_structureID;
if (!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
- break;
+ return;
if (Options::verboseOSR())
dataLogF("Clearing LLInt property access.\n");
metadata.m_structureID = 0;
metadata.m_offset = 0;
- break;
- }
- case op_put_by_id: {
- auto& metadata = curInstruction->as<OpPutById>().metadata(this);
+ });
+
+ m_metadata->forEach<OpPutById>([&] (auto& metadata) {
StructureID oldStructureID = metadata.m_oldStructureID;
StructureID newStructureID = metadata.m_newStructureID;
StructureChain* chain = metadata.m_structureChain.get();
@@ -1256,7 +1234,7 @@
if ((!oldStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(oldStructureID)))
&& (!newStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(newStructureID)))
&& (!chain || vm.heap.isMarked(chain)))
- break;
+ return;
if (Options::verboseOSR())
dataLogF("Clearing LLInt put transition.\n");
metadata.m_oldStructureID = 0;
@@ -1263,16 +1241,11 @@
metadata.m_offset = 0;
metadata.m_newStructureID = 0;
metadata.m_structureChain.clear();
- break;
- }
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=166418
- // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution.
- case op_resolve_scope_for_hoisting_func_decl_in_eval:
- break;
- case op_to_this: {
- auto& metadata = curInstruction->as<OpToThis>().metadata(this);
+ });
+
+ m_metadata->forEach<OpToThis>([&] (auto& metadata) {
if (!metadata.m_cachedStructureID || vm.heap.isMarked(vm.heap.structureIDTable().get(metadata.m_cachedStructureID)))
- break;
+ return;
if (Options::verboseOSR()) {
Structure* structure = vm.heap.structureIDTable().get(metadata.m_cachedStructureID);
dataLogF("Clearing LLInt to_this with structure %p.\n", structure);
@@ -1279,57 +1252,53 @@
}
metadata.m_cachedStructureID = 0;
metadata.m_toThisStatus = merge(metadata.m_toThisStatus, ToThisClearedByGC);
- break;
- }
- case op_create_this: {
- auto& metadata = curInstruction->as<OpCreateThis>().metadata(this);
+ });
+
+ auto handleCreateBytecode = [&] (auto& metadata, ASCIILiteral name) {
auto& cacheWriteBarrier = metadata.m_cachedCallee;
if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
- break;
+ return;
JSCell* cachedFunction = cacheWriteBarrier.get();
if (vm.heap.isMarked(cachedFunction))
- break;
- if (Options::verboseOSR())
- dataLogF("Clearing LLInt create_this with cached callee %p.\n", cachedFunction);
+ return;
+ dataLogLnIf(Options::verboseOSR(), "Clearing LLInt ", name, " with cached callee ", RawPointer(cachedFunction), ".");
cacheWriteBarrier.clear();
- break;
- }
- case op_create_promise: {
- auto& metadata = curInstruction->as<OpCreatePromise>().metadata(this);
- auto& cacheWriteBarrier = metadata.m_cachedCallee;
- if (!cacheWriteBarrier || cacheWriteBarrier.unvalidatedGet() == JSCell::seenMultipleCalleeObjects())
- break;
- JSCell* cachedFunction = cacheWriteBarrier.get();
- if (vm.heap.isMarked(cachedFunction))
- break;
- if (Options::verboseOSR())
- dataLogF("Clearing LLInt create_promise with cached callee %p.\n", cachedFunction);
- cacheWriteBarrier.clear();
- break;
- }
- case op_resolve_scope: {
+ };
+
+ m_metadata->forEach<OpCreateThis>([&] (auto& metadata) {
+ handleCreateBytecode(metadata, "op_create_this"_s);
+ });
+ m_metadata->forEach<OpCreatePromise>([&] (auto& metadata) {
+ handleCreateBytecode(metadata, "op_create_promise"_s);
+ });
+
+ m_metadata->forEach<OpResolveScope>([&] (auto& metadata) {
// Right now this isn't strictly necessary. Any symbol tables that this will refer to
// are for outer functions, and we refer to those functions strongly, and they refer
// to the symbol table strongly. But it's nice to be on the safe side.
- auto& metadata = curInstruction->as<OpResolveScope>().metadata(this);
WriteBarrierBase<SymbolTable>& symbolTable = metadata.m_symbolTable;
if (!symbolTable || vm.heap.isMarked(symbolTable.get()))
- break;
+ return;
if (Options::verboseOSR())
dataLogF("Clearing dead symbolTable %p.\n", symbolTable.get());
symbolTable.clear();
- break;
- }
- case op_get_from_scope:
- handleGetPutFromScope(curInstruction->as<OpGetFromScope>().metadata(this));
- break;
- case op_put_to_scope:
- handleGetPutFromScope(curInstruction->as<OpPutToScope>().metadata(this));
- break;
- default:
- OpcodeID opcodeID = curInstruction->opcodeID();
- ASSERT_WITH_MESSAGE_UNUSED(opcodeID, false, "Unhandled opcode in CodeBlock::finalizeUnconditionally, %s(%d) at bc %u", opcodeNames[opcodeID], opcodeID, propertyAccessInstructions[i]);
- }
+ });
+
+ auto handleGetPutFromScope = [&] (auto& metadata) {
+ GetPutInfo getPutInfo = metadata.m_getPutInfo;
+ if (getPutInfo.resolveType() == GlobalVar || getPutInfo.resolveType() == GlobalVarWithVarInjectionChecks
+ || getPutInfo.resolveType() == LocalClosureVar || getPutInfo.resolveType() == GlobalLexicalVar || getPutInfo.resolveType() == GlobalLexicalVarWithVarInjectionChecks)
+ return;
+ WriteBarrierBase<Structure>& structure = metadata.m_structure;
+ if (!structure || vm.heap.isMarked(structure.get()))
+ return;
+ if (Options::verboseOSR())
+ dataLogF("Clearing scope access with structure %p.\n", structure.get());
+ structure.clear();
+ };
+
+ m_metadata->forEach<OpGetFromScope>(handleGetPutFromScope);
+ m_metadata->forEach<OpPutToScope>(handleGetPutFromScope);
}
// We can't just remove all the sets when we clear the caches since we might have created a watchpoint set
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp (249667 => 249668)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.cpp 2019-09-09 21:38:17 UTC (rev 249668)
@@ -363,9 +363,6 @@
}
}
- for (size_t i = 0; i < m_propertyAccessInstructions.size(); ++i)
- m_propertyAccessInstructions[i] = rewriter.adjustAbsoluteOffset(m_propertyAccessInstructions[i]);
-
for (size_t i = 0; i < m_expressionInfo.size(); ++i)
m_expressionInfo[i].instructionOffset = rewriter.adjustAbsoluteOffset(m_expressionInfo[i].instructionOffset);
@@ -382,7 +379,6 @@
auto locker = holdLock(cellLock());
m_jumpTargets.shrinkToFit();
- m_propertyAccessInstructions.shrinkToFit();
m_identifiers.shrinkToFit();
m_constantRegisters.shrinkToFit();
m_constantsSourceCodeRepresentation.shrinkToFit();
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (249667 => 249668)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2019-09-09 21:38:17 UTC (rev 249668)
@@ -277,14 +277,6 @@
VirtualRegister thisRegister() const { return m_thisRegister; }
VirtualRegister scopeRegister() const { return m_scopeRegister; }
- void addPropertyAccessInstruction(InstructionStream::Offset propertyAccessInstruction)
- {
- m_propertyAccessInstructions.append(propertyAccessInstruction);
- }
-
- size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
- const Vector<InstructionStream::Offset>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
-
bool hasRareData() const { return m_rareData.get(); }
int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
@@ -459,9 +451,6 @@
DFG::ExitProfile m_exitProfile;
#endif
-
- Vector<InstructionStream::Offset> m_propertyAccessInstructions;
-
// Constant Pools
Vector<Identifier> m_identifiers;
Vector<WriteBarrier<Unknown>> m_constantRegisters;
Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (249667 => 249668)
--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp 2019-09-09 21:38:17 UTC (rev 249668)
@@ -2496,7 +2496,6 @@
dst = tempDestination(dst);
OpResolveScope::emit(this, kill(dst), scopeRegister(), addConstant(variable.ident()), resolveType(), localScopeDepth());
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return dst;
}
@@ -2525,7 +2524,6 @@
GetPutInfo(resolveMode, variable.offset().isScope() ? LocalClosureVar : resolveType(), InitializationMode::NotInitialization),
localScopeDepth(),
variable.offset().isScope() ? variable.offset().scopeOffset().offset() : 0);
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return dst;
} }
@@ -2558,7 +2556,6 @@
symbolTableOrScopeDepth = SymbolTableOrScopeDepth::scopeDepth(localScopeDepth());
}
OpPutToScope::emit(this, scope, addConstant(variable.ident()), value, getPutInfo, symbolTableOrScopeDepth, !!offset ? offset.offset() : 0);
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return value;
} }
@@ -2609,7 +2606,6 @@
ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val.");
OpGetById::emit(this, kill(dst), base, addConstant(property));
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return dst;
}
@@ -2626,7 +2622,6 @@
ASSERT_WITH_MESSAGE(!parseIndex(property), "Indexed properties should be handled with get_by_val_direct.");
OpGetByIdDirect::emit(this, kill(dst), base, addConstant(property));
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return dst;
}
@@ -2639,8 +2634,6 @@
m_staticPropertyAnalyzer.putById(base, propertyIndex);
OpPutById::emit(this, base, propertyIndex, value, PutByIdNone); // is not direct
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
-
return value;
}
@@ -2665,7 +2658,6 @@
PutByIdFlags type = (putType == PropertyNode::KnownDirect || property != m_vm.propertyNames->underscoreProto) ? PutByIdIsDirect : PutByIdNone;
OpPutById::emit(this, base, propertyIndex, value, type);
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return value;
}
@@ -2851,8 +2843,6 @@
{
OpCreateThis::emit(this, dst, dst, 0);
m_staticPropertyAnalyzer.createThis(dst, m_lastInstruction);
-
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
return dst;
}
@@ -5134,7 +5124,6 @@
void BytecodeGenerator::emitToThis()
{
OpToThis::emit(this, kill(&m_thisRegister));
- m_codeBlock->addPropertyAccessInstruction(m_lastInstruction.offset());
}
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (249667 => 249668)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-09-09 21:20:59 UTC (rev 249667)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-09-09 21:38:17 UTC (rev 249668)
@@ -1838,7 +1838,6 @@
CachedPtr<CachedInstructionStream> m_instructions;
CachedVector<InstructionStream::Offset> m_jumpTargets;
- CachedVector<InstructionStream::Offset> m_propertyAccessInstructions;
CachedVector<CachedJSValue> m_constantRegisters;
CachedVector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation;
CachedVector<ExpressionRangeInfo> m_expressionInfo;
@@ -2043,7 +2042,6 @@
for (unsigned i = LinkTimeConstantCount; i--;)
codeBlock.m_linkTimeConstants[i] = m_linkTimeConstants[i];
- m_propertyAccessInstructions.decode(decoder, codeBlock.m_propertyAccessInstructions);
m_constantRegisters.decode(decoder, codeBlock.m_constantRegisters, &codeBlock);
m_constantsSourceCodeRepresentation.decode(decoder, codeBlock.m_constantsSourceCodeRepresentation);
m_expressionInfo.decode(decoder, codeBlock.m_expressionInfo);
@@ -2219,7 +2217,6 @@
m_sourceMappingURLDirective.encode(encoder, codeBlock.m_sourceURLDirective.impl());
m_instructions.encode(encoder, codeBlock.m_instructions.get());
- m_propertyAccessInstructions.encode(encoder, codeBlock.m_propertyAccessInstructions);
m_constantRegisters.encode(encoder, codeBlock.m_constantRegisters);
m_constantsSourceCodeRepresentation.encode(encoder, codeBlock.m_constantsSourceCodeRepresentation);
m_expressionInfo.encode(encoder, codeBlock.m_expressionInfo);