Log Message
[DFG] PutByVal with Array::Generic is too generic https://bugs.webkit.org/show_bug.cgi?id=176345
Reviewed by Filip Pizlo.
JSTests:
* stress/object-assign-symbols.js: Added.
(shouldBe):
(test):
* stress/object-assign.js: Added.
(shouldBe):
(test):
(i.shouldBe.JSON.stringify.test):
Source/_javascript_Core:
Our DFG/FTL's PutByVal with Array::Generic is too generic implementation.
We could have the case like,
dst[key] = src[key];
with string or symbol keys. But they are handled in slow path.
This patch adds PutByVal(CellUse, StringUse/SymbolUse, UntypedUse). They go
to optimized path that does not have generic checks like (isInt32() / isDouble() etc.).
This improves SixSpeed object-assign.es5 by 9.1%.
object-assign.es5 424.3159+-11.0471 ^ 388.8771+-10.9239 ^ definitely 1.0911x faster
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGOperations.cpp:
(JSC::DFG::putByVal):
(JSC::DFG::putByValInternal):
(JSC::DFG::putByValCellInternal):
(JSC::DFG::putByValCellStringInternal):
(JSC::DFG::operationPutByValInternal): Deleted.
* dfg/DFGOperations.h:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compilePutByValForCellWithString):
(JSC::DFG::SpeculativeJIT::compilePutByValForCellWithSymbol):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compilePutByVal):
* jit/JITOperations.h:
Modified Paths
- trunk/JSTests/ChangeLog
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp
- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp
- trunk/Source/_javascript_Core/dfg/DFGOperations.h
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp
- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp
- trunk/Source/_javascript_Core/jit/JITOperations.h
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (221792 => 221793)
--- trunk/JSTests/ChangeLog 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/JSTests/ChangeLog 2017-09-08 18:58:24 UTC (rev 221793)
@@ -1,5 +1,20 @@
2017-09-08 Yusuke Suzuki <[email protected]>
+ [DFG] PutByVal with Array::Generic is too generic
+ https://bugs.webkit.org/show_bug.cgi?id=176345
+
+ Reviewed by Filip Pizlo.
+
+ * stress/object-assign-symbols.js: Added.
+ (shouldBe):
+ (test):
+ * stress/object-assign.js: Added.
+ (shouldBe):
+ (test):
+ (i.shouldBe.JSON.stringify.test):
+
+2017-09-08 Yusuke Suzuki <[email protected]>
+
[DFG][FTL] GetByVal(ObjectUse with Array::Generic, StringUse/SymbolUse) should be supported
https://bugs.webkit.org/show_bug.cgi?id=176590
Added: trunk/JSTests/stress/object-assign-symbols.js (0 => 221793)
--- trunk/JSTests/stress/object-assign-symbols.js (rev 0)
+++ trunk/JSTests/stress/object-assign-symbols.js 2017-09-08 18:58:24 UTC (rev 221793)
@@ -0,0 +1,38 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+var a = Symbol("a");
+var b = Symbol("b");
+var c = Symbol("c");
+var d = Symbol("d");
+var e = Symbol("e");
+
+var obj = {
+ [a]: 1,
+ [b]: 2,
+ [c]: 3,
+ [d]: null,
+ [e]: 'e'
+};
+
+function test(src) {
+ var o = {};
+ var keys = Object.getOwnPropertySymbols(src);
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ o[key] = src[key];
+ }
+ return o;
+}
+noInline(test);
+
+for (var i = 0; i < 1e4; ++i) {
+ var result = test(obj);
+ shouldBe(result[a], 1);
+ shouldBe(result[b], 2);
+ shouldBe(result[c], 3);
+ shouldBe(result[d], null);
+ shouldBe(result[e], 'e');
+}
Added: trunk/JSTests/stress/object-assign.js (0 => 221793)
--- trunk/JSTests/stress/object-assign.js (rev 0)
+++ trunk/JSTests/stress/object-assign.js 2017-09-08 18:58:24 UTC (rev 221793)
@@ -0,0 +1,26 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+var obj = {
+ a: 1,
+ b: 2,
+ c: 3,
+ d: null,
+ e: 'e'
+};
+
+function test(src) {
+ var o = {};
+ var keys = Object.keys(src);
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ o[key] = src[key];
+ }
+ return o;
+}
+noInline(test);
+
+for (var i = 0; i < 1e4; ++i)
+ shouldBe(JSON.stringify(test(obj)), `{"a":1,"b":2,"c":3,"d":null,"e":"e"}`);
Modified: trunk/Source/_javascript_Core/ChangeLog (221792 => 221793)
--- trunk/Source/_javascript_Core/ChangeLog 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-09-08 18:58:24 UTC (rev 221793)
@@ -1,5 +1,47 @@
2017-09-08 Yusuke Suzuki <[email protected]>
+ [DFG] PutByVal with Array::Generic is too generic
+ https://bugs.webkit.org/show_bug.cgi?id=176345
+
+ Reviewed by Filip Pizlo.
+
+ Our DFG/FTL's PutByVal with Array::Generic is too generic implementation.
+ We could have the case like,
+
+ dst[key] = src[key];
+
+ with string or symbol keys. But they are handled in slow path.
+ This patch adds PutByVal(CellUse, StringUse/SymbolUse, UntypedUse). They go
+ to optimized path that does not have generic checks like (isInt32() / isDouble() etc.).
+
+ This improves SixSpeed object-assign.es5 by 9.1%.
+
+ object-assign.es5 424.3159+-11.0471 ^ 388.8771+-10.9239 ^ definitely 1.0911x faster
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGOperations.cpp:
+ (JSC::DFG::putByVal):
+ (JSC::DFG::putByValInternal):
+ (JSC::DFG::putByValCellInternal):
+ (JSC::DFG::putByValCellStringInternal):
+ (JSC::DFG::operationPutByValInternal): Deleted.
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compilePutByValForCellWithString):
+ (JSC::DFG::SpeculativeJIT::compilePutByValForCellWithSymbol):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compilePutByVal):
+ * jit/JITOperations.h:
+
+2017-09-08 Yusuke Suzuki <[email protected]>
+
[DFG][FTL] GetByVal(ObjectUse with Array::Generic, StringUse/SymbolUse) should be supported
https://bugs.webkit.org/show_bug.cgi?id=176590
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -865,6 +865,19 @@
break;
case Array::ForceExit:
case Array::Generic:
+ if (child1->shouldSpeculateCell()) {
+ if (child2->shouldSpeculateString()) {
+ fixEdge<CellUse>(child1);
+ fixEdge<StringUse>(child2);
+ break;
+ }
+
+ if (child2->shouldSpeculateSymbol()) {
+ fixEdge<CellUse>(child1);
+ fixEdge<SymbolUse>(child2);
+ break;
+ }
+ }
#if USE(JSVALUE32_64)
// Due to register pressure on 32-bit, we speculate cell and
// ignore the base-is-not-cell case entirely by letting the
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -75,10 +75,8 @@
namespace JSC { namespace DFG {
template<bool strict, bool direct>
-static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
+static inline void putByVal(ExecState* exec, VM& vm, JSValue baseValue, uint32_t index, JSValue value)
{
- VM& vm = exec->vm();
- NativeCallFrameTracer tracer(&vm, exec);
ASSERT(isIndex(index));
if (direct) {
RELEASE_ASSERT(baseValue.isObject());
@@ -100,11 +98,9 @@
}
template<bool strict, bool direct>
-ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
+ALWAYS_INLINE static void putByValInternal(ExecState* exec, VM& vm, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- auto scope = DECLARE_THROW_SCOPE(*vm);
- NativeCallFrameTracer tracer(vm, exec);
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSValue baseValue = JSValue::decode(encodedBase);
JSValue property = JSValue::decode(encodedProperty);
@@ -114,7 +110,7 @@
// Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
ASSERT(isIndex(property.asUInt32()));
scope.release();
- putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
+ putByVal<strict, direct>(exec, vm, baseValue, property.asUInt32(), value);
return;
}
@@ -123,7 +119,7 @@
uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
scope.release();
- putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
+ putByVal<strict, direct>(exec, vm, baseValue, propertyAsUInt32, value);
return;
}
}
@@ -140,7 +136,7 @@
asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
return;
}
- asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
+ asObject(baseValue)->putDirect(vm, propertyName, value, slot);
return;
}
scope.release();
@@ -147,6 +143,33 @@
baseValue.put(exec, propertyName, value, slot);
}
+template<bool strict, bool direct>
+ALWAYS_INLINE static void putByValCellInternal(ExecState* exec, VM& vm, JSCell* base, PropertyName propertyName, JSValue value)
+{
+ PutPropertySlot slot(base, strict);
+ if (direct) {
+ RELEASE_ASSERT(base->isObject());
+ if (std::optional<uint32_t> index = parseIndex(propertyName))
+ asObject(base)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
+ else
+ asObject(base)->putDirect(vm, propertyName, value, slot);
+ return;
+ }
+ base->putInline(exec, propertyName, value, slot);
+}
+
+template<bool strict, bool direct>
+ALWAYS_INLINE static void putByValCellStringInternal(ExecState* exec, VM& vm, JSCell* base, JSString* property, JSValue value)
+{
+ auto scope = DECLARE_THROW_SCOPE(vm);
+
+ auto propertyName = property->toIdentifier(exec);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ scope.release();
+ putByValCellInternal<strict, direct>(exec, vm, base, propertyName, value);
+}
+
template<typename ViewClass>
char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, char* vector)
{
@@ -618,36 +641,68 @@
void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
+ putByValInternal<true, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
+ putByValInternal<false, false>(exec, vm, encodedBase, encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
+ putByValInternal<true, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
+ putByValInternal<false, false>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
}
+void JIT_OPERATION operationPutByValCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellStringInternal<true, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellStringInternal<false, false>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellInternal<true, false>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellInternal<false, false>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
+}
+
void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
{
VM& vm = exec->vm();
@@ -714,36 +769,68 @@
void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
+ putByValInternal<true, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
+ putByValInternal<false, true>(exec, vm, encodedBase, encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
+ putByValInternal<true, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
}
void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
{
- VM* vm = &exec->vm();
- NativeCallFrameTracer tracer(vm, exec);
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
- operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
+ putByValInternal<false, true>(exec, vm, JSValue::encode(cell), encodedProperty, encodedValue);
}
+void JIT_OPERATION operationPutByValDirectCellStringStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellStringInternal<true, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValDirectCellStringNonStrict(ExecState* exec, JSCell* cell, JSCell* string, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellStringInternal<false, true>(exec, vm, cell, asString(string), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValDirectCellSymbolStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellInternal<true, true>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
+}
+
+void JIT_OPERATION operationPutByValDirectCellSymbolNonStrict(ExecState* exec, JSCell* cell, JSCell* symbol, EncodedJSValue encodedValue)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ putByValCellInternal<false, true>(exec, vm, cell, asSymbol(symbol)->privateName(), JSValue::decode(encodedValue));
+}
+
void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
{
VM* vm = &exec->vm();
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.h 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h 2017-09-08 18:58:24 UTC (rev 221793)
@@ -103,6 +103,10 @@
void JIT_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValCellStringStrict(ExecState*, JSCell*, JSCell* string, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValCellStringNonStrict(ExecState*, JSCell*, JSCell* string, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValCellSymbolStrict(ExecState*, JSCell*, JSCell* symbol, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValCellSymbolNonStrict(ExecState*, JSCell*, JSCell* symbol, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL;
@@ -110,6 +114,10 @@
void JIT_OPERATION operationPutByValDirectNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValDirectCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValDirectCellStringStrict(ExecState*, JSCell*, JSCell* string, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValDirectCellStringNonStrict(ExecState*, JSCell*, JSCell* string, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValDirectCellSymbolStrict(ExecState*, JSCell*, JSCell* symbol, EncodedJSValue encodedValue) WTF_INTERNAL;
+void JIT_OPERATION operationPutByValDirectCellSymbolNonStrict(ExecState*, JSCell*, JSCell* symbol, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState*, JSObject*, int32_t index, EncodedJSValue encodedValue) WTF_INTERNAL;
void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState*, JSObject*, int32_t index, double value) WTF_INTERNAL;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -3200,6 +3200,44 @@
jsValueResult(resultRegs, node);
}
+void SpeculativeJIT::compilePutByValForCellWithString(Node* node, Edge& child1, Edge& child2, Edge& child3)
+{
+ SpeculateCellOperand arg1(this, child1);
+ SpeculateCellOperand arg2(this, child2);
+ JSValueOperand arg3(this, child3);
+
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg arg2GPR = arg2.gpr();
+ JSValueRegs arg3Regs = arg3.jsValueRegs();
+
+ speculateString(child2, arg2GPR);
+
+ flushRegisters();
+ callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValCellStringStrict : operationPutByValCellStringNonStrict, arg1GPR, arg2GPR, arg3Regs);
+ m_jit.exceptionCheck();
+
+ noResult(node);
+}
+
+void SpeculativeJIT::compilePutByValForCellWithSymbol(Node* node, Edge& child1, Edge& child2, Edge& child3)
+{
+ SpeculateCellOperand arg1(this, child1);
+ SpeculateCellOperand arg2(this, child2);
+ JSValueOperand arg3(this, child3);
+
+ GPRReg arg1GPR = arg1.gpr();
+ GPRReg arg2GPR = arg2.gpr();
+ JSValueRegs arg3Regs = arg3.jsValueRegs();
+
+ speculateSymbol(child2, arg2GPR);
+
+ flushRegisters();
+ callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValCellSymbolStrict : operationPutByValCellSymbolNonStrict, arg1GPR, arg2GPR, arg3Regs);
+ m_jit.exceptionCheck();
+
+ noResult(node);
+}
+
void SpeculativeJIT::compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg, GPRReg scratch2Reg)
{
// Check that prototype is an object.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2017-09-08 18:58:24 UTC (rev 221793)
@@ -1885,6 +1885,11 @@
m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
return appendCall(operation);
}
+ JITCompiler::Call callOperation(V_JITOperation_ECCJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR());
+ return appendCall(operation);
+ }
JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1)
{
@@ -2423,6 +2428,11 @@
m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR());
return appendCall(operation);
}
+ JITCompiler::Call callOperation(V_JITOperation_ECCJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR());
+ return appendCall(operation);
+ }
JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3)
{
@@ -2875,6 +2885,8 @@
void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
void compileGetByValForObjectWithString(Node*);
void compileGetByValForObjectWithSymbol(Node*);
+ void compilePutByValForCellWithString(Node*, Edge& child1, Edge& child2, Edge& child3);
+ void compilePutByValForCellWithSymbol(Node*, Edge& child1, Edge& child2, Edge& child3);
// If this returns false it means that we terminated speculative execution.
bool getIntTypedArrayStoreOperand(
GPRTemporary& value,
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -2903,6 +2903,20 @@
break;
case Array::Generic: {
ASSERT(node->op() == PutByVal || node->op() == PutByValDirect);
+
+ if (child1.useKind() == CellUse) {
+ if (child2.useKind() == StringUse) {
+ compilePutByValForCellWithString(node, child1, child2, child3);
+ alreadyHandled = true;
+ break;
+ }
+
+ if (child2.useKind() == SymbolUse) {
+ compilePutByValForCellWithSymbol(node, child1, child2, child3);
+ alreadyHandled = true;
+ break;
+ }
+ }
SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right.
JSValueOperand property(this, child2);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -2975,6 +2975,20 @@
break;
case Array::Generic: {
DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal || node->op() == PutByValDirect);
+
+ if (child1.useKind() == CellUse) {
+ if (child2.useKind() == StringUse) {
+ compilePutByValForCellWithString(node, child1, child2, child3);
+ alreadyHandled = true;
+ break;
+ }
+
+ if (child2.useKind() == SymbolUse) {
+ compilePutByValForCellWithSymbol(node, child1, child2, child3);
+ alreadyHandled = true;
+ break;
+ }
+ }
JSValueOperand arg1(this, child1);
JSValueOperand arg2(this, child2);
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (221792 => 221793)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2017-09-08 18:58:24 UTC (rev 221793)
@@ -3846,6 +3846,41 @@
switch (m_node->arrayMode().type()) {
case Array::Generic: {
+ if (child1.useKind() == CellUse) {
+ V_JITOperation_ECCJ operation = nullptr;
+ if (child2.useKind() == StringUse) {
+ if (m_node->op() == PutByValDirect) {
+ if (m_graph.isStrictModeFor(m_node->origin.semantic))
+ operation = operationPutByValDirectCellStringStrict;
+ else
+ operation = operationPutByValDirectCellStringNonStrict;
+ } else {
+ if (m_graph.isStrictModeFor(m_node->origin.semantic))
+ operation = operationPutByValCellStringStrict;
+ else
+ operation = operationPutByValCellStringNonStrict;
+ }
+ vmCall(Void, m_out.operation(operation), m_callFrame, lowCell(child1), lowString(child2), lowJSValue(child3));
+ return;
+ }
+
+ if (child2.useKind() == SymbolUse) {
+ if (m_node->op() == PutByValDirect) {
+ if (m_graph.isStrictModeFor(m_node->origin.semantic))
+ operation = operationPutByValDirectCellSymbolStrict;
+ else
+ operation = operationPutByValDirectCellSymbolNonStrict;
+ } else {
+ if (m_graph.isStrictModeFor(m_node->origin.semantic))
+ operation = operationPutByValCellSymbolStrict;
+ else
+ operation = operationPutByValCellSymbolNonStrict;
+ }
+ vmCall(Void, m_out.operation(operation), m_callFrame, lowCell(child1), lowSymbol(child2), lowJSValue(child3));
+ return;
+ }
+ }
+
V_JITOperation_EJJJ operation;
if (m_node->op() == PutByValDirect) {
if (m_graph.isStrictModeFor(m_node->origin.semantic))
Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (221792 => 221793)
--- trunk/Source/_javascript_Core/jit/JITOperations.h 2017-09-08 18:55:48 UTC (rev 221792)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h 2017-09-08 18:58:24 UTC (rev 221793)
@@ -265,6 +265,7 @@
typedef void (JIT_OPERATION *V_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
typedef void (JIT_OPERATION *V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
typedef void (JIT_OPERATION *V_JITOperation_ECliJsf)(ExecState*, CallLinkInfo*, JSFunction*);
+typedef void (JIT_OPERATION *V_JITOperation_ECCJ)(ExecState*, JSCell*, JSCell*, EncodedJSValue);
typedef void (JIT_OPERATION *V_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue);
typedef void (JIT_OPERATION *V_JITOperation_EJ)(ExecState*, EncodedJSValue);
typedef void (JIT_OPERATION *V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, UniquedStringImpl*);
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
