author | Jan de Mooij <jdemooij@mozilla.com> |
Tue, 12 Mar 2019 14:04:39 +0000 (2019-03-12) | |
changeset 463654 | 1e2091a92a1db1d5f602cb3a469571fd517c5ed6 |
parent 463653 | 4e5dbbdb10f31f6cf8460011c46a47dd4d135b7f |
child 463655 | 5aee215799365ba80bbede0bf44edf24c9ff365a |
push id | 80272 |
push user | jdemooij@mozilla.com |
push date | Tue, 12 Mar 2019 14:54:04 +0000 (2019-03-12) |
treeherder | autoland@6382f22140dd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | tcampbell |
bugs | 1530937 |
milestone | 67.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/BaselineCacheIRCompiler.cpp +++ b/js/src/jit/BaselineCacheIRCompiler.cpp @@ -10,16 +10,17 @@ #include "jit/Linker.h" #include "jit/SharedICHelpers.h" #include "jit/VMFunctions.h" #include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" #include "jit/MacroAssembler-inl.h" #include "jit/SharedICHelpers-inl.h" +#include "jit/VMFunctionList-inl.h" #include "vm/JSContext-inl.h" #include "vm/Realm-inl.h" using namespace js; using namespace js::jit; using mozilla::Maybe; @@ -33,19 +34,25 @@ Address CacheRegisterAllocator::addressO } // BaselineCacheIRCompiler compiles CacheIR to BaselineIC native code. class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler { bool inStubFrame_; bool makesGCCalls_; BaselineCacheIRStubKind kind_; - void callVM(MacroAssembler& masm, const VMFunction& fun); + void callVMInternal(MacroAssembler& masm, VMFunctionId id); void tailCallVM(MacroAssembler& masm, const VMFunction& fun); + template <typename Fn, Fn fn> + void callVM(MacroAssembler& masm) { + VMFunctionId id = VMFunctionToId<Fn, fn>::id; + callVMInternal(masm, id); + } + MOZ_MUST_USE bool callTypeUpdateIC(Register obj, ValueOperand val, Register scratch, LiveGeneralRegisterSet saveRegs); MOZ_MUST_USE bool emitStoreSlotShared(bool isFixed); MOZ_MUST_USE bool emitAddAndStoreSlotShared(CacheOp op); public: @@ -136,22 +143,22 @@ class MOZ_RAII AutoStubFrame { EmitBaselineLeaveStubFrame(masm, calledIntoIon); } #ifdef DEBUG ~AutoStubFrame() { MOZ_ASSERT(!compiler.inStubFrame_); } #endif }; -void BaselineCacheIRCompiler::callVM(MacroAssembler& masm, - const VMFunction& fun) { +void BaselineCacheIRCompiler::callVMInternal(MacroAssembler& masm, + VMFunctionId id) { MOZ_ASSERT(inStubFrame_); - TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(fun); - MOZ_ASSERT(fun.expectTailCall == NonTailCall); + TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(id); + MOZ_ASSERT(GetVMFunction(id).expectTailCall == NonTailCall); EmitBaselineCallVM(code, masm); } void BaselineCacheIRCompiler::tailCallVM(MacroAssembler& masm, const VMFunction& fun) { MOZ_ASSERT(!inStubFrame_); @@ -574,21 +581,16 @@ bool BaselineCacheIRCompiler::emitCallSc if (isCrossRealm) { masm.switchToBaselineFrameRealm(R1.scratchReg()); } return true; } -typedef bool (*CallNativeGetterFn)(JSContext*, HandleFunction, HandleObject, - MutableHandleValue); -static const VMFunction CallNativeGetterInfo = - FunctionInfo<CallNativeGetterFn>(CallNativeGetter, "CallNativeGetter"); - bool BaselineCacheIRCompiler::emitCallNativeGetterResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); Address getterAddr(stubAddress(reader.stubOffset())); AutoScratchRegister scratch(allocator, masm); allocator.discardStack(masm); @@ -597,17 +599,19 @@ bool BaselineCacheIRCompiler::emitCallNa stubFrame.enter(masm, scratch); // Load the callee in the scratch register. masm.loadPtr(getterAddr, scratch); masm.Push(obj); masm.Push(scratch); - callVM(masm, CallNativeGetterInfo); + using Fn = + bool (*)(JSContext*, HandleFunction, HandleObject, MutableHandleValue); + callVM<Fn, CallNativeGetter>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallProxyGetResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -621,17 +625,18 @@ bool BaselineCacheIRCompiler::emitCallPr stubFrame.enter(masm, scratch); // Load the jsid in the scratch register. masm.loadPtr(idAddr, scratch); masm.Push(scratch); masm.Push(obj); - callVM(masm, ProxyGetPropertyInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleId, MutableHandleValue); + callVM<Fn, ProxyGetProperty>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallProxyGetByValueResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -642,17 +647,19 @@ bool BaselineCacheIRCompiler::emitCallPr allocator.discardStack(masm); AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(idVal); masm.Push(obj); - callVM(masm, ProxyGetPropertyByValueInfo); + using Fn = + bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue); + callVM<Fn, ProxyGetPropertyByValue>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallProxyHasPropResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -664,20 +671,22 @@ bool BaselineCacheIRCompiler::emitCallPr allocator.discardStack(masm); AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(idVal); masm.Push(obj); + using Fn = + bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue); if (hasOwn) { - callVM(masm, ProxyHasOwnInfo); + callVM<Fn, ProxyHasOwn>(masm); } else { - callVM(masm, ProxyHasInfo); + callVM<Fn, ProxyHas>(masm); } stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallNativeGetElementResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); @@ -690,17 +699,19 @@ bool BaselineCacheIRCompiler::emitCallNa AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(index); masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); masm.Push(obj); - callVM(masm, NativeGetElementInfo); + using Fn = bool (*)(JSContext*, HandleNativeObject, HandleValue, int32_t, + MutableHandleValue); + callVM<Fn, NativeGetElement>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoOutputRegister output(*this); @@ -870,17 +881,19 @@ bool BaselineCacheIRCompiler::emitCallSt // Load the group in the scratch register. masm.loadPtr(groupAddr, scratch); masm.Push(Imm32(INT32_MAX)); masm.Push(scratch); masm.Push(sep); masm.Push(str); - callVM(masm, StringSplitHelperInfo); + using Fn = bool (*)(JSContext*, HandleString, HandleString, HandleObjectGroup, + uint32_t limit, MutableHandleValue); + callVM<Fn, StringSplitHelper>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCompareStringResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoOutputRegister output(*this); @@ -904,18 +917,23 @@ bool BaselineCacheIRCompiler::emitCompar masm.bind(&slow); { AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(right); masm.Push(left); - callVM(masm, (op == JSOP_EQ || op == JSOP_STRICTEQ) ? StringsEqualInfo - : StringsNotEqualInfo); + using Fn = bool (*)(JSContext*, HandleString, HandleString, bool*); + if (op == JSOP_EQ || op == JSOP_STRICTEQ) { + callVM<Fn, jit::StringsEqual<true>>(masm); + } else { + callVM<Fn, jit::StringsEqual<false>>(masm); + } + stubFrame.leave(masm); masm.mov(ReturnReg, scratch); } masm.bind(&done); masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg()); return true; } @@ -961,17 +979,19 @@ bool BaselineCacheIRCompiler::callTypeUp masm.Push(val); masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); masm.Push(ICStubReg); // Load previous frame pointer, push BaselineFrame*. masm.loadPtr(Address(BaselineFrameReg, 0), scratch); masm.pushBaselineFramePtr(scratch, scratch); - callVM(masm, DoTypeUpdateFallbackInfo); + using Fn = bool (*)(JSContext*, BaselineFrame*, ICUpdatedStub*, HandleValue, + HandleValue); + callVM<Fn, DoTypeUpdateFallback>(masm); masm.PopRegsInMask(saveRegs); stubFrame.leave(masm); masm.bind(&done); return true; } @@ -1629,21 +1649,16 @@ bool BaselineCacheIRCompiler::emitStoreT masm.bind(&fail); masm.pop(scratch2); masm.jump(failure->label()); masm.bind(&done); return true; } -typedef bool (*CallNativeSetterFn)(JSContext*, HandleFunction, HandleObject, - HandleValue); -static const VMFunction CallNativeSetterInfo = - FunctionInfo<CallNativeSetterFn>(CallNativeSetter, "CallNativeSetter"); - bool BaselineCacheIRCompiler::emitCallNativeSetter() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); Address setterAddr(stubAddress(reader.stubOffset())); ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId()); AutoScratchRegister scratch(allocator, masm); @@ -1654,17 +1669,18 @@ bool BaselineCacheIRCompiler::emitCallNa // Load the callee in the scratch register. masm.loadPtr(setterAddr, scratch); masm.Push(val); masm.Push(obj); masm.Push(scratch); - callVM(masm, CallNativeSetterInfo); + using Fn = bool (*)(JSContext*, HandleFunction, HandleObject, HandleValue); + callVM<Fn, CallNativeSetter>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallScriptedSetter() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoScratchRegister scratch1(allocator, masm); @@ -1756,17 +1772,18 @@ bool BaselineCacheIRCompiler::emitCallSe AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(obj); - callVM(masm, SetArrayLengthInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, bool); + callVM<Fn, jit::SetArrayLength>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallProxySet() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -1784,17 +1801,18 @@ bool BaselineCacheIRCompiler::emitCallPr // Load the jsid in the scratch register. masm.loadPtr(idAddr, scratch); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(scratch); masm.Push(obj); - callVM(masm, ProxySetPropertyInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleId, HandleValue, bool); + callVM<Fn, ProxySetProperty>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallProxySetByValue() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -1817,17 +1835,18 @@ bool BaselineCacheIRCompiler::emitCallPr masm.loadPtr(Address(BaselineFrameReg, 0), obj); masm.loadPtr(Address(obj, scratchOffset), obj); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(idVal); masm.Push(obj); - callVM(masm, ProxySetPropertyByValueInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValue, bool); + callVM<Fn, ProxySetPropertyByValue>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -1841,17 +1860,19 @@ bool BaselineCacheIRCompiler::emitCallAd AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(id); masm.Push(obj); - callVM(masm, AddOrUpdateSparseElementHelperInfo); + using Fn = bool (*)(JSContext * cx, HandleArrayObject obj, int32_t int_id, + HandleValue v, bool strict); + callVM<Fn, AddOrUpdateSparseElementHelper>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallGetSparseElementResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -1861,17 +1882,19 @@ bool BaselineCacheIRCompiler::emitCallGe allocator.discardStack(masm); AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.Push(id); masm.Push(obj); - callVM(masm, GetSparseElementHelperInfo); + using Fn = bool (*)(JSContext * cx, HandleArrayObject obj, int32_t int_id, + MutableHandleValue result); + callVM<Fn, GetSparseElementHelper>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitMegamorphicSetElement() { JitSpew(JitSpew_Codegen, __FUNCTION__); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -1895,17 +1918,19 @@ bool BaselineCacheIRCompiler::emitMegamo masm.loadPtr(Address(obj, scratchOffset), obj); masm.Push(Imm32(strict)); masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); masm.Push(val); masm.Push(idVal); masm.Push(obj); - callVM(masm, SetObjectElementInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValue, + HandleValue, bool); + callVM<Fn, SetObjectElementWithReceiver>(masm); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitTypeMonitorResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); allocator.discardStack(masm); @@ -2360,17 +2385,18 @@ bool BaselineCacheIRCompiler::emitCallSt allocator.discardStack(masm); AutoStubFrame stubFrame(*this); stubFrame.enter(masm, scratch); masm.push(rhs); masm.push(lhs); - callVM(masm, ConcatStringsInfo); + using Fn = JSString* (*)(JSContext*, HandleString, HandleString); + callVM<Fn, ConcatStrings<CanGC>>(masm); masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg()); stubFrame.leave(masm); return true; } bool BaselineCacheIRCompiler::emitCallStringObjectConcatResult() {
--- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -1686,19 +1686,19 @@ bool ICUpdatedStub::addUpdateStubForValu } return true; } // // TypeUpdate_Fallback // -static bool DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, - ICUpdatedStub* stub, HandleValue objval, - HandleValue value) { +bool DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, + ICUpdatedStub* stub, HandleValue objval, + HandleValue value) { // This can get called from optimized stubs. Therefore it is not allowed to // gc. JS::AutoCheckCannotGC nogc; FallbackICSpew(cx, stub->getChainFallback(), "TypeUpdate(%s)", ICStub::KindString(stub->kind())); MOZ_ASSERT(stub->isCacheIR_Updated());
--- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -2714,12 +2714,16 @@ void EmitICUnboxedPreBarrier(MacroAssemb // Write an arbitrary value to a typed array or typed object address at dest. // If the value could not be converted to the appropriate format, jump to // failure. template <typename T> void StoreToTypedArray(JSContext* cx, MacroAssembler& masm, Scalar::Type type, const ValueOperand& value, const T& dest, Register scratch, Label* failure); +extern bool DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, + ICUpdatedStub* stub, HandleValue objval, + HandleValue value); + } // namespace jit } // namespace js #endif /* jit_BaselineIC_h */
--- a/js/src/jit/IonCacheIRCompiler.cpp +++ b/js/src/jit/IonCacheIRCompiler.cpp @@ -14,16 +14,17 @@ #include "jit/Linker.h" #include "jit/SharedICHelpers.h" #include "jit/VMFunctions.h" #include "proxy/DeadObjectProxy.h" #include "proxy/Proxy.h" #include "jit/JSJitFrameIter-inl.h" #include "jit/MacroAssembler-inl.h" +#include "jit/VMFunctionList-inl.h" #include "vm/Realm-inl.h" #include "vm/TypeInference-inl.h" using namespace js; using namespace js::jit; using mozilla::DebugOnly; using mozilla::Maybe; @@ -98,17 +99,23 @@ class MOZ_RAII IonCacheIRCompiler : publ readStubInt64(offset, StubField::Type::DOMExpandoGeneration); uint64_t* ptr = reinterpret_cast<uint64_t*>(stub_->stubDataStart() + offset); MOZ_ASSERT(*ptr == generation); return ptr; } void prepareVMCall(MacroAssembler& masm, const AutoSaveLiveRegisters&); - void callVM(MacroAssembler& masm, const VMFunction& fun); + void callVMInternal(MacroAssembler& masm, VMFunctionId id); + + template <typename Fn, Fn fn> + void callVM(MacroAssembler& masm) { + VMFunctionId id = VMFunctionToId<Fn, fn>::id; + callVMInternal(masm, id); + } MOZ_MUST_USE bool emitAddAndStoreSlotShared(CacheOp op); bool needsPostBarrier() const { return ic_->asSetPropertyIC()->needsPostBarrier(); } void pushStubCodePointer() { @@ -319,21 +326,22 @@ void IonCacheIRCompiler::prepareVMCall(M masm.Push(Imm32(descriptor)); masm.Push(ImmPtr(GetReturnAddressToIonCode(cx_))); #ifdef DEBUG calledPrepareVMCall_ = true; #endif } -void IonCacheIRCompiler::callVM(MacroAssembler& masm, const VMFunction& fun) { +void IonCacheIRCompiler::callVMInternal(MacroAssembler& masm, VMFunctionId id) { MOZ_ASSERT(calledPrepareVMCall_); - TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(fun); - + TrampolinePtr code = cx_->runtime()->jitRuntime()->getVMWrapper(id); + + const VMFunctionData& fun = GetVMFunction(id); uint32_t frameSize = fun.explicitStackSlots() * sizeof(void*); uint32_t descriptor = MakeFrameDescriptor(frameSize, FrameType::IonICCall, ExitFrameLayout::Size()); masm.Push(Imm32(descriptor)); masm.callJit(code); // Remove rest of the frame left on the stack. We remove the return address // which is implicitly popped when returning. @@ -1140,17 +1148,19 @@ bool IonCacheIRCompiler::emitCallProxyGe allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(idVal); masm.Push(obj); - callVM(masm, ProxyGetPropertyByValueInfo); + using Fn = + bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue); + callVM<Fn, ProxyGetPropertyByValue>(masm); masm.storeCallResultValue(output); return true; } bool IonCacheIRCompiler::emitCallProxyHasPropResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); @@ -1162,20 +1172,22 @@ bool IonCacheIRCompiler::emitCallProxyHa allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(idVal); masm.Push(obj); + using Fn = + bool (*)(JSContext*, HandleObject, HandleValue, MutableHandleValue); if (hasOwn) { - callVM(masm, ProxyHasOwnInfo); + callVM<Fn, ProxyHasOwn>(masm); } else { - callVM(masm, ProxyHasInfo); + callVM<Fn, ProxyHas>(masm); } masm.storeCallResultValue(output); return true; } bool IonCacheIRCompiler::emitCallNativeGetElementResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); @@ -1188,17 +1200,19 @@ bool IonCacheIRCompiler::emitCallNativeG allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(index); masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); masm.Push(obj); - callVM(masm, NativeGetElementInfo); + using Fn = bool (*)(JSContext*, HandleNativeObject, HandleValue, int32_t, + MutableHandleValue); + callVM<Fn, NativeGetElement>(masm); masm.storeCallResultValue(output); return true; } bool IonCacheIRCompiler::emitLoadUnboxedPropertyResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoOutputRegister output(*this); @@ -1287,17 +1301,19 @@ bool IonCacheIRCompiler::emitCallStringS prepareVMCall(masm, save); masm.Push(str); masm.Push(sep); masm.Push(ImmGCPtr(group)); masm.Push(Imm32(INT32_MAX)); - callVM(masm, StringSplitHelperInfo); + using Fn = bool (*)(JSContext*, HandleString, HandleString, HandleObjectGroup, + uint32_t limit, MutableHandleValue); + callVM<Fn, StringSplitHelper>(masm); masm.storeCallResultValue(output); return true; } bool IonCacheIRCompiler::emitCompareStringResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); @@ -1315,18 +1331,22 @@ bool IonCacheIRCompiler::emitCompareStri masm.jump(&done); masm.bind(&slow); prepareVMCall(masm, save); masm.Push(right); masm.Push(left); - callVM(masm, (op == JSOP_EQ || op == JSOP_STRICTEQ) ? StringsEqualInfo - : StringsNotEqualInfo); + using Fn = bool (*)(JSContext*, HandleString, HandleString, bool*); + if (op == JSOP_EQ || op == JSOP_STRICTEQ) { + callVM<Fn, jit::StringsEqual<true>>(masm); + } else { + callVM<Fn, jit::StringsEqual<false>>(masm); + } masm.storeCallBoolResult(output.typedReg().gpr()); masm.bind(&done); return true; } static bool GroupHasPropertyTypes(ObjectGroup* group, jsid* id, Value* v) { AutoUnsafeCallWithABI unsafe; @@ -2184,17 +2204,18 @@ bool IonCacheIRCompiler::emitCallSetArra allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(obj); - callVM(masm, SetArrayLengthInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, bool); + callVM<Fn, jit::SetArrayLength>(masm); return true; } bool IonCacheIRCompiler::emitCallProxySet() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -2208,17 +2229,18 @@ bool IonCacheIRCompiler::emitCallProxySe allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(id, scratch); masm.Push(obj); - callVM(masm, ProxySetPropertyInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleId, HandleValue, bool); + callVM<Fn, ProxySetProperty>(masm); return true; } bool IonCacheIRCompiler::emitCallProxySetByValue() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -2231,17 +2253,18 @@ bool IonCacheIRCompiler::emitCallProxySe allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(idVal); masm.Push(obj); - callVM(masm, ProxySetPropertyByValueInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValue, bool); + callVM<Fn, ProxySetPropertyByValue>(masm); return true; } bool IonCacheIRCompiler::emitCallAddOrUpdateSparseElementHelper() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); @@ -2252,34 +2275,38 @@ bool IonCacheIRCompiler::emitCallAddOrUp allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(Imm32(strict)); masm.Push(val); masm.Push(id); masm.Push(obj); - callVM(masm, AddOrUpdateSparseElementHelperInfo); + using Fn = bool (*)(JSContext * cx, HandleArrayObject obj, int32_t int_id, + HandleValue v, bool strict); + callVM<Fn, AddOrUpdateSparseElementHelper>(masm); return true; } bool IonCacheIRCompiler::emitCallGetSparseElementResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); Register id = allocator.useRegister(masm, reader.int32OperandId()); allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(id); masm.Push(obj); - callVM(masm, GetSparseElementHelperInfo); + using Fn = bool (*)(JSContext * cx, HandleArrayObject obj, int32_t int_id, + MutableHandleValue result); + callVM<Fn, GetSparseElementHelper>(masm); masm.storeCallResultValue(output); return true; } bool IonCacheIRCompiler::emitMegamorphicSetElement() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); @@ -2295,17 +2322,19 @@ bool IonCacheIRCompiler::emitMegamorphic prepareVMCall(masm, save); masm.Push(Imm32(strict)); masm.Push(TypedOrValueRegister(MIRType::Object, AnyRegister(obj))); masm.Push(val); masm.Push(idVal); masm.Push(obj); - callVM(masm, SetObjectElementInfo); + using Fn = bool (*)(JSContext*, HandleObject, HandleValue, HandleValue, + HandleValue, bool); + callVM<Fn, SetObjectElementWithReceiver>(masm); return true; } bool IonCacheIRCompiler::emitLoadTypedObjectResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoOutputRegister output(*this); Register obj = allocator.useRegister(masm, reader.objOperandId()); AutoScratchRegister scratch1(allocator, masm); @@ -2574,39 +2603,35 @@ bool IonCacheIRCompiler::emitCallStringC allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(rhs); masm.Push(lhs); - callVM(masm, ConcatStringsInfo); + using Fn = JSString* (*)(JSContext*, HandleString, HandleString); + callVM<Fn, ConcatStrings<CanGC>>(masm); masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, output.valueReg()); return true; } -typedef bool (*DoConcatStringObjectFn)(JSContext*, HandleValue, HandleValue, - MutableHandleValue); -const VMFunction DoIonConcatStringObjectInfo = - FunctionInfo<DoConcatStringObjectFn>(DoConcatStringObject, - "DoIonConcatStringObject"); - bool IonCacheIRCompiler::emitCallStringObjectConcatResult() { JitSpew(JitSpew_Codegen, __FUNCTION__); AutoSaveLiveRegisters save(*this); AutoOutputRegister output(*this); ValueOperand lhs = allocator.useValueRegister(masm, reader.valOperandId()); ValueOperand rhs = allocator.useValueRegister(masm, reader.valOperandId()); allocator.discardStack(masm); prepareVMCall(masm, save); masm.Push(rhs); masm.Push(lhs); - callVM(masm, DoIonConcatStringObjectInfo); + using Fn = bool (*)(JSContext*, HandleValue, HandleValue, MutableHandleValue); + callVM<Fn, DoConcatStringObject>(masm); masm.storeCallResultValue(output); return true; }
--- a/js/src/jit/VMFunctionList-inl.h +++ b/js/src/jit/VMFunctionList-inl.h @@ -21,16 +21,17 @@ namespace js { namespace jit { // List of all VM functions to be used with callVM. Each entry stores the name // (must be unique, used for the VMFunctionId enum and profiling) and the C++ // function to be called. This list must be sorted on the name field. #define VMFUNCTION_LIST(_) \ + _(AddOrUpdateSparseElementHelper, js::AddOrUpdateSparseElementHelper) \ _(AddValues, js::AddValues) \ _(ArgumentsObjectCreateForIon, js::ArgumentsObject::createForIon) \ _(ArrayConstructorOneArg, js::ArrayConstructorOneArg) \ _(ArrayJoin, js::jit::ArrayJoin) \ _(ArrayPopDense, js::jit::ArrayPopDense) \ _(ArrayPushDense, js::jit::ArrayPushDense) \ _(ArrayShiftDense, js::jit::ArrayShiftDense) \ _(ArraySliceDense, js::ArraySliceDense) \ @@ -44,16 +45,18 @@ namespace jit { _(BitAnd, js::BitAnd) \ _(BitLsh, js::BitLsh) \ _(BitNot, js::BitNot) \ _(BitOr, js::BitOr) \ _(BitRsh, js::BitRsh) \ _(BitXor, js::BitXor) \ _(BoxNonStrictThis, js::BoxNonStrictThis) \ _(BuiltinProtoOperation, js::BuiltinProtoOperation) \ + _(CallNativeGetter, js::jit::CallNativeGetter) \ + _(CallNativeSetter, js::jit::CallNativeSetter) \ _(CharCodeAt, js::jit::CharCodeAt) \ _(CheckClassHeritageOperation, js::CheckClassHeritageOperation) \ _(CheckGlobalOrEvalDeclarationConflicts, \ js::CheckGlobalOrEvalDeclarationConflicts) \ _(CheckIsCallable, js::jit::CheckIsCallable) \ _(CheckOverRecursed, js::jit::CheckOverRecursed) \ _(CheckOverRecursedBaseline, js::jit::CheckOverRecursedBaseline) \ _(CloneRegExpObject, js::CloneRegExpObject) \ @@ -81,31 +84,34 @@ namespace jit { _(DefVarOperation, js::DefVarOperation) \ _(DeleteElementNonStrict, js::DeleteElementJit<false>) \ _(DeleteElementStrict, js::DeleteElementJit<true>) \ _(DeleteNameOperation, js::DeleteNameOperation) \ _(DeletePropertyNonStrict, js::DeletePropertyJit<false>) \ _(DeletePropertyStrict, js::DeletePropertyJit<true>) \ _(DirectEvalStringFromIon, js::DirectEvalStringFromIon) \ _(DivValues, js::DivValues) \ + _(DoConcatStringObject, js::jit::DoConcatStringObject) \ _(DoToNumber, js::jit::DoToNumber) \ _(DoToNumeric, js::jit::DoToNumeric) \ + _(DoTypeUpdateFallback, js::jit::DoTypeUpdateFallback) \ _(EnterWith, js::jit::EnterWith) \ _(FinalSuspend, js::jit::FinalSuspend) \ _(FinishBoundFunctionInit, JSFunction::finishBoundFunctionInit) \ _(FreshenLexicalEnv, js::jit::FreshenLexicalEnv) \ _(FunWithProtoOperation, js::FunWithProtoOperation) \ _(GetAndClearException, js::GetAndClearException) \ _(GetElementOperation, js::GetElementOperation) \ _(GetFirstDollarIndexRaw, js::GetFirstDollarIndexRaw) \ _(GetImportOperation, js::GetImportOperation) \ _(GetIntrinsicValue, js::jit::GetIntrinsicValue) \ _(GetNonSyntacticGlobalThis, js::GetNonSyntacticGlobalThis) \ _(GetOrCreateModuleMetaObject, js::GetOrCreateModuleMetaObject) \ _(GetPrototypeOf, js::jit::GetPrototypeOf) \ + _(GetSparseElementHelper, js::GetSparseElementHelper) \ _(GetValueProperty, js::GetValueProperty) \ _(GlobalNameConflictsCheckFromIon, js::jit::GlobalNameConflictsCheckFromIon) \ _(GreaterThan, js::jit::GreaterThan) \ _(GreaterThanOrEqual, js::jit::GreaterThanOrEqual) \ _(HomeObjectSuperBase, js::HomeObjectSuperBase) \ _(ImplicitThisOperation, js::ImplicitThisOperation) \ _(ImportMetaOperation, js::ImportMetaOperation) \ _(InitElemGetterSetterOperation, js::InitElemGetterSetterOperation) \ @@ -147,16 +153,17 @@ namespace jit { _(LooselyEqual, js::jit::LooselyEqual<true>) \ _(LooselyNotEqual, js::jit::LooselyEqual<false>) \ _(MakeDefaultConstructor, js::MakeDefaultConstructor) \ _(ModValues, js::ModValues) \ _(MulValues, js::MulValues) \ _(MutatePrototype, js::jit::MutatePrototype) \ _(NamedLambdaObjectCreateTemplateObject, \ js::NamedLambdaObject::createTemplateObject) \ + _(NativeGetElement, js::NativeGetElement) \ _(NewArgumentsObject, js::jit::NewArgumentsObject) \ _(NewArrayCopyOnWriteOperation, js::NewArrayCopyOnWriteOperation) \ _(NewArrayIteratorObject, js::NewArrayIteratorObject) \ _(NewArrayOperation, js::NewArrayOperation) \ _(NewArrayWithGroup, js::NewArrayWithGroup) \ _(NewCallObject, js::jit::NewCallObject) \ _(NewDenseCopyOnWriteArray, js::NewDenseCopyOnWriteArray) \ _(NewObjectOperation, js::NewObjectOperation) \ @@ -176,37 +183,45 @@ namespace jit { _(ObjectWithProtoOperation, js::ObjectWithProtoOperation) \ _(OnDebuggerStatement, js::jit::OnDebuggerStatement) \ _(OperatorInI, js::jit::OperatorInI) \ _(OptimizeSpreadCall, js::OptimizeSpreadCall) \ _(PopLexicalEnv, js::jit::PopLexicalEnv) \ _(PopVarEnv, js::jit::PopVarEnv) \ _(PowValues, js::PowValues) \ _(ProcessCallSiteObjOperation, js::ProcessCallSiteObjOperation) \ + _(ProxyGetProperty, js::ProxyGetProperty) \ + _(ProxyGetPropertyByValue, js::ProxyGetPropertyByValue) \ + _(ProxyHas, js::ProxyHas) \ + _(ProxyHasOwn, js::ProxyHasOwn) \ + _(ProxySetProperty, js::ProxySetProperty) \ + _(ProxySetPropertyByValue, js::ProxySetPropertyByValue) \ _(PushLexicalEnv, js::jit::PushLexicalEnv) \ _(PushVarEnv, js::jit::PushVarEnv) \ _(RecreateLexicalEnv, js::jit::RecreateLexicalEnv) \ _(RegExpMatcherRaw, js::RegExpMatcherRaw) \ _(RegExpSearcherRaw, js::RegExpSearcherRaw) \ _(RegExpTesterRaw, js::RegExpTesterRaw) \ _(SameValue, js::SameValue) \ + _(SetArrayLength, js::jit::SetArrayLength) \ _(SetDenseElement, js::jit::SetDenseElement) \ _(SetFunctionName, js::SetFunctionName) \ _(SetIntrinsicOperation, js::SetIntrinsicOperation) \ _(SetObjectElementWithReceiver, js::SetObjectElementWithReceiver) \ _(SetProperty, js::jit::SetProperty) \ _(SetPropertySuper, js::SetPropertySuper) \ _(SingletonObjectLiteralOperation, js::SingletonObjectLiteralOperation) \ _(StartDynamicModuleImport, js::StartDynamicModuleImport) \ _(StrictlyEqual, js::jit::StrictlyEqual<true>) \ _(StrictlyNotEqual, js::jit::StrictlyEqual<false>) \ _(StringFlatReplaceString, js::StringFlatReplaceString) \ _(StringFromCharCode, js::jit::StringFromCharCode) \ _(StringFromCodePoint, js::jit::StringFromCodePoint) \ _(StringReplace, js::jit::StringReplace) \ + _(StringSplitHelper, js::jit::StringSplitHelper) \ _(StringSplitString, js::StringSplitString) \ _(StringToLowerCase, js::StringToLowerCase) \ _(StringToNumber, js::StringToNumber) \ _(StringToUpperCase, js::StringToUpperCase) \ _(StringsEqual, js::jit::StringsEqual<true>) \ _(StringsNotEqual, js::jit::StringsEqual<false>) \ _(SubValues, js::SubValues) \ _(SubstringKernel, js::SubstringKernel) \
--- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -382,40 +382,28 @@ bool StringsEqual(JSContext* cx, HandleS return true; } template bool StringsEqual<true>(JSContext* cx, HandleString lhs, HandleString rhs, bool* res); template bool StringsEqual<false>(JSContext* cx, HandleString lhs, HandleString rhs, bool* res); -typedef bool (*StringCompareFn)(JSContext*, HandleString, HandleString, bool*); -const VMFunction StringsEqualInfo = - FunctionInfo<StringCompareFn>(jit::StringsEqual<true>, "StringsEqual"); -const VMFunction StringsNotEqualInfo = - FunctionInfo<StringCompareFn>(jit::StringsEqual<false>, "StringsEqual"); - bool StringSplitHelper(JSContext* cx, HandleString str, HandleString sep, HandleObjectGroup group, uint32_t limit, MutableHandleValue result) { JSObject* resultObj = StringSplitString(cx, group, str, sep, limit); if (!resultObj) { return false; } result.setObject(*resultObj); return true; } -typedef bool (*StringSplitHelperFn)(JSContext*, HandleString, HandleString, - HandleObjectGroup, uint32_t limit, - MutableHandleValue); -const VMFunction StringSplitHelperInfo = - FunctionInfo<StringSplitHelperFn>(StringSplitHelper, "StringSplitHelper"); - bool ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval) { MOZ_ASSERT(obj->is<ArrayObject>()); AutoDetectInvalidation adi(cx, rval); JS::AutoValueArray<2> argv(cx); argv[0].setUndefined(); argv[1].setObject(*obj); @@ -530,20 +518,16 @@ bool SetArrayLength(JSContext* cx, Handl } } else { MOZ_ALWAYS_TRUE(result.fail(JSMSG_READ_ONLY)); } return result.checkStrictErrorOrWarning(cx, obj, id, strict); } -typedef bool (*SetArrayLengthFn)(JSContext*, HandleObject, HandleValue, bool); -const VMFunction SetArrayLengthInfo = - FunctionInfo<SetArrayLengthFn>(SetArrayLength, "SetArrayLength"); - bool CharCodeAt(JSContext* cx, HandleString str, int32_t index, uint32_t* code) { char16_t c; if (!str->getChar(cx, index, &c)) { return false; } *code = c; return true; @@ -1840,25 +1824,16 @@ bool GetPrototypeOf(JSContext* cx, Handl RootedObject proto(cx); if (!GetPrototype(cx, target, &proto)) { return false; } rval.setObjectOrNull(proto); return true; } -typedef bool (*SetObjectElementFn)(JSContext*, HandleObject, HandleValue, - HandleValue, HandleValue, bool); -const VMFunction SetObjectElementInfo = FunctionInfo<SetObjectElementFn>( - js::SetObjectElementWithReceiver, "SetObjectElementWithReceiver"); - -typedef JSString* (*ConcatStringsFn)(JSContext*, HandleString, HandleString); -const VMFunction ConcatStringsInfo = - FunctionInfo<ConcatStringsFn>(ConcatStrings<CanGC>, "ConcatStrings"); - static JSString* ConvertObjectToStringForConcat(JSContext* cx, HandleValue obj) { MOZ_ASSERT(obj.isObject()); RootedValue rootedObj(cx, obj); if (!ToPrimitive(cx, &rootedObj)) { return nullptr; } return ToString<CanGC>(cx, rootedObj); @@ -1933,67 +1908,16 @@ bool IsPossiblyWrappedTypedArray(JSConte ReportAccessDenied(cx); return false; } *result = unwrapped->is<TypedArrayObject>(); return true; } -typedef bool (*ProxyGetPropertyFn)(JSContext*, HandleObject, HandleId, - MutableHandleValue); -const VMFunction ProxyGetPropertyInfo = - FunctionInfo<ProxyGetPropertyFn>(ProxyGetProperty, "ProxyGetProperty"); - -typedef bool (*ProxyGetPropertyByValueFn)(JSContext*, HandleObject, HandleValue, - MutableHandleValue); -const VMFunction ProxyGetPropertyByValueInfo = - FunctionInfo<ProxyGetPropertyByValueFn>(ProxyGetPropertyByValue, - "ProxyGetPropertyByValue"); - -typedef bool (*ProxySetPropertyFn)(JSContext*, HandleObject, HandleId, - HandleValue, bool); -const VMFunction ProxySetPropertyInfo = - FunctionInfo<ProxySetPropertyFn>(ProxySetProperty, "ProxySetProperty"); - -typedef bool (*ProxySetPropertyByValueFn)(JSContext*, HandleObject, HandleValue, - HandleValue, bool); -const VMFunction ProxySetPropertyByValueInfo = - FunctionInfo<ProxySetPropertyByValueFn>(ProxySetPropertyByValue, - "ProxySetPropertyByValue"); - -typedef bool (*ProxyHasFn)(JSContext*, HandleObject, HandleValue, - MutableHandleValue); -const VMFunction ProxyHasInfo = FunctionInfo<ProxyHasFn>(ProxyHas, "ProxyHas"); - -typedef bool (*ProxyHasOwnFn)(JSContext*, HandleObject, HandleValue, - MutableHandleValue); -const VMFunction ProxyHasOwnInfo = - FunctionInfo<ProxyHasOwnFn>(ProxyHasOwn, "ProxyHasOwn"); - -typedef bool (*NativeGetElementFn)(JSContext*, HandleNativeObject, HandleValue, - int32_t, MutableHandleValue); -const VMFunction NativeGetElementInfo = - FunctionInfo<NativeGetElementFn>(NativeGetElement, "NativeGetProperty"); - -typedef bool (*AddOrUpdateSparseElementHelperFn)(JSContext* cx, - HandleArrayObject obj, - int32_t int_id, HandleValue v, - bool strict); -const VMFunction AddOrUpdateSparseElementHelperInfo = - FunctionInfo<AddOrUpdateSparseElementHelperFn>( - AddOrUpdateSparseElementHelper, "AddOrUpdateSparseElementHelper"); - -typedef bool (*GetSparseElementHelperFn)(JSContext* cx, HandleArrayObject obj, - int32_t int_id, - MutableHandleValue result); -const VMFunction GetSparseElementHelperInfo = - FunctionInfo<GetSparseElementHelperFn>(GetSparseElementHelper, - "getSparseElementHelper"); - bool DoToNumber(JSContext* cx, HandleValue arg, MutableHandleValue ret) { ret.set(arg); return ToNumber(cx, ret); } bool DoToNumeric(JSContext* cx, HandleValue arg, MutableHandleValue ret) { ret.set(arg); return ToNumeric(cx, ret);
--- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -1217,37 +1217,16 @@ bool DoConcatStringObject(JSContext* cx, MOZ_MUST_USE bool TrySkipAwait(JSContext* cx, HandleValue val, MutableHandleValue resolved); bool IsPossiblyWrappedTypedArray(JSContext* cx, JSObject* obj, bool* result); bool DoToNumber(JSContext* cx, HandleValue arg, MutableHandleValue ret); bool DoToNumeric(JSContext* cx, HandleValue arg, MutableHandleValue ret); -// VMFunctions shared by JITs -extern const VMFunction SetArrayLengthInfo; -extern const VMFunction SetObjectElementInfo; - -extern const VMFunction StringsEqualInfo; -extern const VMFunction StringsNotEqualInfo; -extern const VMFunction ConcatStringsInfo; -extern const VMFunction StringSplitHelperInfo; - -extern const VMFunction ProxyGetPropertyInfo; -extern const VMFunction ProxyGetPropertyByValueInfo; -extern const VMFunction ProxySetPropertyInfo; -extern const VMFunction ProxySetPropertyByValueInfo; -extern const VMFunction ProxyHasInfo; -extern const VMFunction ProxyHasOwnInfo; - -extern const VMFunction NativeGetElementInfo; - -extern const VMFunction AddOrUpdateSparseElementHelperInfo; -extern const VMFunction GetSparseElementHelperInfo; - // TailCall VMFunctions extern const VMFunction DoConcatStringObjectInfo; enum class VMFunctionId; extern const VMFunctionData& GetVMFunction(VMFunctionId id); } // namespace jit