Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (246072 => 246073)
--- trunk/Source/_javascript_Core/ChangeLog 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-06-04 18:27:59 UTC (rev 246073)
@@ -1,3 +1,109 @@
+2019-06-04 Yusuke Suzuki <[email protected]>
+
+ [JSC] InferredValue should not be a JSCell
+ https://bugs.webkit.org/show_bug.cgi?id=198407
+
+ Reviewed by Filip Pizlo.
+
+ Allocating InferredValue as a JSCell is too costly in terms of memory. Gmail has 90000 FunctionExecutables. And each gets
+ InferredValue, which takes 32 bytes. So it takes 2.7 MB memory footprint.
+
+ In this patch, we introduce a new container InferredValue<>. Which is similar to WriteBarrier<> container, but it replaces
+ the existing InferredValue cells with one pointer size field. The implementation of InferredValue<> is similar to
+ InlineWatchpointSet. But we encode JSCell* too to the pointer data of InlineWatchpointSet. So sizeof(InferredValue<>) is one
+ pointer size while it keeps Watchpoint feature and JSCell holder feature.
+
+ InferredValue<> needs validation in GC finalize phase. So this patch also makes SymbolTable Iso-allocated.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * Sources.txt:
+ * bytecode/ObjectAllocationProfileInlines.h:
+ (JSC::ObjectAllocationProfileBase<Derived>::initializeProfile):
+ * bytecode/Watchpoint.h:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::get):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGClobbersExitState.cpp:
+ (JSC::DFG::clobbersExitState):
+ * dfg/DFGDesiredWatchpoints.cpp:
+ (JSC::DFG::SymbolTableAdaptor::add):
+ (JSC::DFG::FunctionExecutableAdaptor::add):
+ (JSC::DFG::DesiredWatchpoints::addLazily):
+ (JSC::DFG::DesiredWatchpoints::reallyAdd):
+ (JSC::DFG::DesiredWatchpoints::areStillValid const):
+ (JSC::DFG::DesiredWatchpoints::dumpInContext const):
+ (JSC::DFG::InferredValueAdaptor::add): Deleted.
+ * dfg/DFGDesiredWatchpoints.h:
+ (JSC::DFG::SymbolTableAdaptor::hasBeenInvalidated):
+ (JSC::DFG::SymbolTableAdaptor::dumpInContext):
+ (JSC::DFG::FunctionExecutableAdaptor::hasBeenInvalidated):
+ (JSC::DFG::FunctionExecutableAdaptor::dumpInContext):
+ (JSC::DFG::DesiredWatchpoints::isWatched):
+ (JSC::DFG::InferredValueAdaptor::hasBeenInvalidated): Deleted.
+ (JSC::DFG::InferredValueAdaptor::dumpInContext): Deleted.
+ * dfg/DFGObjectAllocationSinkingPhase.cpp:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileNewFunction):
+ (JSC::DFG::SpeculativeJIT::compileCreateActivation):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileCreateActivation):
+ (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction):
+ * heap/Heap.cpp:
+ (JSC::Heap::finalizeUnconditionalFinalizers):
+ * runtime/FunctionExecutable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ (JSC::FunctionExecutable::finishCreation):
+ (JSC::FunctionExecutable::visitChildren):
+ * runtime/FunctionExecutable.h:
+ * runtime/FunctionExecutableInlines.h: Copied from Source/_javascript_Core/runtime/InferredValueInlines.h.
+ (JSC::FunctionExecutable::finalizeUnconditionally):
+ * runtime/InferredValue.cpp: Removed.
+ * runtime/InferredValue.h:
+ (JSC::InferredValue::inferredValue):
+ (JSC::InferredValue::InferredValue):
+ (JSC::InferredValue::~InferredValue):
+ (JSC::InferredValue::stateOnJSThread const):
+ (JSC::InferredValue::state const):
+ (JSC::InferredValue::hasBeenInvalidated const):
+ (JSC::InferredValue::isStillValid const):
+ (JSC::InferredValue::invalidate):
+ (JSC::InferredValue::isBeingWatched const):
+ (JSC::InferredValue::notifyWrite):
+ (JSC::InferredValue::isThin):
+ (JSC::InferredValue::isFat):
+ (JSC::InferredValue::decodeState):
+ (JSC::InferredValue::encodeState):
+ (JSC::InferredValue::isThin const):
+ (JSC::InferredValue::isFat const):
+ (JSC::InferredValue::fat):
+ (JSC::InferredValue::fat const):
+ (JSC::InferredValue::inflate):
+ (JSC::InferredValue<JSCellType>::InferredValueWatchpointSet::notifyWriteSlow):
+ (JSC::InferredValue<JSCellType>::notifyWriteSlow):
+ (JSC::InferredValue<JSCellType>::add):
+ (JSC::InferredValue<JSCellType>::inflateSlow):
+ (JSC::InferredValue<JSCellType>::freeFat):
+ * runtime/InferredValueInlines.h:
+ (JSC::InferredValue<JSCellType>::finalizeUnconditionally):
+ (JSC::InferredValue::finalizeUnconditionally): Deleted.
+ * runtime/JSFunctionInlines.h:
+ (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
+ * runtime/JSSymbolTableObject.h:
+ (JSC::JSSymbolTableObject::setSymbolTable):
+ * runtime/SymbolTable.cpp:
+ (JSC::SymbolTable::finishCreation):
+ (JSC::SymbolTable::visitChildren):
+ * runtime/SymbolTable.h:
+ * runtime/SymbolTableInlines.h: Copied from Source/_javascript_Core/runtime/InferredValueInlines.h.
+ (JSC::SymbolTable::finalizeUnconditionally):
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ * runtime/VM.h:
+
2019-06-04 Tadeu Zagallo <[email protected]>
Argument elimination should check for negative indices in GetByVal
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (246072 => 246073)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-06-04 18:27:59 UTC (rev 246073)
@@ -1774,6 +1774,7 @@
E33F50811B8429A400413856 /* JSInternalPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F507F1B8429A400413856 /* JSInternalPromise.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50851B8437A000413856 /* JSInternalPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50831B8437A000413856 /* JSInternalPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */; };
+ E3400EC122A1CC7B009DED54 /* FunctionExecutableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */; };
E34E657520668EAA00FB81AC /* ParseHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E34E657320668E8D00FB81AC /* ParseHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1792,6 +1793,7 @@
E38D999C221B78BB00D50474 /* JSNonDestructibleProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = E38D999A221B789F00D50474 /* JSNonDestructibleProxy.h */; settings = {ATTRIBUTES = (Private, ); }; };
E39006212208BFC4001019CF /* SubspaceAccess.h in Headers */ = {isa = PBXBuildFile; fileRef = E39006202208BFC3001019CF /* SubspaceAccess.h */; settings = {ATTRIBUTES = (Private, ); }; };
E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */; };
+ E39BF39922A2288B00BD183E /* SymbolTableInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39BF39822A2288B00BD183E /* SymbolTableInlines.h */; };
E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
E39EEAF322812450008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E39EEAF22281244C008474F4 /* ObjectToStringAdaptiveStructureWatchpoint.h */; };
@@ -3133,7 +3135,6 @@
0FF729A0166AD347000F5BA3 /* ProfilerOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOrigin.h; path = profiler/ProfilerOrigin.h; sourceTree = "<group>"; };
0FF729A1166AD347000F5BA3 /* ProfilerOriginStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerOriginStack.cpp; path = profiler/ProfilerOriginStack.cpp; sourceTree = "<group>"; };
0FF729A2166AD347000F5BA3 /* ProfilerOriginStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerOriginStack.h; path = profiler/ProfilerOriginStack.h; sourceTree = "<group>"; };
- 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InferredValue.cpp; sourceTree = "<group>"; };
0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InferredValue.h; sourceTree = "<group>"; };
0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = JSCLLIntOffsetsExtractor; sourceTree = BUILT_PRODUCTS_DIR; };
0FF9CE711B9CD6D0004EDCA6 /* PolymorphicAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PolymorphicAccess.cpp; sourceTree = "<group>"; };
@@ -4772,6 +4773,7 @@
E33F50831B8437A000413856 /* JSInternalPromiseDeferred.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromiseDeferred.h; sourceTree = "<group>"; };
E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromiseConstructor.lut.h; sourceTree = "<group>"; };
E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = InternalPromiseConstructor.js; sourceTree = "<group>"; };
+ E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FunctionExecutableInlines.h; sourceTree = "<group>"; };
E34E657320668E8D00FB81AC /* ParseHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParseHash.h; sourceTree = "<group>"; };
E34E657420668E8E00FB81AC /* ParseHash.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParseHash.cpp; sourceTree = "<group>"; };
E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameTracers.h; sourceTree = "<group>"; };
@@ -4804,6 +4806,7 @@
E39006202208BFC3001019CF /* SubspaceAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SubspaceAccess.h; sourceTree = "<group>"; };
E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakMapImplInlines.h; sourceTree = "<group>"; };
E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodesAnalyzeModule.cpp; sourceTree = "<group>"; };
+ E39BF39822A2288B00BD183E /* SymbolTableInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolTableInlines.h; sourceTree = "<group>"; };
E39D9D841D39000600667282 /* InterpreterInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterpreterInlines.h; sourceTree = "<group>"; };
E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = "<group>"; };
E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; };
@@ -6872,6 +6875,7 @@
147341D71DC02F9900AA29BA /* FunctionExecutable.h */,
0FB4B52116B6278D003F696B /* FunctionExecutableDump.cpp */,
0FB4B52216B6278D003F696B /* FunctionExecutableDump.h */,
+ E3400EC022A1CC78009DED54 /* FunctionExecutableInlines.h */,
52B310FC1974AE870080857C /* FunctionHasExecutedCache.cpp */,
52B310FA1974AE610080857C /* FunctionHasExecutedCache.h */,
F692A85C0255597D01FF60F7 /* FunctionPrototype.cpp */,
@@ -6909,7 +6913,6 @@
0FB7F38F15ED8E3800F167B2 /* IndexingType.h */,
14386A761DD6989C008652C4 /* IndirectEvalExecutable.cpp */,
14386A771DD6989C008652C4 /* IndirectEvalExecutable.h */,
- 0FF8BDE81AD4CF7100DFE884 /* InferredValue.cpp */,
0FF8BDE91AD4CF7100DFE884 /* InferredValue.h */,
0F4AE0421FE0D25400E20839 /* InferredValueInlines.h */,
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */,
@@ -7317,6 +7320,7 @@
705B41AA1A6E501E00716757 /* SymbolPrototype.h */,
0F919D2715856770004A4E7D /* SymbolTable.cpp */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+ E39BF39822A2288B00BD183E /* SymbolTableInlines.h */,
E31179A92288385D00514B2C /* SymbolTableOrScopeDepth.h */,
BDB4B5E099CD4C1BB3C1CF05 /* TemplateObjectDescriptor.cpp */,
70ECA6041AFDBEA200449739 /* TemplateObjectDescriptor.h */,
@@ -9184,6 +9188,7 @@
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
147341D81DC02F9900AA29BA /* FunctionExecutable.h in Headers */,
0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
+ E3400EC122A1CC7B009DED54 /* FunctionExecutableInlines.h in Headers */,
52B310FB1974AE610080857C /* FunctionHasExecutedCache.h in Headers */,
FE4BFF2C1AD476E700088F87 /* FunctionOverrides.h in Headers */,
BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
@@ -9880,6 +9885,7 @@
705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */,
BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
+ E39BF39922A2288B00BD183E /* SymbolTableInlines.h in Headers */,
E31179AA2288386100514B2C /* SymbolTableOrScopeDepth.h in Headers */,
0FD79A2D1EBBBDBB00DA88D3 /* Synchronousness.h in Headers */,
0F1FB38F1E173A6700A9BE50 /* SynchronousStopTheWorldMutatorScheduler.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (246072 => 246073)
--- trunk/Source/_javascript_Core/Sources.txt 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/Sources.txt 2019-06-04 18:27:59 UTC (rev 246073)
@@ -784,7 +784,6 @@
runtime/Identifier.cpp
runtime/IndexingType.cpp
runtime/IndirectEvalExecutable.cpp
-runtime/InferredValue.cpp
runtime/InitializeThreading.cpp
runtime/InspectorInstrumentationObject.cpp
runtime/InternalFunction.cpp
Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h (246072 => 246073)
--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -63,7 +63,7 @@
if (Options::forcePolyProto())
isPolyProto = true;
else
- isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunctionHasBeenInvalidated();
+ isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singleton().hasBeenInvalidated();
}
unsigned inlineCapacity = 0;
Modified: trunk/Source/_javascript_Core/bytecode/Watchpoint.h (246072 => 246073)
--- trunk/Source/_javascript_Core/bytecode/Watchpoint.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/bytecode/Watchpoint.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -161,10 +161,11 @@
Type m_type;
};
-enum WatchpointState {
- ClearWatchpoint,
- IsWatched,
- IsInvalidated
+// Make sure that the state can be represented in 2 bits.
+enum WatchpointState : uint8_t {
+ ClearWatchpoint = 0,
+ IsWatched = 1,
+ IsInvalidated = 2
};
class InlineWatchpointSet;
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -2762,10 +2762,8 @@
case GetCallee:
if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(m_vm, m_codeBlock->ownerExecutable())) {
- InferredValue* singleton = executable->singletonFunction();
- if (JSValue value = singleton->inferredValue()) {
- m_graph.watchpoints().addLazily(singleton);
- JSFunction* function = jsCast<JSFunction*>(value);
+ if (JSFunction* function = executable->singleton().inferredValue()) {
+ m_graph.watchpoints().addLazily(executable);
setConstant(node, *m_graph.freeze(function));
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -321,10 +321,8 @@
// that we don't have such watchpoint-based folding for inlined uses of Callee, since in that
// case if the function is a singleton then we already know it.
if (FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(*m_vm, m_codeBlock->ownerExecutable())) {
- InferredValue* singleton = executable->singletonFunction();
- if (JSValue value = singleton->inferredValue()) {
- m_graph.watchpoints().addLazily(singleton);
- JSFunction* function = jsCast<JSFunction*>(value);
+ if (JSFunction* function = executable->singleton().inferredValue()) {
+ m_graph.watchpoints().addLazily(executable);
return weakJSConstant(function);
}
}
@@ -6276,11 +6274,11 @@
// We have various forms of constant folding here. This is necessary to avoid
// spurious recompiles in dead-but-foldable code.
+
if (symbolTable) {
- InferredValue* singleton = symbolTable->singletonScope();
- if (JSValue value = singleton->inferredValue()) {
- m_graph.watchpoints().addLazily(singleton);
- set(bytecode.m_dst, weakJSConstant(value));
+ if (JSScope* scope = symbolTable->singleton().inferredValue()) {
+ m_graph.watchpoints().addLazily(symbolTable);
+ set(bytecode.m_dst, weakJSConstant(scope));
break;
}
}
@@ -6311,7 +6309,6 @@
case op_resolve_scope_for_hoisting_func_decl_in_eval: {
auto bytecode = currentInstruction->as<OpResolveScopeForHoistingFuncDeclInEval>();
unsigned identifierNumber = m_inlineStackTop->m_identifierRemap[bytecode.m_property];
-
set(bytecode.m_dst, addToGraph(ResolveScopeForHoistingFuncDeclInEval, OpInfo(identifierNumber), get(bytecode.m_scope)));
NEXT_OPCODE(op_resolve_scope_for_hoisting_func_decl_in_eval);
Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -514,7 +514,7 @@
case CreateActivation: {
SymbolTable* table = node->castOperand<SymbolTable*>();
- if (table->singletonScope()->isStillValid())
+ if (table->singleton().isStillValid())
write(Watchpoint_fire);
read(HeapObjectCount);
write(HeapObjectCount);
@@ -1568,7 +1568,7 @@
case NewGeneratorFunction:
case NewAsyncGeneratorFunction:
case NewAsyncFunction:
- if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid())
+ if (node->castOperand<FunctionExecutable*>()->singleton().isStillValid())
write(Watchpoint_fire);
read(HeapObjectCount);
write(HeapObjectCount);
Modified: trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGClobbersExitState.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -87,7 +87,7 @@
case CreateActivation:
// Like above, but with the activation allocation caveat.
- return node->castOperand<SymbolTable*>()->singletonScope()->isStillValid();
+ return node->castOperand<SymbolTable*>()->singleton().isStillValid();
case NewFunction:
case NewGeneratorFunction:
@@ -94,7 +94,7 @@
case NewAsyncGeneratorFunction:
case NewAsyncFunction:
// Like above, but with the JSFunction allocation caveat.
- return node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid();
+ return node->castOperand<FunctionExecutable*>()->singleton().isStillValid();
default:
// For all other nodes, we just care about whether they write to something other than SideState.
Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -48,13 +48,20 @@
vm.heap.addReference(neuteringWatchpoint, view->possiblySharedBuffer());
}
-void InferredValueAdaptor::add(
- CodeBlock* codeBlock, InferredValue* inferredValue, CommonData& common)
+void SymbolTableAdaptor::add(
+ CodeBlock* codeBlock, SymbolTable* symbolTable, CommonData& common)
{
- codeBlock->addConstant(inferredValue); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
- inferredValue->add(common.watchpoints.add(codeBlock));
+ codeBlock->addConstant(symbolTable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
+ symbolTable->singleton().add(common.watchpoints.add(codeBlock));
}
+void FunctionExecutableAdaptor::add(
+ CodeBlock* codeBlock, FunctionExecutable* executable, CommonData& common)
+{
+ codeBlock->addConstant(executable); // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
+ executable->singleton().add(common.watchpoints.add(codeBlock));
+}
+
void AdaptiveStructureWatchpointAdaptor::add(
CodeBlock* codeBlock, const ObjectPropertyCondition& key, CommonData& common)
{
@@ -82,11 +89,16 @@
m_inlineSets.addLazily(&set);
}
-void DesiredWatchpoints::addLazily(InferredValue* inferredValue)
+void DesiredWatchpoints::addLazily(SymbolTable* symbolTable)
{
- m_inferredValues.addLazily(inferredValue);
+ m_symbolTables.addLazily(symbolTable);
}
+void DesiredWatchpoints::addLazily(FunctionExecutable* executable)
+{
+ m_functionExecutables.addLazily(executable);
+}
+
void DesiredWatchpoints::addLazily(JSArrayBufferView* view)
{
m_bufferViews.addLazily(view);
@@ -109,7 +121,8 @@
{
m_sets.reallyAdd(codeBlock, commonData);
m_inlineSets.reallyAdd(codeBlock, commonData);
- m_inferredValues.reallyAdd(codeBlock, commonData);
+ m_symbolTables.reallyAdd(codeBlock, commonData);
+ m_functionExecutables.reallyAdd(codeBlock, commonData);
m_bufferViews.reallyAdd(codeBlock, commonData);
m_adaptiveStructureSets.reallyAdd(codeBlock, commonData);
}
@@ -118,7 +131,8 @@
{
return m_sets.areStillValid()
&& m_inlineSets.areStillValid()
- && m_inferredValues.areStillValid()
+ && m_symbolTables.areStillValid()
+ && m_functionExecutables.areStillValid()
&& m_bufferViews.areStillValid()
&& m_adaptiveStructureSets.areStillValid();
}
@@ -128,7 +142,8 @@
out.print("Desired watchpoints:\n");
out.print(" Watchpoint sets: ", inContext(m_sets, context), "\n");
out.print(" Inline watchpoint sets: ", inContext(m_inlineSets, context), "\n");
- out.print(" Inferred values: ", inContext(m_inferredValues, context), "\n");
+ out.print(" SymbolTables: ", inContext(m_symbolTables, context), "\n");
+ out.print(" FunctionExecutables: ", inContext(m_functionExecutables, context), "\n");
out.print(" Buffer views: ", inContext(m_bufferViews, context), "\n");
out.print(" Object property conditions: ", inContext(m_adaptiveStructureSets, context), "\n");
}
Modified: trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGDesiredWatchpoints.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -28,9 +28,10 @@
#if ENABLE(DFG_JIT)
#include "DFGCommonData.h"
-#include "InferredValue.h"
+#include "FunctionExecutable.h"
#include "JSArrayBufferView.h"
#include "ObjectPropertyCondition.h"
+#include "SymbolTable.h"
#include "Watchpoint.h"
#include <wtf/CommaPrinter.h>
#include <wtf/HashSet.h>
@@ -55,18 +56,30 @@
}
};
-struct InferredValueAdaptor {
- static void add(CodeBlock*, InferredValue*, CommonData&);
- static bool hasBeenInvalidated(InferredValue* inferredValue)
+struct SymbolTableAdaptor {
+ static void add(CodeBlock*, SymbolTable*, CommonData&);
+ static bool hasBeenInvalidated(SymbolTable* symbolTable)
{
- return inferredValue->hasBeenInvalidated();
+ return symbolTable->singleton().hasBeenInvalidated();
}
- static void dumpInContext(PrintStream& out, InferredValue* inferredValue, DumpContext*)
+ static void dumpInContext(PrintStream& out, SymbolTable* symbolTable, DumpContext*)
{
- out.print(RawPointer(inferredValue));
+ out.print(RawPointer(symbolTable));
}
};
+struct FunctionExecutableAdaptor {
+ static void add(CodeBlock*, FunctionExecutable*, CommonData&);
+ static bool hasBeenInvalidated(FunctionExecutable* executable)
+ {
+ return executable->singleton().hasBeenInvalidated();
+ }
+ static void dumpInContext(PrintStream& out, FunctionExecutable* executable, DumpContext*)
+ {
+ out.print(RawPointer(executable));
+ }
+};
+
struct ArrayBufferViewWatchpointAdaptor {
static void add(CodeBlock*, JSArrayBufferView*, CommonData&);
static bool hasBeenInvalidated(JSArrayBufferView* view)
@@ -154,7 +167,8 @@
void addLazily(WatchpointSet*);
void addLazily(InlineWatchpointSet&);
- void addLazily(InferredValue*);
+ void addLazily(SymbolTable*);
+ void addLazily(FunctionExecutable*);
void addLazily(JSArrayBufferView*);
// It's recommended that you don't call this directly. Use Graph::watchCondition(), which does
@@ -175,10 +189,14 @@
{
return m_inlineSets.isWatched(&set);
}
- bool isWatched(InferredValue* inferredValue)
+ bool isWatched(SymbolTable* symbolTable)
{
- return m_inferredValues.isWatched(inferredValue);
+ return m_symbolTables.isWatched(symbolTable);
}
+ bool isWatched(FunctionExecutable* executable)
+ {
+ return m_functionExecutables.isWatched(executable);
+ }
bool isWatched(JSArrayBufferView* view)
{
return m_bufferViews.isWatched(view);
@@ -193,7 +211,8 @@
private:
GenericDesiredWatchpoints<WatchpointSet*> m_sets;
GenericDesiredWatchpoints<InlineWatchpointSet*> m_inlineSets;
- GenericDesiredWatchpoints<InferredValue*, InferredValueAdaptor> m_inferredValues;
+ GenericDesiredWatchpoints<SymbolTable*, SymbolTableAdaptor> m_symbolTables;
+ GenericDesiredWatchpoints<FunctionExecutable*, FunctionExecutableAdaptor> m_functionExecutables;
GenericDesiredWatchpoints<JSArrayBufferView*, ArrayBufferViewWatchpointAdaptor> m_bufferViews;
GenericDesiredWatchpoints<ObjectPropertyCondition, AdaptiveStructureWatchpointAdaptor> m_adaptiveStructureSets;
};
Modified: trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGObjectAllocationSinkingPhase.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -840,7 +840,7 @@
case NewGeneratorFunction:
case NewAsyncGeneratorFunction:
case NewAsyncFunction: {
- if (isStillValid(node->castOperand<FunctionExecutable*>()->singletonFunction())) {
+ if (isStillValid(node->castOperand<FunctionExecutable*>())) {
m_heap.escape(node->child1().node());
break;
}
@@ -868,7 +868,7 @@
}
case CreateActivation: {
- if (isStillValid(node->castOperand<SymbolTable*>()->singletonScope())) {
+ if (isStillValid(node->castOperand<SymbolTable*>())) {
m_heap.escape(node->child1().node());
break;
}
@@ -2382,11 +2382,17 @@
// different answers. It turns out that this analysis works OK regardless of what this
// returns but breaks badly if this changes its mind for any particular InferredValue. This
// method protects us from that.
- bool isStillValid(InferredValue* value)
+ bool isStillValid(SymbolTable* value)
{
- return m_validInferredValues.add(value, value->isStillValid()).iterator->value;
+ return m_validInferredValues.add(value, value->singleton().isStillValid()).iterator->value;
}
+ bool isStillValid(FunctionExecutable* value)
+ {
+ return m_validInferredValues.add(value, value->singleton().isStillValid()).iterator->value;
+ }
+
+
SSACalculator m_pointerSSA;
SSACalculator m_allocationSSA;
NodeSet m_sinkCandidates;
@@ -2397,7 +2403,7 @@
InsertionSet m_insertionSet;
CombinedLiveness m_combinedLiveness;
- HashMap<InferredValue*, bool> m_validInferredValues;
+ HashMap<JSCell*, bool> m_validInferredValues;
HashMap<Node*, Node*> m_materializationToEscapee;
HashMap<Node*, Vector<Node*>> m_materializationSiteToMaterializations;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -7193,7 +7193,7 @@
FunctionExecutable* executable = node->castOperand<FunctionExecutable*>();
- if (executable->singletonFunction()->isStillValid()) {
+ if (executable->singleton().isStillValid()) {
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
@@ -7410,7 +7410,7 @@
JSValue initializationValue = node->initializationValueForActivation();
ASSERT(initializationValue == jsUndefined() || initializationValue == jsTDZValue());
- if (table->singletonScope()->isStillValid()) {
+ if (table->singleton().isStillValid()) {
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -5441,7 +5441,7 @@
RegisteredStructure structure = m_graph.registerStructure(m_graph.globalObjectFor(m_node->origin.semantic)->activationStructure());
JSValue initializationValue = m_node->initializationValueForActivation();
ASSERT(initializationValue.isUndefined() || initializationValue == jsTDZValue());
- if (table->singletonScope()->isStillValid()) {
+ if (table->singleton().isStillValid()) {
LValue callResult = vmCall(
Int64,
m_out.operation(operationCreateActivationDirect), m_callFrame, weakStructure(structure),
@@ -5502,7 +5502,7 @@
LValue scope = lowCell(m_node->child1());
FunctionExecutable* executable = m_node->castOperand<FunctionExecutable*>();
- if (executable->singletonFunction()->isStillValid()) {
+ if (executable->singleton().isStillValid()) {
LValue callResult =
isGeneratorFunction ? vmCall(Int64, m_out.operation(operationNewGeneratorFunction), m_callFrame, scope, weakPointer(executable)) :
isAsyncFunction ? vmCall(Int64, m_out.operation(operationNewAsyncFunction), m_callFrame, scope, weakPointer(executable)) :
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -31,6 +31,7 @@
#include "EdenGCActivityCallback.h"
#include "Exception.h"
#include "FullGCActivityCallback.h"
+#include "FunctionExecutableInlines.h"
#include "GCActivityCallback.h"
#include "GCIncomingRefCountedSetInlines.h"
#include "GCSegmentedArrayInlines.h"
@@ -67,6 +68,7 @@
#include "SubspaceInlines.h"
#include "SuperSampler.h"
#include "SweepingScope.h"
+#include "SymbolTableInlines.h"
#include "SynchronousStopTheWorldMutatorScheduler.h"
#include "TypeProfiler.h"
#include "TypeProfilerLog.h"
@@ -596,8 +598,8 @@
void Heap::finalizeUnconditionalFinalizers()
{
vm()->builtinExecutables()->finalizeUnconditionally();
- if (vm()->m_inferredValueSpace)
- finalizeMarkedUnconditionalFinalizers<InferredValue>(vm()->m_inferredValueSpace->space);
+ finalizeMarkedUnconditionalFinalizers<FunctionExecutable>(vm()->functionExecutableSpace.space);
+ finalizeMarkedUnconditionalFinalizers<SymbolTable>(vm()->symbolTableSpace);
vm()->forEachCodeBlockSpace(
[&] (auto& space) {
this->finalizeMarkedUnconditionalFinalizers<CodeBlock>(space.set);
Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -48,10 +48,6 @@
{
RELEASE_ASSERT(!source.isNull());
ASSERT(source.length());
- if (VM::canUseJIT())
- new (&m_singletonFunction) WriteBarrier<InferredValue>();
- else
- m_singletonFunctionState = ClearWatchpoint;
}
void FunctionExecutable::finishCreation(VM& vm, ScriptExecutable* topLevelExecutable)
@@ -58,8 +54,6 @@
{
Base::finishCreation(vm);
m_topLevelExecutable.set(vm, this, topLevelExecutable ? topLevelExecutable : this);
- if (VM::canUseJIT())
- m_singletonFunction.set(vm, this, InferredValue::create(vm));
}
void FunctionExecutable::destroy(JSCell* cell)
@@ -90,8 +84,6 @@
visitor.append(thisObject->m_codeBlockForCall);
visitor.append(thisObject->m_codeBlockForConstruct);
visitor.append(thisObject->m_unlinkedExecutable);
- if (VM::canUseJIT())
- visitor.append(thisObject->m_singletonFunction);
if (RareData* rareData = thisObject->m_rareData.get()) {
visitor.append(rareData->m_cachedPolyProtoStructure);
if (TemplateObjectMap* map = rareData->m_templateObjectMap.get()) {
Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -248,38 +248,16 @@
DECLARE_INFO;
- InferredValue* singletonFunction()
+ InferredValue<JSFunction>& singleton()
{
- if (VM::canUseJIT())
- return m_singletonFunction.get();
- return nullptr;
+ return m_singleton;
}
- void notifyCreation(VM& vm, JSValue value, const char* reason)
+ void notifyCreation(VM& vm, JSFunction* function, const char* reason)
{
- if (VM::canUseJIT()) {
- singletonFunction()->notifyWrite(vm, value, reason);
- return;
- }
- switch (m_singletonFunctionState) {
- case ClearWatchpoint:
- m_singletonFunctionState = IsWatched;
- return;
- case IsWatched:
- m_singletonFunctionState = IsInvalidated;
- return;
- case IsInvalidated:
- return;
- }
+ m_singleton.notifyWrite(vm, this, function, reason);
}
- bool singletonFunctionHasBeenInvalidated()
- {
- if (VM::canUseJIT())
- return singletonFunction()->hasBeenInvalidated();
- return m_singletonFunctionState == IsInvalidated;
- }
-
// Cached poly proto structure for the result of constructing this executable.
Structure* cachedPolyProtoStructure()
{
@@ -305,6 +283,8 @@
TemplateObjectMap& ensureTemplateObjectMap(VM&);
+ void finalizeUnconditionally(VM&);
+
private:
friend class ExecutableBase;
FunctionExecutable(VM&, const SourceCode&, UnlinkedFunctionExecutable*, Intrinsic);
@@ -342,10 +322,7 @@
WriteBarrier<UnlinkedFunctionExecutable> m_unlinkedExecutable;
WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForConstruct;
- union {
- WriteBarrier<InferredValue> m_singletonFunction;
- WatchpointState m_singletonFunctionState;
- };
+ InferredValue<JSFunction> m_singleton;
Box<InlineWatchpointSet> m_polyProtoWatchpoint;
};
Copied: trunk/Source/_javascript_Core/runtime/FunctionExecutableInlines.h (from rev 246072, trunk/Source/_javascript_Core/runtime/InferredValueInlines.h) (0 => 246073)
--- trunk/Source/_javascript_Core/runtime/FunctionExecutableInlines.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutableInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "FunctionExecutable.h"
+#include "InferredValueInlines.h"
+
+namespace JSC {
+
+inline void FunctionExecutable::finalizeUnconditionally(VM& vm)
+{
+ m_singleton.finalizeUnconditionally(vm);
+}
+
+} // namespace JSC
+
Deleted: trunk/Source/_javascript_Core/runtime/InferredValue.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/InferredValue.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/InferredValue.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InferredValue.h"
-
-#include "IsoCellSetInlines.h"
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo InferredValue::s_info = { "InferredValue", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(InferredValue) };
-
-InferredValue* InferredValue::create(VM& vm)
-{
- ASSERT(VM::canUseJIT());
- InferredValue* result = new (NotNull, allocateCell<InferredValue>(vm.heap)) InferredValue(vm);
- result->finishCreation(vm);
- return result;
-}
-
-void InferredValue::destroy(JSCell* cell)
-{
- InferredValue* inferredValue = static_cast<InferredValue*>(cell);
- inferredValue->InferredValue::~InferredValue();
-}
-
-Structure* InferredValue::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-{
- return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
-}
-
-void InferredValue::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
- InferredValue* inferredValue = jsCast<InferredValue*>(cell);
- Base::visitChildren(cell, visitor);
-
- JSValue value = inferredValue->m_value.get();
- if (!value)
- return;
- if (!value.isCell())
- return;
-
- VM::SpaceAndSet::setFor(*inferredValue->subspace()).add(inferredValue);
-}
-
-InferredValue::InferredValue(VM& vm)
- : Base(vm, vm.inferredValueStructure.get())
- , m_set(ClearWatchpoint)
-{
-}
-
-InferredValue::~InferredValue()
-{
-}
-
-void InferredValue::notifyWriteSlow(VM& vm, JSValue value, const FireDetail& detail)
-{
- ASSERT(!!value);
- switch (m_set.state()) {
- case ClearWatchpoint:
- m_value.set(vm, this, value);
- m_set.startWatching();
- return;
-
- case IsWatched:
- ASSERT(!!m_value);
- if (m_value.get() == value)
- return;
- invalidate(vm, detail);
- return;
-
- case IsInvalidated:
- ASSERT_NOT_REACHED();
- return;
- }
-
- ASSERT_NOT_REACHED();
-}
-
-void InferredValue::notifyWriteSlow(VM& vm, JSValue value, const char* reason)
-{
- notifyWriteSlow(vm, value, StringFireDetail(reason));
-}
-
-} // namespace JSC
-
Modified: trunk/Source/_javascript_Core/runtime/InferredValue.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/InferredValue.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/InferredValue.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,43 +25,19 @@
#pragma once
-#include "IsoSubspace.h"
#include "JSCast.h"
#include "VM.h"
#include "Watchpoint.h"
#include "WriteBarrier.h"
+#include <wtf/Nonmovable.h>
namespace JSC {
-// Allocate one of these if you'd like to infer a constant value. Writes to the value should use
-// notifyWrite(). So long as exactly one value had ever been written and invalidate() has never been
-// called, and you register a watchpoint, you can rely on the inferredValue() being the one true
-// value.
-//
-// Commonly used for inferring singletons - in that case each allocation does notifyWrite(). But you
-// can use it for other things as well.
-
-class InferredValue final : public JSCell {
+template<typename JSCellType>
+class InferredValue {
+ WTF_MAKE_NONCOPYABLE(InferredValue);
+ WTF_MAKE_NONMOVABLE(InferredValue);
public:
- typedef JSCell Base;
-
- template<typename CellType, SubspaceAccess mode>
- static IsoSubspace* subspaceFor(VM& vm)
- {
- return vm.inferredValueSpace<mode>();
- }
-
- static InferredValue* create(VM&);
-
- static const bool needsDestruction = true;
- static void destroy(JSCell*);
-
- static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
-
- static void visitChildren(JSCell*, SlotVisitor&);
-
- DECLARE_INFO;
-
// For the purpose of deciding whether or not to watch this variable, you only need
// to inspect inferredValue(). If this returns something other than the empty
// value, then it means that at all future safepoints, this watchpoint set will be
@@ -73,51 +49,259 @@
// IsInvalidated: in this case the variable's value may be anything but you'll
// either notice that it's invalidated and not install the watchpoint, or
// you will have been notified that the watchpoint was fired.
- JSValue inferredValue() { return m_value.get(); }
+ JSCellType* inferredValue()
+ {
+ uintptr_t data = ""
+ if (isFat(data))
+ return fat(data)->inferredValue();
+ return bitwise_cast<JSCellType*>(data & ValueMask);
+ }
- // Forwards some WatchpointSet methods.
- WatchpointState state() const { return m_set.state(); }
- bool isStillValid() const { return m_set.isStillValid(); }
- bool hasBeenInvalidated() const { return m_set.hasBeenInvalidated(); }
- void add(Watchpoint* watchpoint) { m_set.add(watchpoint); }
-
- void notifyWrite(VM& vm, JSValue value, const FireDetail& detail)
+ explicit InferredValue()
+ : m_data(encodeState(ClearWatchpoint))
{
- if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
+ ASSERT(inferredValue() == nullptr);
+ }
+
+ ~InferredValue()
+ {
+ if (isThin())
return;
- notifyWriteSlow(vm, value, detail);
+ freeFat();
}
+
+ // Fast way of getting the state, which only works from the main thread.
+ WatchpointState stateOnJSThread() const
+ {
+ uintptr_t data = ""
+ if (isFat(data))
+ return fat(data)->stateOnJSThread();
+ return decodeState(data);
+ }
+
+ // It is safe to call this from another thread. It may return a prior state,
+ // but that should be fine since you should only perform actions based on the
+ // state if you also add a watchpoint.
+ WatchpointState state() const
+ {
+ WTF::loadLoadFence();
+ uintptr_t data = ""
+ WTF::loadLoadFence();
+ if (isFat(data))
+ return fat(data)->state();
+ return decodeState(data);
+ }
+
+ // It is safe to call this from another thread. It may return false
+ // even if the set actually had been invalidated, but that ought to happen
+ // only in the case of races, and should be rare.
+ bool hasBeenInvalidated() const
+ {
+ return state() == IsInvalidated;
+ }
- void notifyWrite(VM& vm, JSValue value, const char* reason)
+ // Like hasBeenInvalidated(), may be called from another thread.
+ bool isStillValid() const
{
- if (LIKELY(m_set.stateOnJSThread() == IsInvalidated))
- return;
- notifyWriteSlow(vm, value, reason);
+ return !hasBeenInvalidated();
}
+ void add(Watchpoint*);
+
void invalidate(VM& vm, const FireDetail& detail)
{
- m_value.clear();
- m_set.invalidate(vm, detail);
+ if (isFat())
+ fat()->invalidate(vm, detail);
+ else
+ m_data = encodeState(IsInvalidated);
}
- static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+ bool isBeingWatched() const
+ {
+ if (isFat())
+ return fat()->isBeingWatched();
+ return false;
+ }
+
+ void notifyWrite(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
+ {
+ if (LIKELY(stateOnJSThread() == IsInvalidated))
+ return;
+ notifyWriteSlow(vm, owner, value, detail);
+ }
+ void notifyWrite(VM& vm, JSCell* owner, JSCellType* value, const char* reason)
+ {
+ if (LIKELY(stateOnJSThread() == IsInvalidated))
+ return;
+ notifyWriteSlow(vm, owner, value, reason);
+ }
+
void finalizeUnconditionally(VM&);
-
+
private:
- InferredValue(VM&);
- ~InferredValue();
+ class InferredValueWatchpointSet final : public WatchpointSet {
+ public:
+ InferredValueWatchpointSet(WatchpointState state, JSCellType* value)
+ : WatchpointSet(state)
+ , m_value(value)
+ {
+ }
+
+ JSCellType* inferredValue() const { return m_value; }
+
+ void invalidate(VM& vm, const FireDetail& detail)
+ {
+ m_value = nullptr;
+ WatchpointSet::invalidate(vm, detail);
+ }
+
+ void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const FireDetail&);
+
+ private:
+ JSCellType* m_value;
+ };
+
+ static constexpr uintptr_t IsThinFlag = 1;
+ static constexpr uintptr_t StateMask = 6;
+ static constexpr uintptr_t StateShift = 1;
+ static constexpr uintptr_t ValueMask = ~static_cast<uintptr_t>(IsThinFlag | StateMask);
- JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const FireDetail&);
- JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const char* reason);
+ static bool isThin(uintptr_t data) { return data & IsThinFlag; }
+ static bool isFat(uintptr_t data) { return !isThin(data); }
- InlineWatchpointSet m_set;
- WriteBarrier<Unknown> m_value;
+ static WatchpointState decodeState(uintptr_t data)
+ {
+ ASSERT(isThin(data));
+ return static_cast<WatchpointState>((data & StateMask) >> StateShift);
+ }
+
+ static uintptr_t encodeState(WatchpointState state)
+ {
+ return (static_cast<uintptr_t>(state) << StateShift) | IsThinFlag;
+ }
+
+ bool isThin() const { return isThin(m_data); }
+ bool isFat() const { return isFat(m_data); };
+
+ static InferredValueWatchpointSet* fat(uintptr_t data)
+ {
+ return bitwise_cast<InferredValueWatchpointSet*>(data);
+ }
+
+ InferredValueWatchpointSet* fat()
+ {
+ ASSERT(isFat());
+ return fat(m_data);
+ }
+
+ const InferredValueWatchpointSet* fat() const
+ {
+ ASSERT(isFat());
+ return fat(m_data);
+ }
+
+ InferredValueWatchpointSet* inflate()
+ {
+ if (LIKELY(isFat()))
+ return fat();
+ return inflateSlow();
+ }
+
+ InferredValueWatchpointSet* inflateSlow();
+ void freeFat();
+
+ void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const FireDetail&);
+ void notifyWriteSlow(VM&, JSCell* owner, JSCellType*, const char* reason);
+
+ uintptr_t m_data;
};
-// FIXME: We could have an InlineInferredValue, which only allocates the InferredValue object when
-// a notifyWrite() transitions us towards watching, and then clears the reference (allowing the object
-// to die) when we get invalidated.
+template<typename JSCellType>
+void InferredValue<JSCellType>::InferredValueWatchpointSet::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
+{
+ switch (state()) {
+ case ClearWatchpoint:
+ m_value = value;
+ vm.heap.writeBarrier(owner, value);
+ startWatching();
+ return;
+ case IsWatched:
+ ASSERT(!!m_value);
+ if (m_value == value)
+ return;
+ invalidate(vm, detail);
+ return;
+
+ case IsInvalidated:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
+template<typename JSCellType>
+void InferredValue<JSCellType>::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const FireDetail& detail)
+{
+ uintptr_t data = ""
+ if (isFat(data)) {
+ fat(data)->notifyWriteSlow(vm, owner, value, detail);
+ return;
+ }
+
+ switch (state()) {
+ case ClearWatchpoint:
+ ASSERT(decodeState(m_data) != IsInvalidated);
+ m_data = (bitwise_cast<uintptr_t>(value) & ValueMask) | encodeState(IsWatched);
+ vm.heap.writeBarrier(owner, value);
+ return;
+
+ case IsWatched:
+ ASSERT(!!inferredValue());
+ if (inferredValue() == value)
+ return;
+ invalidate(vm, detail);
+ return;
+
+ case IsInvalidated:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ASSERT_NOT_REACHED();
+}
+
+template<typename JSCellType>
+void InferredValue<JSCellType>::notifyWriteSlow(VM& vm, JSCell* owner, JSCellType* value, const char* reason)
+{
+ notifyWriteSlow(vm, owner, value, StringFireDetail(reason));
+}
+
+template<typename JSCellType>
+void InferredValue<JSCellType>::add(Watchpoint* watchpoint)
+{
+ inflate()->add(watchpoint);
+}
+
+template<typename JSCellType>
+auto InferredValue<JSCellType>::inflateSlow() -> InferredValueWatchpointSet*
+{
+ ASSERT(isThin());
+ ASSERT(!isCompilationThread());
+ uintptr_t data = ""
+ InferredValueWatchpointSet* fat = adoptRef(new InferredValueWatchpointSet(decodeState(m_data), bitwise_cast<JSCellType*>(data & ValueMask))).leakRef();
+ WTF::storeStoreFence();
+ m_data = bitwise_cast<uintptr_t>(fat);
+ return fat;
+}
+
+template<typename JSCellType>
+void InferredValue<JSCellType>::freeFat()
+{
+ ASSERT(isFat());
+ fat()->deref();
+}
+
} // namespace JSC
Modified: trunk/Source/_javascript_Core/runtime/InferredValueInlines.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/InferredValueInlines.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/InferredValueInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -20,7 +20,7 @@
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
@@ -29,19 +29,17 @@
namespace JSC {
-void InferredValue::finalizeUnconditionally(VM& vm)
+template<typename JSCellType>
+void InferredValue<JSCellType>::finalizeUnconditionally(VM& vm)
{
- JSValue value = m_value.get();
-
- if (value && value.isCell()) {
- if (vm.heap.isMarked(value.asCell()))
+ JSCellType* value = inferredValue();
+
+ if (value) {
+ if (vm.heap.isMarked(value))
return;
-
+
invalidate(vm, StringFireDetail("InferredValue clean-up during GC"));
}
-
- VM::SpaceAndSet::setFor(*subspace()).remove(this);
}
} // namespace JSC
-
Modified: trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -34,7 +34,7 @@
inline JSFunction* JSFunction::createWithInvalidatedReallocationWatchpoint(
VM& vm, FunctionExecutable* executable, JSScope* scope)
{
- ASSERT(executable->singletonFunctionHasBeenInvalidated());
+ ASSERT(executable->singleton().hasBeenInvalidated());
return createImpl(vm, executable, scope, selectStructureForNewFuncExp(scope->globalObject(vm), executable));
}
Modified: trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -66,8 +66,7 @@
void setSymbolTable(VM& vm, SymbolTable* symbolTable)
{
ASSERT(!m_symbolTable);
- if (auto* singletonScope = symbolTable->singletonScope())
- singletonScope->notifyWrite(vm, this, "Allocated a scope");
+ symbolTable->notifyCreation(vm, this, "Allocated a scope");
m_symbolTable.set(vm, this, symbolTable);
}
Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/SymbolTable.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -90,8 +90,6 @@
void SymbolTable::finishCreation(VM& vm)
{
Base::finishCreation(vm);
- if (VM::canUseJIT())
- m_singletonScope.set(vm, this, InferredValue::create(vm));
}
void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor)
@@ -100,7 +98,6 @@
Base::visitChildren(thisSymbolTable, visitor);
visitor.append(thisSymbolTable->m_arguments);
- visitor.append(thisSymbolTable->m_singletonScope);
if (thisSymbolTable->m_rareData)
visitor.append(thisSymbolTable->m_rareData->m_codeBlock);
Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/SymbolTable.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -345,7 +345,6 @@
};
SymbolTableEntry& copySlow(const SymbolTableEntry&);
- JS_EXPORT_PRIVATE void notifyWriteSlow(VM&, JSValue, const FireDetail&);
bool isFat() const
{
@@ -450,6 +449,12 @@
typedef HashMap<VarOffset, RefPtr<UniquedStringImpl>> OffsetToVariableMap;
typedef Vector<SymbolTableEntry*> LocalToEntryVec;
+ template<typename CellType, SubspaceAccess>
+ static IsoSubspace* subspaceFor(VM& vm)
+ {
+ return &vm.symbolTableSpace;
+ }
+
static SymbolTable* create(VM& vm)
{
SymbolTable* symbolTable = new (NotNull, allocateCell<SymbolTable>(vm.heap)) SymbolTable(vm);
@@ -687,12 +692,19 @@
CodeBlock* rareDataCodeBlock();
void setRareDataCodeBlock(CodeBlock*);
- InferredValue* singletonScope() { return m_singletonScope.get(); }
+ InferredValue<JSScope>& singleton() { return m_singleton; }
+ void notifyCreation(VM& vm, JSScope* scope, const char* reason)
+ {
+ m_singleton.notifyWrite(vm, this, scope, reason);
+ }
+
static void visitChildren(JSCell*, SlotVisitor&);
DECLARE_EXPORT_INFO;
+ void finalizeUnconditionally(VM&);
+
private:
JS_EXPORT_PRIVATE SymbolTable(VM&);
~SymbolTable();
@@ -717,7 +729,7 @@
std::unique_ptr<SymbolTableRareData> m_rareData;
WriteBarrier<ScopedArgumentsTable> m_arguments;
- WriteBarrier<InferredValue> m_singletonScope;
+ InferredValue<JSScope> m_singleton;
std::unique_ptr<LocalToEntryVec> m_localToEntry;
};
Copied: trunk/Source/_javascript_Core/runtime/SymbolTableInlines.h (from rev 246072, trunk/Source/_javascript_Core/runtime/InferredValueInlines.h) (0 => 246073)
--- trunk/Source/_javascript_Core/runtime/SymbolTableInlines.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/SymbolTableInlines.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "InferredValueInlines.h"
+#include "SymbolTable.h"
+
+namespace JSC {
+
+inline void SymbolTable::finalizeUnconditionally(VM& vm)
+{
+ m_singleton.finalizeUnconditionally(vm);
+}
+
+} // namespace JSC
+
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2019-06-04 18:27:59 UTC (rev 246073)
@@ -64,7 +64,6 @@
#include "Identifier.h"
#include "IncrementalSweeper.h"
#include "IndirectEvalExecutable.h"
-#include "InferredValue.h"
#include "Interpreter.h"
#include "IntlCollatorConstructor.h"
#include "IntlDateTimeFormatConstructor.h"
@@ -286,6 +285,7 @@
, propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable)
, structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData)
, structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure)
+ , symbolTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), SymbolTable)
, executableToCodeBlockEdgesWithConstraints(executableToCodeBlockEdgeSpace)
, executableToCodeBlockEdgesWithFinalizers(executableToCodeBlockEdgeSpace)
, codeBlockSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), CodeBlock)
@@ -378,8 +378,6 @@
unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
unlinkedModuleProgramCodeBlockStructure.set(*this, UnlinkedModuleProgramCodeBlock::createStructure(*this, 0, jsNull()));
propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
- if (VM::canUseJIT())
- inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull()));
functionRareDataStructure.set(*this, FunctionRareData::createStructure(*this, 0, jsNull()));
exceptionStructure.set(*this, Exception::createStructure(*this, 0, jsNull()));
promiseDeferredStructure.set(*this, JSPromiseDeferred::createStructure(*this, 0, jsNull()));
@@ -1277,7 +1275,6 @@
return &m_##name->space; \
}
-DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(inferredValueSpace, destructibleCellHeapCellType.get(), InferredValue)
DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(evalExecutableSpace, destructibleCellHeapCellType.get(), EvalExecutable)
DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER_SLOW(moduleProgramExecutableSpace, destructibleCellHeapCellType.get(), ModuleProgramExecutable)
Modified: trunk/Source/_javascript_Core/runtime/VM.h (246072 => 246073)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-06-04 17:59:51 UTC (rev 246072)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-06-04 18:27:59 UTC (rev 246073)
@@ -380,6 +380,7 @@
IsoSubspace propertyTableSpace;
IsoSubspace structureRareDataSpace;
IsoSubspace structureSpace;
+ IsoSubspace symbolTableSpace;
#define DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(name) \
template<SubspaceAccess mode> \
@@ -451,7 +452,6 @@
};
SpaceAndSet codeBlockSpace;
- DYNAMIC_SPACE_AND_SET_DEFINE_MEMBER(inferredValueSpace)
template<typename Func>
void forEachCodeBlockSpace(const Func& func)
@@ -527,7 +527,6 @@
Strong<Structure> unlinkedFunctionCodeBlockStructure;
Strong<Structure> unlinkedModuleProgramCodeBlockStructure;
Strong<Structure> propertyTableStructure;
- Strong<Structure> inferredValueStructure;
Strong<Structure> functionRareDataStructure;
Strong<Structure> exceptionStructure;
Strong<Structure> promiseDeferredStructure;