Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JSC] Expand existing property names caching onto Reflect.ownKeys() /…
… Object.getOwnPropertySymbols()

https://bugs.webkit.org/show_bug.cgi?id=255935
<rdar://problem/108512520>

Reviewed by Yusuke Suzuki.

This change expands existing Object.keys() / Object.getOwnPropertyNames() StructureRareData-based
property names caching onto Reflect.ownKeys() / Object.getOwnPropertySymbols().

Vue.js v3 traps "ownKeys" on all reactive objects (except Map / Set) to merely forward the call to
Reflect.ownKeys(), while web developers often destructure / call Object.assign() on those Proxy objects.

Also, this change enables a follow-up optimization of Proxy objects without "ownKeys" traps,
hence the renaming of CachedPropertyNamesKind that unties enumerators from ObjectConstructor methods.

As for Object.getOwnPropertySymbols(), some older code on the web uses it conditionally instead of
polyfilling Reflect.ownKeys(), and optimizing it along with Reflect.ownKeys() brought convenience
of removing std::optional and a few conditions.

The downside of this patch is sizeof(StructureRareData) increase from 80 to 96.

                                            ToT                      patch

reflect-own-keys-proxy                18.8444+-0.1230     ?     18.9896+-0.1170        ?
reflect-own-keys-proxy-2              23.4113+-0.1775     ^     21.2813+-0.1835        ^ definitely 1.1001x faster
reflect-own-keys-function              8.3105+-0.0650     ^      6.4431+-0.0452        ^ definitely 1.2898x faster
reflect-own-keys                      31.3966+-0.1861     ^      0.9040+-0.0209        ^ definitely 34.7312x faster
object-get-own-property-symbols       18.6633+-0.1597     ^      1.0756+-0.0218        ^ definitely 17.3512x faster

<geometric>                           18.4640+-0.0749     ^      4.7893+-0.0312        ^ definitely 3.8553x faster

* JSTests/microbenchmarks/object-get-own-property-symbols.js:
* JSTests/microbenchmarks/reflect-own-keys.js:
Makes the property keys count way more real-world.

* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* Source/JavaScriptCore/dfg/DFGNode.h:
(JSC::DFG::Node::cachedPropertyNamesKind const):
* Source/JavaScriptCore/dfg/DFGNodeType.h:
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
(JSC::DFG::operationOwnPropertyKeysVariant):
(JSC::DFG::operationOwnPropertyKeysVariantObject):
* Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:
* Source/JavaScriptCore/dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h:
* Source/JavaScriptCore/ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::abstractHeapForOwnPropertyKeysCache):
(JSC::FTL::DFG::LowerDFGToB3::compileOwnPropertyKeysVariant):
(JSC::FTL::DFG::LowerDFGToB3::compileObjectKeysOrObjectGetOwnPropertyNames): Deleted.
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/ObjectConstructor.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::inferCachedPropertyNamesKind):
(JSC::ownPropertyKeys): Merely removes PropertyNameMode check, de-indents, and extracts copyPropertiesToBuffer() helper.

* Source/JavaScriptCore/runtime/ObjectConstructor.h:
* Source/JavaScriptCore/runtime/ReflectObject.cpp:
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/StructureRareData.h:

Canonical link: https://commits.webkit.org/263441@main
  • Loading branch information
Alexey Shvayka committed Apr 26, 2023
1 parent 9c5f7b8 commit d126a37
Show file tree
Hide file tree
Showing 27 changed files with 275 additions and 102 deletions.
4 changes: 2 additions & 2 deletions JSTests/microbenchmarks/object-get-own-property-symbols.js
@@ -1,6 +1,6 @@
//@ skip if $model == "Apple Watch Series 3" # added by mark-jsc-stress-test.py
var object = {};
for (var i = 0; i < 1e3; ++i) {
for (var i = 0; i < 20; ++i) {
object[Symbol(i + 'prop')] = i;
}

Expand All @@ -10,5 +10,5 @@ function test(object)
}
noInline(test);

for (var i = 0; i < 2500; ++i)
for (var i = 0; i < 1e5; ++i)
test(object);
6 changes: 3 additions & 3 deletions JSTests/microbenchmarks/reflect-own-keys.js
@@ -1,10 +1,10 @@
var obj = {}, i;
for (i = 0; i < 100; ++i)
for (i = 0; i < 10; ++i)
obj[`k${i}`] = i;
for (i = 0; i < 100; ++i)
for (i = 0; i < 10; ++i)
obj[Symbol(i)] = i;

noInline(Reflect.ownKeys);

for (i = 0; i < 1e4; ++i)
for (i = 0; i < 1e5; ++i)
Reflect.ownKeys(obj);
6 changes: 4 additions & 2 deletions Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Expand Up @@ -3309,14 +3309,16 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi
break;
}

case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectKeys: {
case ObjectGetOwnPropertySymbols:
case ReflectOwnKeys: {
if (node->child1().useKind() == ObjectUse) {
auto& structureSet = forNode(node->child1()).m_structure;
if (structureSet.isFinite() && structureSet.size() == 1) {
RegisteredStructure structure = structureSet.onlyStructure();
if (auto* rareData = structure->rareDataConcurrently()) {
if (!!rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) {
if (!!rareData->cachedPropertyNamesConcurrently(node->cachedPropertyNamesKind())) {
if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
m_state.setShouldTryConstantFolding(true);
didFoldClobberWorld();
Expand Down
18 changes: 18 additions & 0 deletions Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Expand Up @@ -3065,6 +3065,15 @@ auto ByteCodeParser::handleIntrinsicCall(Node* callee, Operand result, CallVaria
return CallOptimizationResult::Inlined;
}

case ObjectGetOwnPropertySymbolsIntrinsic: {
if (argumentCountIncludingThis < 2)
return CallOptimizationResult::DidNothing;

insertChecks();
setResult(addToGraph(ObjectGetOwnPropertySymbols, get(virtualRegisterForArgumentIncludingThis(1, registerOffset))));
return CallOptimizationResult::Inlined;
}

case ObjectToStringIntrinsic: {
insertChecks();
setResult(addToGraph(ObjectToString, get(virtualRegisterForArgumentIncludingThis(0, registerOffset))));
Expand All @@ -3080,6 +3089,15 @@ auto ByteCodeParser::handleIntrinsicCall(Node* callee, Operand result, CallVaria
return CallOptimizationResult::Inlined;
}

case ReflectOwnKeysIntrinsic: {
if (argumentCountIncludingThis < 2)
return CallOptimizationResult::DidNothing;

insertChecks();
setResult(addToGraph(ReflectOwnKeys, get(virtualRegisterForArgumentIncludingThis(1, registerOffset))));
return CallOptimizationResult::Inlined;
}

case IsTypedArrayViewIntrinsic: {
ASSERT(argumentCountIncludingThis == 2);

Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/dfg/DFGClobberize.h
Expand Up @@ -774,7 +774,9 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
case StringValueOf:
case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectGetOwnPropertySymbols:
case ObjectToString:
case ReflectOwnKeys:
clobberTop();
return;

Expand Down
6 changes: 4 additions & 2 deletions Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
Expand Up @@ -876,14 +876,16 @@ class ConstantFoldingPhase : public Phase {
break;
}

case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectKeys: {
case ObjectGetOwnPropertySymbols:
case ReflectOwnKeys: {
if (node->child1().useKind() == ObjectUse) {
auto& structureSet = m_state.forNode(node->child1()).m_structure;
if (structureSet.isFinite() && structureSet.size() == 1) {
RegisteredStructure structure = structureSet.onlyStructure();
if (auto* rareData = structure->rareDataConcurrently()) {
if (auto* immutableButterfly = rareData->cachedPropertyNamesConcurrently(node->op() == ObjectGetOwnPropertyNames ? CachedPropertyNamesKind::GetOwnPropertyNames : CachedPropertyNamesKind::Keys)) {
if (auto* immutableButterfly = rareData->cachedPropertyNamesConcurrently(node->cachedPropertyNamesKind())) {
if (m_graph.isWatchingHavingABadTimeWatchpoint(node)) {
node->convertToNewArrayBuffer(m_graph.freeze(immutableButterfly));
changed = true;
Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/dfg/DFGDoesGC.cpp
Expand Up @@ -367,7 +367,9 @@ bool doesGC(Graph& graph, Node* node)
case ObjectCreate:
case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectGetOwnPropertySymbols:
case ObjectToString:
case ReflectOwnKeys:
case AllocatePropertyStorage:
case ReallocatePropertyStorage:
case Arrayify:
Expand Down
4 changes: 3 additions & 1 deletion Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
Expand Up @@ -2080,8 +2080,10 @@ class FixupPhase : public Phase {
break;
}

case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectKeys: {
case ObjectGetOwnPropertySymbols:
case ReflectOwnKeys: {
if (node->child1()->shouldSpeculateObject()) {
watchHavingABadTime(node);
fixEdge<ObjectUse>(node->child1());
Expand Down
17 changes: 17 additions & 0 deletions Source/JavaScriptCore/dfg/DFGNode.h
Expand Up @@ -3413,6 +3413,23 @@ struct Node {
return OptionSet<JSPropertyNameEnumerator::Flag>::fromRaw(m_opInfo2.as<unsigned>());
}

CachedPropertyNamesKind cachedPropertyNamesKind() const
{
switch (op()) {
case ObjectKeys:
return CachedPropertyNamesKind::EnumerableStrings;
case ObjectGetOwnPropertyNames:
return CachedPropertyNamesKind::Strings;
case ObjectGetOwnPropertySymbols:
return CachedPropertyNamesKind::Symbols;
case ReflectOwnKeys:
return CachedPropertyNamesKind::StringsAndSymbols;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
}
}

void resetOpInfo()
{
m_opInfo = OpInfoWrapper();
Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/dfg/DFGNodeType.h
Expand Up @@ -305,7 +305,9 @@ namespace JSC { namespace DFG {
macro(ObjectCreate, NodeMustGenerate | NodeResultJS) \
macro(ObjectKeys, NodeMustGenerate | NodeResultJS) \
macro(ObjectGetOwnPropertyNames, NodeMustGenerate | NodeResultJS) \
macro(ObjectGetOwnPropertySymbols, NodeMustGenerate | NodeResultJS) \
macro(ObjectToString, NodeMustGenerate | NodeResultJS) \
macro(ReflectOwnKeys, NodeMustGenerate | NodeResultJS) \
\
/* Atomics object functions. */\
macro(AtomicsAdd, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
Expand Down
55 changes: 51 additions & 4 deletions Source/JavaScriptCore/dfg/DFGOperations.cpp
Expand Up @@ -75,6 +75,7 @@
#include "ObjectPrototypeInlines.h"
#include "Operations.h"
#include "ParseInt.h"
#include "ReflectObject.h"
#include "RegExpGlobalDataInlines.h"
#include "RegExpMatchesArray.h"
#include "RegExpObjectInlines.h"
Expand Down Expand Up @@ -260,15 +261,15 @@ JSC_DEFINE_JIT_OPERATION(operationObjectKeys, JSArray*, (JSGlobalObject* globalO
JSObject* object = JSValue::decode(encodedObject).toObject(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);
scope.release();
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
}

JSC_DEFINE_JIT_OPERATION(operationObjectKeysObject, JSArray*, (JSGlobalObject* globalObject, JSObject* object))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude, CachedPropertyNamesKind::Keys);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Exclude);
}

JSC_DEFINE_JIT_OPERATION(operationObjectGetOwnPropertyNames, JSArray*, (JSGlobalObject* globalObject, EncodedJSValue encodedObject))
Expand All @@ -281,15 +282,36 @@ JSC_DEFINE_JIT_OPERATION(operationObjectGetOwnPropertyNames, JSArray*, (JSGlobal
JSObject* object = JSValue::decode(encodedObject).toObject(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);
scope.release();
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include, CachedPropertyNamesKind::GetOwnPropertyNames);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationObjectGetOwnPropertyNamesObject, JSArray*, (JSGlobalObject* globalObject, JSObject* object))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include, CachedPropertyNamesKind::GetOwnPropertyNames);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Strings, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationObjectGetOwnPropertySymbols, JSArray*, (JSGlobalObject* globalObject, EncodedJSValue encodedObject))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
auto scope = DECLARE_THROW_SCOPE(vm);

JSObject* object = JSValue::decode(encodedObject).toObject(globalObject);
RETURN_IF_EXCEPTION(scope, nullptr);
scope.release();
return ownPropertyKeys(globalObject, object, PropertyNameMode::Symbols, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationObjectGetOwnPropertySymbolsObject, JSArray*, (JSGlobalObject* globalObject, JSObject* object))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return ownPropertyKeys(globalObject, object, PropertyNameMode::Symbols, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationObjectCreate, JSCell*, (JSGlobalObject* globalObject, EncodedJSValue encodedPrototype))
Expand Down Expand Up @@ -431,6 +453,31 @@ JSC_DEFINE_JIT_OPERATION(operationObjectToStringObjectSlow, JSString*, (JSGlobal
return objectPrototypeToString(globalObject, thisValue);
}

JSC_DEFINE_JIT_OPERATION(operationReflectOwnKeys, JSArray*, (JSGlobalObject* globalObject, EncodedJSValue encodedObject))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
auto scope = DECLARE_THROW_SCOPE(vm);

JSObject* object = JSValue::decode(encodedObject).getObject();
if (UNLIKELY(!object)) {
throwTypeError(globalObject, scope, ReflectOwnKeysNonObjectArgumentError);
return nullptr;
}

scope.release();
return ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationReflectOwnKeysObject, JSArray*, (JSGlobalObject* globalObject, JSObject* object))
{
VM& vm = globalObject->vm();
CallFrame* callFrame = DECLARE_CALL_FRAME(vm);
JITOperationPrologueCallFrameTracer tracer(vm, callFrame);
return ownPropertyKeys(globalObject, object, PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include);
}

JSC_DEFINE_JIT_OPERATION(operationCreateThis, JSCell*, (JSGlobalObject* globalObject, JSObject* constructor, uint32_t inlineCapacity))
{
VM& vm = globalObject->vm();
Expand Down
39 changes: 39 additions & 0 deletions Source/JavaScriptCore/dfg/DFGOperations.h
Expand Up @@ -28,6 +28,7 @@
#if ENABLE(DFG_JIT)

#include "DFGArithMode.h"
#include "DFGNodeType.h"
#include "IndexingType.h"
#include "JITOperations.h"
#include "TypedArrayType.h"
Expand Down Expand Up @@ -61,12 +62,16 @@ JSC_DECLARE_JIT_OPERATION(operationObjectKeys, JSArray*, (JSGlobalObject*, Encod
JSC_DECLARE_JIT_OPERATION(operationObjectKeysObject, JSArray*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationObjectGetOwnPropertyNames, JSArray*, (JSGlobalObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationObjectGetOwnPropertyNamesObject, JSArray*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationObjectGetOwnPropertySymbols, JSArray*, (JSGlobalObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationObjectGetOwnPropertySymbolsObject, JSArray*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationObjectCreate, JSCell*, (JSGlobalObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationObjectCreateObject, JSCell*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationObjectAssignObject, void, (JSGlobalObject*, JSObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationObjectAssignUntyped, void, (JSGlobalObject*, JSObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationObjectToStringUntyped, JSString*, (JSGlobalObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationObjectToStringObjectSlow, JSString*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationReflectOwnKeys, JSArray*, (JSGlobalObject*, EncodedJSValue));
JSC_DECLARE_JIT_OPERATION(operationReflectOwnKeysObject, JSArray*, (JSGlobalObject*, JSObject*));
JSC_DECLARE_JIT_OPERATION(operationCreateThis, JSCell*, (JSGlobalObject*, JSObject* constructor, uint32_t inlineCapacity));
JSC_DECLARE_JIT_OPERATION(operationCreatePromise, JSCell*, (JSGlobalObject*, JSObject* constructor));
JSC_DECLARE_JIT_OPERATION(operationCreateInternalPromise, JSCell*, (JSGlobalObject*, JSObject* constructor));
Expand Down Expand Up @@ -451,6 +456,40 @@ inline auto operationNewTypedArrayWithOneArgumentForType(TypedArrayType type) ->
return nullptr;
}

inline auto operationOwnPropertyKeysVariant(NodeType type) -> decltype(&operationObjectKeys)
{
switch (type) {
case ObjectKeys:
return operationObjectKeys;
case ObjectGetOwnPropertyNames:
return operationObjectGetOwnPropertyNames;
case ObjectGetOwnPropertySymbols:
return operationObjectGetOwnPropertySymbols;
case ReflectOwnKeys:
return operationReflectOwnKeys;
default:
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
}
}

inline auto operationOwnPropertyKeysVariantObject(NodeType type) -> decltype(&operationObjectKeysObject)
{
switch (type) {
case ObjectKeys:
return operationObjectKeysObject;
case ObjectGetOwnPropertyNames:
return operationObjectGetOwnPropertyNamesObject;
case ObjectGetOwnPropertySymbols:
return operationObjectGetOwnPropertySymbolsObject;
case ReflectOwnKeys:
return operationReflectOwnKeysObject;
default:
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
}
}

} } // namespace JSC::DFG

#endif
4 changes: 3 additions & 1 deletion Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
Expand Up @@ -1201,7 +1201,9 @@ class PredictionPropagationPhase : public Phase {
case CreateRest:
case NewArrayBuffer:
case ObjectKeys:
case ObjectGetOwnPropertyNames: {
case ObjectGetOwnPropertyNames:
case ObjectGetOwnPropertySymbols:
case ReflectOwnKeys: {
setPrediction(SpecArray);
break;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/dfg/DFGSafeToExecute.h
Expand Up @@ -514,7 +514,9 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno
case ObjectCreate:
case ObjectKeys:
case ObjectGetOwnPropertyNames:
case ObjectGetOwnPropertySymbols:
case ObjectToString:
case ReflectOwnKeys:
case SetLocal:
case SetCallee:
case PutStack:
Expand Down
10 changes: 5 additions & 5 deletions Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Expand Up @@ -15147,7 +15147,7 @@ void SpeculativeJIT::compileToThis(Node* node)
jsValueResult(tempRegs, node);
}

void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)
void SpeculativeJIT::compileOwnPropertyKeysVariant(Node* node)
{
switch (node->child1().useKind()) {
case ObjectUse: {
Expand Down Expand Up @@ -15175,7 +15175,7 @@ void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)
slowCases.append(branchTestPtr(Zero, scratchGPR));
slowCases.append(branchIfStructure(scratchGPR));

loadPtr(Address(scratchGPR, StructureRareData::offsetOfCachedPropertyNames(node->op() == ObjectKeys ? CachedPropertyNamesKind::Keys : CachedPropertyNamesKind::GetOwnPropertyNames)), scratchGPR);
loadPtr(Address(scratchGPR, StructureRareData::offsetOfCachedPropertyNames(node->cachedPropertyNamesKind())), scratchGPR);

ASSERT(bitwise_cast<uintptr_t>(StructureRareData::cachedPropertyNamesSentinel()) == 1);
slowCases.append(branchPtr(BelowOrEqual, scratchGPR, TrustedImmPtr(bitwise_cast<void*>(StructureRareData::cachedPropertyNamesSentinel()))));
Expand All @@ -15192,7 +15192,7 @@ void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)

addSlowPathGenerator(slowPathCall(slowButArrayBufferCases, this, operationNewArrayBuffer, resultGPR, TrustedImmPtr(&vm()), arrayStructure, scratch3GPR));

addSlowPathGenerator(slowPathCall(slowCases, this, node->op() == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, resultGPR, LinkableConstant::globalObject(*this, node), objectGPR));
addSlowPathGenerator(slowPathCall(slowCases, this, operationOwnPropertyKeysVariantObject(node->op()), resultGPR, LinkableConstant::globalObject(*this, node), objectGPR));

cellResult(resultGPR, node);
break;
Expand All @@ -15207,7 +15207,7 @@ void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)
flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
callOperation(node->op() == ObjectKeys ? operationObjectKeysObject : operationObjectGetOwnPropertyNamesObject, resultGPR, LinkableConstant::globalObject(*this, node), objectGPR);
callOperation(operationOwnPropertyKeysVariantObject(node->op()), resultGPR, LinkableConstant::globalObject(*this, node), objectGPR);
exceptionCheck();

cellResult(resultGPR, node);
Expand All @@ -15222,7 +15222,7 @@ void SpeculativeJIT::compileObjectKeysOrObjectGetOwnPropertyNames(Node* node)
flushRegisters();
GPRFlushedCallResult result(this);
GPRReg resultGPR = result.gpr();
callOperation(node->op() == ObjectKeys ? operationObjectKeys : operationObjectGetOwnPropertyNames, resultGPR, LinkableConstant::globalObject(*this, node), objectRegs);
callOperation(operationOwnPropertyKeysVariant(node->op()), resultGPR, LinkableConstant::globalObject(*this, node), objectRegs);
exceptionCheck();

cellResult(resultGPR, node);
Expand Down

0 comments on commit d126a37

Please sign in to comment.