summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-07-14 19:04:52 -0400
committerGaming4JC <g4jc@hyperbola.info>2019-07-18 22:38:46 -0400
commit85aeff765ea921ea2c947fa9d68756eb989b6287 (patch)
tree827d8b39cfe8bfd8a972ef1fa92fa07bd5a8415c
parent449ea84dcc7dffb2f042fc414eb7238ae842d596 (diff)
downloadUXP-85aeff765ea921ea2c947fa9d68756eb989b6287.tar
UXP-85aeff765ea921ea2c947fa9d68756eb989b6287.tar.gz
UXP-85aeff765ea921ea2c947fa9d68756eb989b6287.tar.lz
UXP-85aeff765ea921ea2c947fa9d68756eb989b6287.tar.xz
UXP-85aeff765ea921ea2c947fa9d68756eb989b6287.zip
1344477 - Part 2: Optimize Array.prototype.splice with JSOP_NORVCALL.
-rw-r--r--js/src/jit/CodeGenerator.cpp13
-rw-r--r--js/src/jit/CodeGenerator.h1
-rw-r--r--js/src/jit/InlinableNatives.h1
-rw-r--r--js/src/jit/IonBuilder.h1
-rw-r--r--js/src/jit/Lowering.cpp10
-rw-r--r--js/src/jit/Lowering.h1
-rw-r--r--js/src/jit/MCallOptimize.cpp42
-rw-r--r--js/src/jit/MIR.h21
-rw-r--r--js/src/jit/MOpcodes.h1
-rw-r--r--js/src/jit/VMFunctions.cpp12
-rw-r--r--js/src/jit/VMFunctions.h3
-rw-r--r--js/src/jit/shared/LIR-shared.h28
-rw-r--r--js/src/jit/shared/LOpcodes-shared.h1
-rw-r--r--js/src/jsarray.cpp35
-rw-r--r--js/src/jsarray.h5
-rw-r--r--js/src/vm/SelfHosting.cpp2
16 files changed, 28 insertions, 149 deletions
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 114fc96b3..205812942 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -4440,19 +4440,6 @@ CodeGenerator::visitApplyArrayGeneric(LApplyArrayGeneric* apply)
emitApplyGeneric(apply);
}
-typedef bool (*ArraySpliceDenseFn)(JSContext*, HandleObject, uint32_t, uint32_t);
-static const VMFunction ArraySpliceDenseInfo =
- FunctionInfo<ArraySpliceDenseFn>(ArraySpliceDense, "ArraySpliceDense");
-
-void
-CodeGenerator::visitArraySplice(LArraySplice* lir)
-{
- pushArg(ToRegister(lir->getDeleteCount()));
- pushArg(ToRegister(lir->getStart()));
- pushArg(ToRegister(lir->getObject()));
- callVM(ArraySpliceDenseInfo, lir);
-}
-
void
CodeGenerator::visitBail(LBail* lir)
{
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
index 1c9a7e89b..12f1238ef 100644
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -251,7 +251,6 @@ class CodeGenerator final : public CodeGeneratorSpecific
void emitSetPropertyPolymorphic(LInstruction* lir, Register obj,
Register scratch, const ConstantOrRegister& value);
void visitSetPropertyPolymorphicV(LSetPropertyPolymorphicV* ins);
- void visitArraySplice(LArraySplice* splice);
void visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins);
void visitAbsI(LAbsI* lir);
void visitAtan2D(LAtan2D* lir);
diff --git a/js/src/jit/InlinableNatives.h b/js/src/jit/InlinableNatives.h
index 18535389a..1d0506f74 100644
--- a/js/src/jit/InlinableNatives.h
+++ b/js/src/jit/InlinableNatives.h
@@ -15,7 +15,6 @@
_(ArrayShift) \
_(ArrayPush) \
_(ArraySlice) \
- _(ArraySplice) \
\
_(AtomicsCompareExchange) \
_(AtomicsExchange) \
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index 9e40b3959..1f763a4f2 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -821,7 +821,6 @@ class IonBuilder
InliningStatus inlineArrayPush(CallInfo& callInfo);
InliningStatus inlineArraySlice(CallInfo& callInfo);
InliningStatus inlineArrayJoin(CallInfo& callInfo);
- InliningStatus inlineArraySplice(CallInfo& callInfo);
// Math natives.
InliningStatus inlineMathAbs(CallInfo& callInfo);
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 68417138b..22f1d5f70 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -657,16 +657,6 @@ LIRGenerator::visitAssertRecoveredOnBailout(MAssertRecoveredOnBailout* assertion
}
void
-LIRGenerator::visitArraySplice(MArraySplice* ins)
-{
- LArraySplice* lir = new(alloc()) LArraySplice(useRegisterAtStart(ins->object()),
- useRegisterAtStart(ins->start()),
- useRegisterAtStart(ins->deleteCount()));
- add(lir, ins);
- assignSafepoint(lir, ins);
-}
-
-void
LIRGenerator::visitGetDynamicName(MGetDynamicName* ins)
{
MDefinition* envChain = ins->getEnvironmentChain();
diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
index b096bb143..9342ef471 100644
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -107,7 +107,6 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitCall(MCall* call);
void visitApplyArgs(MApplyArgs* apply);
void visitApplyArray(MApplyArray* apply);
- void visitArraySplice(MArraySplice* splice);
void visitBail(MBail* bail);
void visitUnreachable(MUnreachable* unreachable);
void visitEncodeSnapshot(MEncodeSnapshot* ins);
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 359f04639..5eee30e49 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -85,8 +85,6 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
return inlineArrayPush(callInfo);
case InlinableNative::ArraySlice:
return inlineArraySlice(callInfo);
- case InlinableNative::ArraySplice:
- return inlineArraySplice(callInfo);
// Atomic natives.
case InlinableNative::AtomicsCompareExchange:
@@ -654,46 +652,6 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
}
IonBuilder::InliningStatus
-IonBuilder::inlineArraySplice(CallInfo& callInfo)
-{
- if (callInfo.argc() != 2 || callInfo.constructing()) {
- trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
- return InliningStatus_NotInlined;
- }
-
- // Ensure |this|, argument and result are objects.
- if (getInlineReturnType() != MIRType::Object)
- return InliningStatus_NotInlined;
- if (callInfo.thisArg()->type() != MIRType::Object)
- return InliningStatus_NotInlined;
- if (callInfo.getArg(0)->type() != MIRType::Int32)
- return InliningStatus_NotInlined;
- if (callInfo.getArg(1)->type() != MIRType::Int32)
- return InliningStatus_NotInlined;
-
- callInfo.setImplicitlyUsedUnchecked();
-
- // Specialize arr.splice(start, deleteCount) with unused return value and
- // avoid creating the result array in this case.
- if (!BytecodeIsPopped(pc)) {
- trackOptimizationOutcome(TrackedOutcome::CantInlineGeneric);
- return InliningStatus_NotInlined;
- }
-
- MArraySplice* ins = MArraySplice::New(alloc(),
- callInfo.thisArg(),
- callInfo.getArg(0),
- callInfo.getArg(1));
-
- current->add(ins);
- pushConstant(UndefinedValue());
-
- if (!resumeAfter(ins))
- return InliningStatus_Error;
- return InliningStatus_Inlined;
-}
-
-IonBuilder::InliningStatus
IonBuilder::inlineArrayJoin(CallInfo& callInfo)
{
if (callInfo.argc() != 1 || callInfo.constructing()) {
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index ac55b1150..6c376d528 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -4186,27 +4186,6 @@ class MCallDOMNative : public MCall
virtual void computeMovable() override;
};
-// arr.splice(start, deleteCount) with unused return value.
-class MArraySplice
- : public MTernaryInstruction,
- public Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, IntPolicy<2> >::Data
-{
- private:
-
- MArraySplice(MDefinition* object, MDefinition* start, MDefinition* deleteCount)
- : MTernaryInstruction(object, start, deleteCount)
- { }
-
- public:
- INSTRUCTION_HEADER(ArraySplice)
- TRIVIAL_NEW_WRAPPERS
- NAMED_OPERANDS((0, object), (1, start), (2, deleteCount))
-
- bool possiblyCalls() const override {
- return true;
- }
-};
-
// fun.apply(self, arguments)
class MApplyArgs
: public MAryInstruction<3>,
diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h
index ab37604b4..9e460a2ba 100644
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -69,7 +69,6 @@ namespace jit {
_(Call) \
_(ApplyArgs) \
_(ApplyArray) \
- _(ArraySplice) \
_(Bail) \
_(Unreachable) \
_(EncodeSnapshot) \
diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp
index e58c3f570..1ff7adfd1 100644
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -304,18 +304,6 @@ template bool StringsEqual<true>(JSContext* cx, HandleString lhs, HandleString r
template bool StringsEqual<false>(JSContext* cx, HandleString lhs, HandleString rhs, bool* res);
bool
-ArraySpliceDense(JSContext* cx, HandleObject obj, uint32_t start, uint32_t deleteCount)
-{
- JS::AutoValueArray<4> argv(cx);
- argv[0].setUndefined();
- argv[1].setObject(*obj);
- argv[2].set(Int32Value(start));
- argv[3].set(Int32Value(deleteCount));
-
- return js::array_splice_impl(cx, 2, argv.begin(), false);
-}
-
-bool
ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval)
{
MOZ_ASSERT(obj->is<ArrayObject>());
diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h
index bd65df134..94f741397 100644
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -739,9 +739,6 @@ JSObject* CreateDerivedTypedObj(JSContext* cx, HandleObject descr,
HandleObject owner, int32_t offset);
MOZ_MUST_USE bool
-ArraySpliceDense(JSContext* cx, HandleObject obj, uint32_t start, uint32_t deleteCount);
-
-MOZ_MUST_USE bool
Recompile(JSContext* cx);
MOZ_MUST_USE bool
ForcedRecompile(JSContext* cx);
diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h
index 2b242d2e4..ecf02816e 100644
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -2221,34 +2221,6 @@ class LApplyArrayGeneric : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES
}
};
-class LArraySplice : public LCallInstructionHelper<0, 3, 0>
-{
- public:
- LIR_HEADER(ArraySplice)
-
- LArraySplice(const LAllocation& object, const LAllocation& start,
- const LAllocation& deleteCount)
- {
- setOperand(0, object);
- setOperand(1, start);
- setOperand(2, deleteCount);
- }
-
- MArraySplice* mir() const {
- return mir_->toArraySplice();
- }
-
- const LAllocation* getObject() {
- return getOperand(0);
- }
- const LAllocation* getStart() {
- return getOperand(1);
- }
- const LAllocation* getDeleteCount() {
- return getOperand(2);
- }
-};
-
class LGetDynamicName : public LCallInstructionHelper<BOX_PIECES, 2, 3>
{
public:
diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h
index deae92839..e260d7e94 100644
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -69,7 +69,6 @@
_(NewArrayDynamicLength) \
_(NewTypedArray) \
_(NewTypedArrayDynamicLength) \
- _(ArraySplice) \
_(NewObject) \
_(NewTypedObject) \
_(NewNamedLambdaObject) \
diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp
index 33ff67f36..e618c319f 100644
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -2380,13 +2380,6 @@ CopyDenseElements(JSContext* cx, NativeObject* dst, NativeObject* src,
return DenseElementResult::Success;
}
-/* ES 2016 draft Mar 25, 2016 22.1.3.26. */
-bool
-js::array_splice(JSContext* cx, unsigned argc, Value* vp)
-{
- return array_splice_impl(cx, argc, vp, true);
-}
-
static inline bool
ArraySpliceCopy(JSContext* cx, HandleObject arr, HandleObject obj,
uint32_t actualStart, uint32_t actualDeleteCount)
@@ -2416,8 +2409,8 @@ ArraySpliceCopy(JSContext* cx, HandleObject arr, HandleObject obj,
return SetLengthProperty(cx, arr, actualDeleteCount);
}
-bool
-js::array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueIsUsed)
+static bool
+array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueIsUsed)
{
AutoSPSEntry pseudoFrame(cx->runtime(), "Array.prototype.splice");
CallArgs args = CallArgsFromVp(argc, vp);
@@ -2667,6 +2660,19 @@ js::array_splice_impl(JSContext* cx, unsigned argc, Value* vp, bool returnValueI
return true;
}
+/* ES 2016 draft Mar 25, 2016 22.1.3.26. */
+bool
+js::array_splice(JSContext* cx, unsigned argc, Value* vp)
+{
+ return array_splice_impl(cx, argc, vp, true);
+}
+
+static bool
+array_splice_noRetVal(JSContext* cx, unsigned argc, Value* vp)
+{
+ return array_splice_impl(cx, argc, vp, false);
+}
+
struct SortComparatorIndexes
{
bool operator()(uint32_t a, uint32_t b, bool* lessOrEqualp) {
@@ -3084,6 +3090,15 @@ array_of(JSContext* cx, unsigned argc, Value* vp)
return true;
}
+const JSJitInfo js::array_splice_info = {
+ { (JSJitGetterOp)array_splice_noRetVal },
+ { 0 }, /* unused */
+ { 0 }, /* unused */
+ JSJitInfo::IgnoresReturnValueNative,
+ JSJitInfo::AliasEverything,
+ JSVAL_TYPE_UNDEFINED,
+};
+
static const JSFunctionSpec array_methods[] = {
#if JS_HAS_TOSOURCE
JS_FN(js_toSource_str, array_toSource, 0,0),
@@ -3099,7 +3114,7 @@ static const JSFunctionSpec array_methods[] = {
JS_INLINABLE_FN("pop", array_pop, 0,0, ArrayPop),
JS_INLINABLE_FN("shift", array_shift, 0,0, ArrayShift),
JS_FN("unshift", array_unshift, 1,0),
- JS_INLINABLE_FN("splice", array_splice, 2,0, ArraySplice),
+ JS_FNINFO("splice", array_splice, &array_splice_info, 2,0),
/* Pythonic sequence methods. */
JS_SELF_HOSTED_FN("concat", "ArrayConcat", 1,0),
diff --git a/js/src/jsarray.h b/js/src/jsarray.h
index 00b475a8e..d0084731f 100644
--- a/js/src/jsarray.h
+++ b/js/src/jsarray.h
@@ -147,9 +147,6 @@ extern bool
array_pop(JSContext* cx, unsigned argc, js::Value* vp);
extern bool
-array_splice_impl(JSContext* cx, unsigned argc, js::Value* vp, bool pop);
-
-extern bool
array_join(JSContext* cx, unsigned argc, js::Value* vp);
extern void
@@ -173,6 +170,8 @@ array_reverse(JSContext* cx, unsigned argc, js::Value* vp);
extern bool
array_splice(JSContext* cx, unsigned argc, js::Value* vp);
+extern const JSJitInfo array_splice_info;
+
/*
* Append the given (non-hole) value to the end of an array. The array must be
* a newborn array -- that is, one which has not been exposed to script for
diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp
index 2ff20cfea..792a00490 100644
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2154,7 +2154,7 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_INLINABLE_FN("std_Array_slice", array_slice, 2,0, ArraySlice),
JS_FN("std_Array_sort", array_sort, 1,0),
JS_FN("std_Array_reverse", array_reverse, 0,0),
- JS_INLINABLE_FN("std_Array_splice", array_splice, 2,0, ArraySplice),
+ JS_FNINFO("std_Array_splice", array_splice, &array_splice_info, 2,0),
JS_FN("std_Date_now", date_now, 0,0),
JS_FN("std_Date_valueOf", date_valueOf, 0,0),