Title: [240796] trunk/Source/_javascript_Core
Revision
240796
Author
ysuz...@apple.com
Date
2019-01-31 11:13:20 -0800 (Thu, 31 Jan 2019)

Log Message

[JSC] Do not use InferredValue in non-JIT configuration
https://bugs.webkit.org/show_bug.cgi?id=194084

Reviewed by Saam Barati.

InferredValue is not meaningful if our VM is non-JIT configuration. InferredValue is used to watch the instantiation of the  FunctionExecutable's
JSFunction and SymbolTable's JSScope to explore the chance of folding them into constants in DFG and FTL. If it is instantiated only once, we can
put a watchpoint and fold it into this constant. But if JIT is disabled, we do not need to care it.
Even in non-JIT configuration, we still use InferredValue for FunctionExecutable to determine whether the given FunctionExecutable is preferable
target for poly proto. If JSFunction for the FunctionExecutable is used as a constructor and instantiated more than once, poly proto Structure
seems appropriate for objects created by this JSFunction. But at that time, only thing we would like to know is that whether JSFunction for this
FunctionExecutable is instantiated multiple times. This does not require the full feature of InferredValue, WatchpointState is enough.
To summarize, since nobody uses InferredValue feature in non-JIT configuration, we should not create it.

* bytecode/ObjectAllocationProfileInlines.h:
(JSC::ObjectAllocationProfile::initializeProfile):
* runtime/FunctionExecutable.cpp:
(JSC::FunctionExecutable::finishCreation):
(JSC::FunctionExecutable::visitChildren):
* runtime/FunctionExecutable.h:
* runtime/InferredValue.cpp:
(JSC::InferredValue::create):
* runtime/JSAsyncFunction.cpp:
(JSC::JSAsyncFunction::create):
* runtime/JSAsyncGeneratorFunction.cpp:
(JSC::JSAsyncGeneratorFunction::create):
* runtime/JSFunction.cpp:
(JSC::JSFunction::create):
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
* runtime/JSGeneratorFunction.cpp:
(JSC::JSGeneratorFunction::create):
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::setSymbolTable):
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::finishCreation):
* runtime/VM.cpp:
(JSC::VM::VM):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (240795 => 240796)


--- trunk/Source/_javascript_Core/ChangeLog	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-01-31 19:13:20 UTC (rev 240796)
@@ -1,3 +1,44 @@
+2019-01-31  Yusuke Suzuki  <ysuz...@apple.com>
+
+        [JSC] Do not use InferredValue in non-JIT configuration
+        https://bugs.webkit.org/show_bug.cgi?id=194084
+
+        Reviewed by Saam Barati.
+
+        InferredValue is not meaningful if our VM is non-JIT configuration. InferredValue is used to watch the instantiation of the  FunctionExecutable's
+        JSFunction and SymbolTable's JSScope to explore the chance of folding them into constants in DFG and FTL. If it is instantiated only once, we can
+        put a watchpoint and fold it into this constant. But if JIT is disabled, we do not need to care it.
+        Even in non-JIT configuration, we still use InferredValue for FunctionExecutable to determine whether the given FunctionExecutable is preferable
+        target for poly proto. If JSFunction for the FunctionExecutable is used as a constructor and instantiated more than once, poly proto Structure
+        seems appropriate for objects created by this JSFunction. But at that time, only thing we would like to know is that whether JSFunction for this
+        FunctionExecutable is instantiated multiple times. This does not require the full feature of InferredValue, WatchpointState is enough.
+        To summarize, since nobody uses InferredValue feature in non-JIT configuration, we should not create it.
+
+        * bytecode/ObjectAllocationProfileInlines.h:
+        (JSC::ObjectAllocationProfile::initializeProfile):
+        * runtime/FunctionExecutable.cpp:
+        (JSC::FunctionExecutable::finishCreation):
+        (JSC::FunctionExecutable::visitChildren):
+        * runtime/FunctionExecutable.h:
+        * runtime/InferredValue.cpp:
+        (JSC::InferredValue::create):
+        * runtime/JSAsyncFunction.cpp:
+        (JSC::JSAsyncFunction::create):
+        * runtime/JSAsyncGeneratorFunction.cpp:
+        (JSC::JSAsyncGeneratorFunction::create):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::create):
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::createWithInvalidatedReallocationWatchpoint):
+        * runtime/JSGeneratorFunction.cpp:
+        (JSC::JSGeneratorFunction::create):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::setSymbolTable):
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::finishCreation):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+
 2019-01-31  Fujii Hironori  <hironori.fu...@sony.com>
 
         [CMake][JSC] Changing ud_opcode.py should trigger invoking ud_opcode.py

Modified: trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h (240795 => 240796)


--- trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/bytecode/ObjectAllocationProfileInlines.h	2019-01-31 19:13:20 UTC (rev 240796)
@@ -65,7 +65,7 @@
         if (Options::forcePolyProto())
             isPolyProto = true;
         else
-            isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunction()->hasBeenInvalidated();
+            isPolyProto = executable->ensurePolyProtoWatchpoint().hasBeenInvalidated() && executable->singletonFunctionHasBeenInvalidated();
     }
 
     unsigned inlineCapacity = 0;

Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -58,7 +58,10 @@
 void FunctionExecutable::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    m_singletonFunction.set(vm, this, InferredValue::create(vm));
+    if (VM::canUseJIT())
+        m_singletonFunction.set(vm, this, InferredValue::create(vm));
+    else
+        m_singletonFunctionState = ClearWatchpoint;
 }
 
 void FunctionExecutable::destroy(JSCell* cell)
@@ -88,7 +91,8 @@
     visitor.append(thisObject->m_codeBlockForCall);
     visitor.append(thisObject->m_codeBlockForConstruct);
     visitor.append(thisObject->m_unlinkedExecutable);
-    visitor.append(thisObject->m_singletonFunction);
+    if (VM::canUseJIT())
+        visitor.append(thisObject->m_singletonFunction);
     visitor.append(thisObject->m_cachedPolyProtoStructure);
 }
 

Modified: trunk/Source/_javascript_Core/runtime/FunctionExecutable.h (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/FunctionExecutable.h	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/FunctionExecutable.h	2019-01-31 19:13:20 UTC (rev 240796)
@@ -183,7 +183,38 @@
 
     DECLARE_INFO;
 
-    InferredValue* singletonFunction() { return m_singletonFunction.get(); }
+    InferredValue* singletonFunction()
+    {
+        if (VM::canUseJIT())
+            return m_singletonFunction.get();
+        return nullptr;
+    }
+
+    void notifyCreation(VM& vm, JSValue value, 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;
+        }
+    }
+
+    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() { return m_cachedPolyProtoStructure.get(); }
     void setCachedPolyProtoStructure(VM& vm, Structure* structure) { m_cachedPolyProtoStructure.set(vm, this, structure); }
@@ -212,7 +243,10 @@
     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForCall;
     WriteBarrier<ExecutableToCodeBlockEdge> m_codeBlockForConstruct;
     RefPtr<TypeSet> m_returnStatementTypeSet;
-    WriteBarrier<InferredValue> m_singletonFunction;
+    union {
+        WriteBarrier<InferredValue> m_singletonFunction;
+        WatchpointState m_singletonFunctionState;
+    };
     WriteBarrier<Structure> m_cachedPolyProtoStructure;
     Box<InlineWatchpointSet> m_polyProtoWatchpoint;
 };

Modified: trunk/Source/_javascript_Core/runtime/InferredValue.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/InferredValue.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/InferredValue.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -35,6 +35,7 @@
 
 InferredValue* InferredValue::create(VM& vm)
 {
+    ASSERT(VM::canUseJIT());
     InferredValue* result = new (NotNull, allocateCell<InferredValue>(vm.heap)) InferredValue(vm);
     result->finishCreation(vm);
     return result;

Modified: trunk/Source/_javascript_Core/runtime/JSAsyncFunction.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSAsyncFunction.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSAsyncFunction.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -55,7 +55,7 @@
 JSAsyncFunction* JSAsyncFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
 {
     JSAsyncFunction* asyncFunction = createImpl(vm, executable, scope, scope->globalObject(vm)->asyncFunctionStructure());
-    executable->singletonFunction()->notifyWrite(vm, asyncFunction, "Allocating an async function");
+    executable->notifyCreation(vm, asyncFunction, "Allocating an async function");
     return asyncFunction;
 }
 
@@ -62,7 +62,7 @@
 JSAsyncFunction* JSAsyncFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, Structure* structure)
 {
     JSAsyncFunction* asyncFunction = createImpl(vm, executable, scope, structure);
-    executable->singletonFunction()->notifyWrite(vm, asyncFunction, "Allocating an async function");
+    executable->notifyCreation(vm, asyncFunction, "Allocating an async function");
     return asyncFunction;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSAsyncGeneratorFunction.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSAsyncGeneratorFunction.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSAsyncGeneratorFunction.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -55,7 +55,7 @@
 JSAsyncGeneratorFunction* JSAsyncGeneratorFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
 {
     JSAsyncGeneratorFunction* asyncGenerator = createImpl(vm, executable, scope, scope->globalObject(vm)->asyncGeneratorFunctionStructure());
-    executable->singletonFunction()->notifyWrite(vm, asyncGenerator, "Allocating an async generator");
+    executable->notifyCreation(vm, asyncGenerator, "Allocating an async generator");
     return asyncGenerator;
 }
 
@@ -62,7 +62,7 @@
 JSAsyncGeneratorFunction* JSAsyncGeneratorFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, Structure* structure)
 {
     JSAsyncGeneratorFunction* asyncGenerator = createImpl(vm, executable, scope, structure);
-    executable->singletonFunction()->notifyWrite(vm, asyncGenerator, "Allocating an async generator");
+    executable->notifyCreation(vm, asyncGenerator, "Allocating an async generator");
     return asyncGenerator;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -84,7 +84,7 @@
 JSFunction* JSFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, Structure* structure)
 {
     JSFunction* result = createImpl(vm, executable, scope, structure);
-    executable->singletonFunction()->notifyWrite(vm, result, "Allocating a function");
+    executable->notifyCreation(vm, result, "Allocating a function");
     return result;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSFunctionInlines.h	2019-01-31 19:13:20 UTC (rev 240796)
@@ -34,7 +34,7 @@
 inline JSFunction* JSFunction::createWithInvalidatedReallocationWatchpoint(
     VM& vm, FunctionExecutable* executable, JSScope* scope)
 {
-    ASSERT(executable->singletonFunction()->hasBeenInvalidated());
+    ASSERT(executable->singletonFunctionHasBeenInvalidated());
     return createImpl(vm, executable, scope, selectStructureForNewFuncExp(scope->globalObject(vm), executable));
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSGeneratorFunction.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSGeneratorFunction.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSGeneratorFunction.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -60,7 +60,7 @@
 JSGeneratorFunction* JSGeneratorFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope, Structure* structure)
 {
     JSGeneratorFunction* generatorFunction = createImpl(vm, executable, scope, structure);
-    executable->singletonFunction()->notifyWrite(vm, generatorFunction, "Allocating a generator function");
+    executable->notifyCreation(vm, generatorFunction, "Allocating a generator function");
     return generatorFunction;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/JSSymbolTableObject.h	2019-01-31 19:13:20 UTC (rev 240796)
@@ -66,7 +66,8 @@
     void setSymbolTable(VM& vm, SymbolTable* symbolTable)
     {
         ASSERT(!m_symbolTable);
-        symbolTable->singletonScope()->notifyWrite(vm, this, "Allocated a scope");
+        if (auto* singletonScope = symbolTable->singletonScope())
+            singletonScope->notifyWrite(vm, this, "Allocated a scope");
         m_symbolTable.set(vm, this, symbolTable);
     }
     

Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/SymbolTable.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -95,7 +95,8 @@
 void SymbolTable::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    m_singletonScope.set(vm, this, InferredValue::create(vm));
+    if (VM::canUseJIT())
+        m_singletonScope.set(vm, this, InferredValue::create(vm));
 }
 
 void SymbolTable::visitChildren(JSCell* thisCell, SlotVisitor& visitor)

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (240795 => 240796)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2019-01-31 18:10:48 UTC (rev 240795)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2019-01-31 19:13:20 UTC (rev 240796)
@@ -409,7 +409,8 @@
     unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull()));
     unlinkedModuleProgramCodeBlockStructure.set(*this, UnlinkedModuleProgramCodeBlock::createStructure(*this, 0, jsNull()));
     propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull()));
-    inferredValueStructure.set(*this, InferredValue::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()));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to