From f214aa5dbe2c4aa3e543aecc2b6ad96d7786862e Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 30 Aug 2018 12:26:26 +0200 Subject: Revert "Bug 1444668 - Avoid allocating large AssemblerBuffers. r=luke, r=bbouvier, a=RyanVM" This reverts commit 9472136272f01b858412f2d9d7854d2daa82496f. --- js/src/jit/MacroAssembler.cpp | 6 ---- js/src/jit/ProcessExecutableMemory.cpp | 8 ++++++ js/src/jit/ProcessExecutableMemory.h | 8 ------ js/src/jit/shared/IonAssemblerBuffer.h | 4 --- js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h | 32 +--------------------- 5 files changed, 9 insertions(+), 49 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 9dbbe7624..f633b9b7b 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -2214,12 +2214,6 @@ MacroAssembler::finish() } MacroAssemblerSpecific::finish(); - - MOZ_RELEASE_ASSERT(size() <= MaxCodeBytesPerProcess, - "AssemblerBuffer should ensure we don't exceed MaxCodeBytesPerProcess"); - - if (bytesNeeded() > MaxCodeBytesPerProcess) - setOOM(); } void diff --git a/js/src/jit/ProcessExecutableMemory.cpp b/js/src/jit/ProcessExecutableMemory.cpp index 301541541..71c2ab0dc 100644 --- a/js/src/jit/ProcessExecutableMemory.cpp +++ b/js/src/jit/ProcessExecutableMemory.cpp @@ -385,6 +385,14 @@ class PageBitSet #endif }; +// Limit on the number of bytes of executable memory to prevent JIT spraying +// attacks. +#if JS_BITS_PER_WORD == 32 +static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024; +#else +static const size_t MaxCodeBytesPerProcess = 1 * 1024 * 1024 * 1024; +#endif + // Per-process executable memory allocator. It reserves a block of memory of // MaxCodeBytesPerProcess bytes, then allocates/deallocates pages from that. // diff --git a/js/src/jit/ProcessExecutableMemory.h b/js/src/jit/ProcessExecutableMemory.h index a0e2fab98..078ce7cb7 100644 --- a/js/src/jit/ProcessExecutableMemory.h +++ b/js/src/jit/ProcessExecutableMemory.h @@ -17,14 +17,6 @@ namespace jit { // alignment though. static const size_t ExecutableCodePageSize = 64 * 1024; -// Limit on the number of bytes of executable memory to prevent JIT spraying -// attacks. -#if JS_BITS_PER_WORD == 32 -static const size_t MaxCodeBytesPerProcess = 128 * 1024 * 1024; -#else -static const size_t MaxCodeBytesPerProcess = 1 * 1024 * 1024 * 1024; -#endif - enum class ProtectionSetting { Protected, // Not readable, writable, or executable. Writable, diff --git a/js/src/jit/shared/IonAssemblerBuffer.h b/js/src/jit/shared/IonAssemblerBuffer.h index 3a6552696..cc20e26d2 100644 --- a/js/src/jit/shared/IonAssemblerBuffer.h +++ b/js/src/jit/shared/IonAssemblerBuffer.h @@ -181,10 +181,6 @@ class AssemblerBuffer protected: virtual Slice* newSlice(LifoAlloc& a) { - if (size() > MaxCodeBytesPerProcess - sizeof(Slice)) { - fail_oom(); - return nullptr; - } Slice* tmp = static_cast(a.alloc(sizeof(Slice))); if (!tmp) { fail_oom(); diff --git a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h index fe678fc7d..8cb557784 100644 --- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h @@ -68,33 +68,6 @@ namespace js { namespace jit { - // AllocPolicy for AssemblerBuffer. OOMs when trying to allocate more than - // MaxCodeBytesPerProcess bytes. Use private inheritance to make sure we - // explicitly have to expose SystemAllocPolicy methods. - class AssemblerBufferAllocPolicy : private SystemAllocPolicy - { - public: - using SystemAllocPolicy::checkSimulatedOOM; - using SystemAllocPolicy::reportAllocOverflow; - using SystemAllocPolicy::free_; - - template T* pod_realloc(T* p, size_t oldSize, size_t newSize) { - static_assert(sizeof(T) == 1, - "AssemblerBufferAllocPolicy should only be used with byte vectors"); - MOZ_ASSERT(oldSize <= MaxCodeBytesPerProcess); - if (MOZ_UNLIKELY(newSize > MaxCodeBytesPerProcess)) - return nullptr; - return SystemAllocPolicy::pod_realloc(p, oldSize, newSize); - } - template T* pod_malloc(size_t numElems) { - static_assert(sizeof(T) == 1, - "AssemblerBufferAllocPolicy should only be used with byte vectors"); - if (MOZ_UNLIKELY(numElems > MaxCodeBytesPerProcess)) - return nullptr; - return SystemAllocPolicy::pod_malloc(numElems); - } - }; - class AssemblerBuffer { template @@ -120,9 +93,6 @@ namespace jit { void ensureSpace(size_t space) { - // This should only be called with small |space| values to ensure - // we don't overflow below. - MOZ_ASSERT(space <= 16); if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space))) oomDetected(); } @@ -198,7 +168,7 @@ namespace jit { m_buffer.clear(); } - PageProtectingVector m_buffer; + PageProtectingVector m_buffer; bool m_oom; }; -- cgit v1.2.3 From 7d73b3fbfe1cd4f3a45b569f98f19041f95a50b9 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 4 Sep 2018 07:40:42 +0200 Subject: Add extra check for assembler buffer space. --- js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h index 8cb557784..8343579c8 100644 --- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h +++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h @@ -93,7 +93,8 @@ namespace jit { void ensureSpace(size_t space) { - if (MOZ_UNLIKELY(!m_buffer.reserve(m_buffer.length() + space))) + if (MOZ_UNLIKELY(m_buffer.length() > (SIZE_MAX - space) || + !m_buffer.reserve(m_buffer.length() + space))) oomDetected(); } -- cgit v1.2.3 From 847f12e88faf1b9a34d0b6fa9b262dfed209aedb Mon Sep 17 00:00:00 2001 From: trav90 Date: Wed, 12 Sep 2018 05:41:41 -0500 Subject: Stop using PodZero in several places to initialize values of non-trivial type --- js/src/jit/IonCode.h | 11 ++++------- js/src/jit/shared/Assembler-shared.h | 10 +++------- 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index c581aa62e..55c3d4dad 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -9,7 +9,6 @@ #include "mozilla/Atomics.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/PodOperations.h" #include "jstypes.h" @@ -692,17 +691,15 @@ struct IonScriptCounts { private: // Any previous invalidated compilation(s) for the script. - IonScriptCounts* previous_; + IonScriptCounts* previous_ = nullptr; // Information about basic blocks in this script. - size_t numBlocks_; - IonBlockCounts* blocks_; + size_t numBlocks_ = 0; + IonBlockCounts* blocks_ = nullptr; public: - IonScriptCounts() { - mozilla::PodZero(this); - } + IonScriptCounts() = default; ~IonScriptCounts() { for (size_t i = 0; i < numBlocks_; i++) diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index aac9687b8..8044e75cb 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -7,8 +7,6 @@ #ifndef jit_shared_Assembler_shared_h #define jit_shared_Assembler_shared_h -#include "mozilla/PodOperations.h" - #include #include "jit/AtomicOp.h" @@ -491,10 +489,10 @@ class CodeLabel class CodeOffsetJump { - size_t offset_; + size_t offset_ = 0; #ifdef JS_SMALL_BRANCH - size_t jumpTableIndex_; + size_t jumpTableIndex_ = 0; #endif public: @@ -510,9 +508,7 @@ class CodeOffsetJump explicit CodeOffsetJump(size_t offset) : offset_(offset) {} #endif - CodeOffsetJump() { - mozilla::PodZero(this); - } + CodeOffsetJump() = default; size_t offset() const { return offset_; -- cgit v1.2.3 From 0712ac7f81a455b21e0065b6a212b64385835e5e Mon Sep 17 00:00:00 2001 From: trav90 Date: Wed, 12 Sep 2018 19:19:12 -0500 Subject: Don't memset-zero the BacktrackingAllocator::vregs array of non-trivial VirtualRegister instances --- js/src/jit/BacktrackingAllocator.cpp | 11 +++++------ js/src/jit/BacktrackingAllocator.h | 15 ++++++--------- 2 files changed, 11 insertions(+), 15 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 94ef25785..73aceeccb 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -378,7 +378,6 @@ BacktrackingAllocator::init() size_t numVregs = graph.numVirtualRegisters(); if (!vregs.init(mir->alloc(), numVregs)) return false; - memset(&vregs[0], 0, sizeof(VirtualRegister) * numVregs); for (uint32_t i = 0; i < numVregs; i++) new(&vregs[i]) VirtualRegister(); @@ -1101,9 +1100,9 @@ BacktrackingAllocator::mergeAndQueueRegisters() if (iter->isParameter()) { for (size_t i = 0; i < iter->numDefs(); i++) { DebugOnly found = false; - VirtualRegister ¶mVreg = vreg(iter->getDef(i)); + VirtualRegister& paramVreg = vreg(iter->getDef(i)); for (; original < paramVreg.vreg(); original++) { - VirtualRegister &originalVreg = vregs[original]; + VirtualRegister& originalVreg = vregs[original]; if (*originalVreg.def()->output() == *iter->getDef(i)->output()) { MOZ_ASSERT(originalVreg.ins()->isParameter()); if (!tryMergeBundles(originalVreg.firstBundle(), paramVreg.firstBundle())) @@ -1136,7 +1135,7 @@ BacktrackingAllocator::mergeAndQueueRegisters() LBlock* block = graph.getBlock(i); for (size_t j = 0; j < block->numPhis(); j++) { LPhi* phi = block->getPhi(j); - VirtualRegister &outputVreg = vreg(phi->getDef(0)); + VirtualRegister& outputVreg = vreg(phi->getDef(0)); for (size_t k = 0, kend = phi->numOperands(); k < kend; k++) { VirtualRegister& inputVreg = vreg(phi->getOperand(k)->toUse()); if (!tryMergeBundles(inputVreg.firstBundle(), outputVreg.firstBundle())) @@ -1334,7 +1333,7 @@ BacktrackingAllocator::computeRequirement(LiveBundle* bundle, for (LiveRange::BundleLinkIterator iter = bundle->rangesBegin(); iter; iter++) { LiveRange* range = LiveRange::get(*iter); - VirtualRegister ® = vregs[range->vreg()]; + VirtualRegister& reg = vregs[range->vreg()]; if (range->hasDefinition()) { // Deal with any definition constraints/hints. @@ -1396,7 +1395,7 @@ BacktrackingAllocator::tryAllocateRegister(PhysicalRegister& r, LiveBundle* bund for (LiveRange::BundleLinkIterator iter = bundle->rangesBegin(); iter; iter++) { LiveRange* range = LiveRange::get(*iter); - VirtualRegister ® = vregs[range->vreg()]; + VirtualRegister& reg = vregs[range->vreg()]; if (!reg.isCompatible(r.reg)) return true; diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index 6d14ffacd..9910498fb 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -478,34 +478,31 @@ class LiveBundle : public TempObject class VirtualRegister { // Instruction which defines this register. - LNode* ins_; + LNode* ins_ = nullptr; // Definition in the instruction for this register. - LDefinition* def_; + LDefinition* def_ = nullptr; // All live ranges for this register. These may overlap each other, and are // ordered by their start position. InlineForwardList ranges_; // Whether def_ is a temp or an output. - bool isTemp_; + bool isTemp_ = false; // Whether this vreg is an input for some phi. This use is not reflected in // any range on the vreg. - bool usedByPhi_; + bool usedByPhi_ = false; // If this register's definition is MUST_REUSE_INPUT, whether a copy must // be introduced before the definition that relaxes the policy. - bool mustCopyInput_; + bool mustCopyInput_ = false; void operator=(const VirtualRegister&) = delete; VirtualRegister(const VirtualRegister&) = delete; public: - explicit VirtualRegister() - { - // Note: This class is zeroed before it is constructed. - } + VirtualRegister() = default; void init(LNode* ins, LDefinition* def, bool isTemp) { MOZ_ASSERT(!ins_); -- cgit v1.2.3 From ca7ecd37c94e268972697a37eec4e46771c6e6f2 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 4 Oct 2018 22:04:26 +0200 Subject: Bug 1493900. DiD fix. --- js/src/jit/BacktrackingAllocator.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 73aceeccb..741ed1592 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -1843,10 +1843,19 @@ BacktrackingAllocator::resolveControlFlow() LiveRange* from = vreg(input).rangeFor(exitOf(predecessor), /* preferRegister = */ true); MOZ_ASSERT(from); - if (!alloc().ensureBallast()) - return false; - if (!moveAtExit(predecessor, from, to, def->type())) + if (!alloc().ensureBallast()) { return false; + } + if (mSuccessor->numPredecessors() > 1) { + MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); + if (!moveAtExit(predecessor, from, to, def->type())) { + return false; + } + } else { + if (!moveAtEntry(successor, from, to, def->type())) { + return false; + } + } } } } -- cgit v1.2.3 From 980b7e4da5d80f09cf805674b8822b260870b8d3 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 23 Oct 2018 09:44:24 +0200 Subject: Improve graph edge resolution code. This is a follow-up to ca7ecd37c94e268972697a37eec4e46771c6e6f2 further improving the DiD resolution for CVE-2018-12386. --- js/src/jit/BacktrackingAllocator.cpp | 38 ++++++++++++++++++++---------------- js/src/jit/BacktrackingAllocator.h | 3 +++ 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BacktrackingAllocator.cpp b/js/src/jit/BacktrackingAllocator.cpp index 741ed1592..645aefc4f 100644 --- a/js/src/jit/BacktrackingAllocator.cpp +++ b/js/src/jit/BacktrackingAllocator.cpp @@ -1735,6 +1735,18 @@ BacktrackingAllocator::deadRange(LiveRange* range) return true; } +bool +BacktrackingAllocator::moveAtEdge(LBlock* predecessor, LBlock* successor, LiveRange* from, + LiveRange* to, LDefinition::Type type) +{ + if (successor->mir()->numPredecessors() > 1) { + MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); + return moveAtExit(predecessor, from, to, type); + } + + return moveAtEntry(successor, from, to, type); +} + bool BacktrackingAllocator::resolveControlFlow() { @@ -1846,15 +1858,11 @@ BacktrackingAllocator::resolveControlFlow() if (!alloc().ensureBallast()) { return false; } - if (mSuccessor->numPredecessors() > 1) { - MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); - if (!moveAtExit(predecessor, from, to, def->type())) { - return false; - } - } else { - if (!moveAtEntry(successor, from, to, def->type())) { - return false; - } + + // Note: we have to use moveAtEdge both here and below (for edge + // resolution) to avoid conflicting moves. See bug 1493900. + if (!moveAtEdge(predecessor, successor, from, to, def->type())) { + return false; } } } @@ -1884,16 +1892,12 @@ BacktrackingAllocator::resolveControlFlow() if (targetRange->covers(exitOf(predecessor))) continue; - if (!alloc().ensureBallast()) + if (!alloc().ensureBallast()) { return false; + } LiveRange* from = reg.rangeFor(exitOf(predecessor), true); - if (successor->mir()->numPredecessors() > 1) { - MOZ_ASSERT(predecessor->mir()->numSuccessors() == 1); - if (!moveAtExit(predecessor, from, targetRange, reg.type())) - return false; - } else { - if (!moveAtEntry(successor, from, targetRange, reg.type())) - return false; + if (!moveAtEdge(predecessor, successor, from, targetRange, reg.type())) { + return false; } } } diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index 9910498fb..ef3c2a572 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -774,6 +774,9 @@ class BacktrackingAllocator : protected RegisterAllocator return addMove(moves, from, to, type); } + MOZ_MUST_USE bool moveAtEdge(LBlock* predecessor, LBlock* successor, LiveRange* from, + LiveRange* to, LDefinition::Type type); + // Debugging methods. void dumpAllocations(); -- cgit v1.2.3 From b4e78255c0df5ec542a6cc0c0a644e248d4d0c5c Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 23 Oct 2018 09:44:51 +0200 Subject: Code style improvements (no bug). --- js/src/jit/BacktrackingAllocator.h | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BacktrackingAllocator.h b/js/src/jit/BacktrackingAllocator.h index ef3c2a572..c6cf26695 100644 --- a/js/src/jit/BacktrackingAllocator.h +++ b/js/src/jit/BacktrackingAllocator.h @@ -108,8 +108,9 @@ class Requirement } MOZ_ASSERT(newRequirement.kind() == Requirement::REGISTER); - if (kind() == Requirement::FIXED) + if (kind() == Requirement::FIXED) { return allocation().isRegister(); + } *this = newRequirement; return true; @@ -353,10 +354,12 @@ class LiveRange : public TempObject // Comparator for use in range splay trees. static int compare(LiveRange* v0, LiveRange* v1) { // LiveRange includes 'from' but excludes 'to'. - if (v0->to() <= v1->from()) + if (v0->to() <= v1->from()) { return -1; - if (v0->from() >= v1->to()) + } + if (v0->from() >= v1->to()) { return 1; + } return 0; } }; @@ -642,10 +645,12 @@ class BacktrackingAllocator : protected RegisterAllocator // Comparator for use in splay tree. static int compare(CallRange* v0, CallRange* v1) { - if (v0->range.to <= v1->range.from) + if (v0->range.to <= v1->range.from) { return -1; - if (v0->range.from >= v1->range.to) + } + if (v0->range.from >= v1->range.to) { return 1; + } return 0; } }; @@ -744,32 +749,36 @@ class BacktrackingAllocator : protected RegisterAllocator MOZ_MUST_USE bool moveInput(LInstruction* ins, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = getInputMoveGroup(ins); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAfter(LInstruction* ins, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = getMoveGroupAfter(ins); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAtExit(LBlock* block, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = block->getExitMoveGroup(alloc()); return addMove(moves, from, to, type); } MOZ_MUST_USE bool moveAtEntry(LBlock* block, LiveRange* from, LiveRange* to, LDefinition::Type type) { - if (from->bundle()->allocation() == to->bundle()->allocation()) + if (from->bundle()->allocation() == to->bundle()->allocation()) { return true; + } LMoveGroup* moves = block->getEntryMoveGroup(alloc()); return addMove(moves, from, to, type); } -- cgit v1.2.3 From 1cfcf17a10898f8c429021c4f78bd9ae61935c52 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 31 Oct 2018 17:30:52 +0100 Subject: Don't mark MGetFirstDollarIndex as movable. --- js/src/jit/MIR.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 6ec05af76..b2e84322f 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -8272,7 +8272,10 @@ class MGetFirstDollarIndex : MUnaryInstruction(str) { setResultType(MIRType::Int32); - setMovable(); + + // Codegen assumes string length > 0 but that's not guaranteed in RegExp. + // Don't allow LICM to move this. + MOZ_ASSERT(!isMovable()); } public: -- cgit v1.2.3 From 24a83a813641a6500e91f9fcf1ea3ca0aecc047a Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 1 Nov 2018 10:33:07 +0100 Subject: Simplify SIMD conversion from Uint64 to Double. --- js/src/jit/x86/Assembler-x86.h | 13 ++----------- js/src/jit/x86/BaseAssembler-x86.h | 8 -------- js/src/jit/x86/MacroAssembler-x86.cpp | 31 +++++++++++++++++++------------ 3 files changed, 21 insertions(+), 31 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index 3fb5efaff..5939583d9 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -421,20 +421,11 @@ class Assembler : public AssemblerX86Shared MOZ_ASSERT(dest.size() == 16); masm.vhaddpd_rr(src.encoding(), dest.encoding()); } - void vsubpd(const Operand& src1, FloatRegister src0, FloatRegister dest) { + void vsubpd(FloatRegister src1, FloatRegister src0, FloatRegister dest) { MOZ_ASSERT(HasSSE2()); MOZ_ASSERT(src0.size() == 16); MOZ_ASSERT(dest.size() == 16); - switch (src1.kind()) { - case Operand::MEM_REG_DISP: - masm.vsubpd_mr(src1.disp(), src1.base(), src0.encoding(), dest.encoding()); - break; - case Operand::MEM_ADDRESS32: - masm.vsubpd_mr(src1.address(), src0.encoding(), dest.encoding()); - break; - default: - MOZ_CRASH("unexpected operand kind"); - } + masm.vsubpd_rr(src1.encoding(), src0.encoding(), dest.encoding()); } void vpunpckldq(FloatRegister src1, FloatRegister src0, FloatRegister dest) { diff --git a/js/src/jit/x86/BaseAssembler-x86.h b/js/src/jit/x86/BaseAssembler-x86.h index 5b16311d0..caaef3f82 100644 --- a/js/src/jit/x86/BaseAssembler-x86.h +++ b/js/src/jit/x86/BaseAssembler-x86.h @@ -152,14 +152,6 @@ class BaseAssemblerX86 : public BaseAssembler { twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, src1, src0, dst); } - void vsubpd_mr(int32_t offset, RegisterID base, XMMRegisterID src0, XMMRegisterID dst) - { - twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, offset, base, src0, dst); - } - void vsubpd_mr(const void* address, XMMRegisterID src0, XMMRegisterID dst) - { - twoByteOpSimd("vsubpd", VEX_PD, OP2_SUBPS_VpsWps, address, src0, dst); - } void vpunpckldq_rr(XMMRegisterID src1, XMMRegisterID src0, XMMRegisterID dst) { twoByteOpSimd("vpunpckldq", VEX_PD, OP2_PUNPCKLDQ, src1, src0, dst); diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index dc97b5b5b..429a71fa9 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -21,15 +21,6 @@ using namespace js; using namespace js::jit; -// vpunpckldq requires 16-byte boundary for memory operand. -// See convertUInt64ToDouble for the details. -MOZ_ALIGNED_DECL(static const uint64_t, 16) TO_DOUBLE[4] = { - 0x4530000043300000LL, - 0x0LL, - 0x4330000000000000LL, - 0x4530000000000000LL -}; - static const double TO_DOUBLE_HIGH_SCALE = 0x100000000; bool @@ -90,8 +81,16 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, FloatRegister dest, Reg // here, each 64-bit part of dest represents following double: // HI(dest) = 0x 1.00000HHHHHHHH * 2**84 == 2**84 + 0x HHHHHHHH 00000000 // LO(dest) = 0x 1.00000LLLLLLLL * 2**52 == 2**52 + 0x 00000000 LLLLLLLL - movePtr(ImmWord((uintptr_t)TO_DOUBLE), temp); - vpunpckldq(Operand(temp, 0), dest128, dest128); + // See convertUInt64ToDouble for the details. + static const int32_t CST1[4] = { + 0x43300000, + 0x45300000, + 0x0, + 0x0, + }; + + loadConstantSimd128Int(SimdConstant::CreateX4(CST1), ScratchSimd128Reg); + vpunpckldq(ScratchSimd128Reg, dest128, dest128); // Subtract a constant C2 from dest, for each 64-bit part: // C2 = 0x 45300000 00000000 43300000 00000000 @@ -101,7 +100,15 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, FloatRegister dest, Reg // after the operation each 64-bit part of dest represents following: // HI(dest) = double(0x HHHHHHHH 00000000) // LO(dest) = double(0x 00000000 LLLLLLLL) - vsubpd(Operand(temp, sizeof(uint64_t) * 2), dest128, dest128); + static const int32_t CST2[4] = { + 0x0, + 0x43300000, + 0x0, + 0x45300000, + }; + + loadConstantSimd128Int(SimdConstant::CreateX4(CST2), ScratchSimd128Reg); + vsubpd(ScratchSimd128Reg, dest128, dest128); // Add HI(dest) and LO(dest) in double and store it into LO(dest), // LO(dest) = double(0x HHHHHHHH 00000000) + double(0x 00000000 LLLLLLLL) -- cgit v1.2.3 From f2d4bd1e395f903355cc157a1de7207e5b22b7fb Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 12 Dec 2018 00:49:58 +0100 Subject: Fix mistakingly flagged instructions. This enables optimizations which were wrongly inhibited before by this typo. --- js/src/jit/IonAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 2c9ffb607..b163d5818 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -2306,7 +2306,7 @@ jit::RemoveUnmarkedBlocks(MIRGenerator* mir, MIRGraph& graph, uint32_t numMarked // bailout. for (PostorderIterator it(graph.poBegin()); it != graph.poEnd();) { MBasicBlock* block = *it++; - if (!block->isMarked()) + if (block->isMarked()) continue; FlagAllOperandsAsHavingRemovedUses(mir, block); -- cgit v1.2.3 From 99b534f23d9db2a6ef6a030aeb95e297cb887dd8 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 13 Dec 2018 12:24:17 +0100 Subject: Restrict ExtractLinearSum to find non-wrapping results. --- js/src/jit/RangeAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index 95484c249..d64f9b8ca 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -2167,7 +2167,7 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock* header, LoopIterationBound* loopBound if (initial->block()->isMarked()) return; - SimpleLinearSum modified = ExtractLinearSum(phi->getLoopBackedgeOperand()); + SimpleLinearSum modified = ExtractLinearSum(phi->getLoopBackedgeOperand(), MathSpace::Infinite); if (modified.term != phi || modified.constant == 0) return; -- cgit v1.2.3 From 90d1ee25b1de235847605fbc95a9ddebcf5c061d Mon Sep 17 00:00:00 2001 From: adeshkp Date: Thu, 14 Mar 2019 09:53:02 -0400 Subject: Remove a couple of unused variables --- js/src/jit/StupidAllocator.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/StupidAllocator.cpp b/js/src/jit/StupidAllocator.cpp index 8e3ea6286..55431e8e0 100644 --- a/js/src/jit/StupidAllocator.cpp +++ b/js/src/jit/StupidAllocator.cpp @@ -407,7 +407,6 @@ StupidAllocator::allocateForDefinition(LInstruction* ins, LDefinition* def) { uint32_t vreg = def->virtualRegister(); - CodePosition from; if ((def->output()->isRegister() && def->policy() == LDefinition::FIXED) || def->policy() == LDefinition::MUST_REUSE_INPUT) { -- cgit v1.2.3 From 890bb438b000821586c076ed8f880e95ea03f075 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 21 Mar 2019 09:53:24 +0100 Subject: Pref the use of unboxed plain objects in JS and disable by default. This should be all that's needed for #1017, but verification of impact is definitely desired. --- js/src/jit/JitOptions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp index eb5a6c1c2..b9a7c7b27 100644 --- a/js/src/jit/JitOptions.cpp +++ b/js/src/jit/JitOptions.cpp @@ -222,7 +222,7 @@ DefaultJitOptions::DefaultJitOptions() } // Toggles whether unboxed plain objects can be created by the VM. - SET_DEFAULT(disableUnboxedObjects, false); + SET_DEFAULT(disableUnboxedObjects, true); // Test whether Atomics are allowed in asm.js code. SET_DEFAULT(asmJSAtomicsEnable, false); -- cgit v1.2.3 From 054794f8c5c93f502318a99517cfacfd757510d6 Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Sat, 23 Mar 2019 09:36:15 +0100 Subject: Restrict ExtractLinearSum to monotonous operation in infinite math space. Thanks to Bruno Keith & Niklas Baumstark from the phoenhex team for finding this issue and reporting it with a proper analysis. --- js/src/jit/IonAnalysis.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index b163d5818..d255c32a8 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -3127,6 +3127,15 @@ ExtractMathSpace(MDefinition* ins) MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unknown TruncateKind"); } +static bool MonotoneAdd(int32_t lhs, int32_t rhs) { + return (lhs >= 0 && rhs >= 0) || (lhs <= 0 && rhs <= 0); +} + +static bool MonotoneSub(int32_t lhs, int32_t rhs) { + return (lhs >= 0 && rhs <= 0) || (lhs <= 0 && rhs >= 0); +} + + // Extract a linear sum from ins, if possible (otherwise giving the sum 'ins + 0'). SimpleLinearSum jit::ExtractLinearSum(MDefinition* ins, MathSpace space) @@ -3168,10 +3177,12 @@ jit::ExtractLinearSum(MDefinition* ins, MathSpace space) // Check if this is of the form + n or n + . if (ins->isAdd()) { int32_t constant; - if (space == MathSpace::Modulo) + if (space == MathSpace::Modulo) { constant = lsum.constant + rsum.constant; - else if (!SafeAdd(lsum.constant, rsum.constant, &constant)) + } else if (!SafeAdd(lsum.constant, rsum.constant, &constant) || + !MonotoneAdd(lsum.constant, rsum.constant)) { return SimpleLinearSum(ins, 0); + } return SimpleLinearSum(lsum.term ? lsum.term : rsum.term, constant); } @@ -3179,10 +3190,12 @@ jit::ExtractLinearSum(MDefinition* ins, MathSpace space) // Check if this is of the form - n. if (lsum.term) { int32_t constant; - if (space == MathSpace::Modulo) + if (space == MathSpace::Modulo) { constant = lsum.constant - rsum.constant; - else if (!SafeSub(lsum.constant, rsum.constant, &constant)) + } else if (!SafeSub(lsum.constant, rsum.constant, &constant) || + !MonotoneSub(lsum.constant, rsum.constant)) { return SimpleLinearSum(ins, 0); + } return SimpleLinearSum(lsum.term, constant); } -- cgit v1.2.3 From 0b999100f6c0b7b90d1167237621826e0e6a808a Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 26 Mar 2019 18:30:57 +0100 Subject: Simplify some alias sets in IonMonkey. --- js/src/jit/AliasAnalysisShared.cpp | 3 ++- js/src/jit/MIR.h | 7 ++----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/AliasAnalysisShared.cpp b/js/src/jit/AliasAnalysisShared.cpp index ae28327ca..81c0fd067 100644 --- a/js/src/jit/AliasAnalysisShared.cpp +++ b/js/src/jit/AliasAnalysisShared.cpp @@ -102,7 +102,6 @@ GetObject(const MDefinition* ins) case MDefinition::Op_SetDisjointTypedElements: case MDefinition::Op_ArrayPopShift: case MDefinition::Op_ArrayPush: - case MDefinition::Op_ArraySlice: case MDefinition::Op_LoadTypedArrayElementHole: case MDefinition::Op_StoreTypedArrayElementHole: case MDefinition::Op_LoadFixedSlot: @@ -126,6 +125,7 @@ GetObject(const MDefinition* ins) object = ins->getOperand(0); break; case MDefinition::Op_GetPropertyCache: + case MDefinition::Op_CallGetProperty: case MDefinition::Op_LoadTypedArrayElementStatic: case MDefinition::Op_StoreTypedArrayElementStatic: case MDefinition::Op_GetDOMProperty: @@ -148,6 +148,7 @@ GetObject(const MDefinition* ins) case MDefinition::Op_WasmLoadGlobalVar: case MDefinition::Op_WasmStoreGlobalVar: case MDefinition::Op_ArrayJoin: + case MDefinition::Op_ArraySlice: return nullptr; default: #ifdef DEBUG diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index b2e84322f..fb0f22fc3 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9910,10 +9910,6 @@ class MArraySlice return unboxedType_; } - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::BoxedOrUnboxedElements(unboxedType()) | - AliasSet::ObjectFields); - } bool possiblyCalls() const override { return true; } @@ -11837,7 +11833,8 @@ class MCallGetProperty AliasSet getAliasSet() const override { if (!idempotent_) return AliasSet::Store(AliasSet::Any); - return AliasSet::None(); + return AliasSet::Load(AliasSet::ObjectFields | AliasSet::FixedSlot | + AliasSet::DynamicSlot); } bool possiblyCalls() const override { return true; -- cgit v1.2.3 From 9a3141515f051b6622f564ba75c171822854a7ac Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 14 May 2019 11:44:11 +0000 Subject: remove unboxed code chunk (wip1) --- js/src/jit/BaselineInspector.cpp | 31 +++++----------- js/src/jit/BaselineInspector.h | 9 ++--- js/src/jit/IonBuilder.cpp | 80 +++++----------------------------------- js/src/jit/IonBuilder.h | 4 -- js/src/jit/MCallOptimize.cpp | 8 ++-- 5 files changed, 25 insertions(+), 107 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index c9e09bed7..9c7b88fb2 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -96,13 +96,8 @@ VectorAppendNoDuplicate(S& list, T value) static bool AddReceiver(const ReceiverGuard& receiver, - BaselineInspector::ReceiverVector& receivers, - BaselineInspector::ObjectGroupVector& convertUnboxedGroups) + BaselineInspector::ReceiverVector& receivers) { - if (receiver.group && receiver.group->maybeUnboxedLayout()) { - if (receiver.group->unboxedLayout().nativeGroup()) - return VectorAppendNoDuplicate(convertUnboxedGroups, receiver.group); - } return VectorAppendNoDuplicate(receivers, receiver); } @@ -170,16 +165,12 @@ GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* r } bool -BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups) +BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers) { // Return a list of the receivers seen by the baseline IC for the current // op. Empty lists indicate no receivers are known, or there was an - // uncacheable access. convertUnboxedGroups is used for unboxed object - // groups which have been seen, but have had instances converted to native - // objects and should be eagerly converted by Ion. + // uncacheable access. MOZ_ASSERT(receivers.empty()); - MOZ_ASSERT(convertUnboxedGroups.empty()); if (!hasBaselineScript()) return true; @@ -207,7 +198,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv return true; } - if (!AddReceiver(receiver, receivers, convertUnboxedGroups)) + if (!AddReceiver(receiver, receivers)) return false; stub = stub->next(); @@ -700,14 +691,12 @@ bool BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape, JSFunction** commonGetter, Shape** globalShape, bool* isOwnProperty, - ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups) + ReceiverVector& receivers) { if (!hasBaselineScript()) return false; MOZ_ASSERT(receivers.empty()); - MOZ_ASSERT(convertUnboxedGroups.empty()); *holder = nullptr; const ICEntry& entry = icEntryFromPC(pc); @@ -719,7 +708,7 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap { ICGetPropCallGetter* nstub = static_cast(stub); bool isOwn = nstub->isOwnGetter(); - if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups)) + if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers)) return false; if (!*holder) { @@ -751,21 +740,19 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap if (!*holder) return false; - MOZ_ASSERT(*isOwnProperty == (receivers.empty() && convertUnboxedGroups.empty())); + MOZ_ASSERT(*isOwnProperty == (receivers.empty())); return true; } bool BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape, JSFunction** commonSetter, bool* isOwnProperty, - ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups) + ReceiverVector& receivers) { if (!hasBaselineScript()) return false; MOZ_ASSERT(receivers.empty()); - MOZ_ASSERT(convertUnboxedGroups.empty()); *holder = nullptr; const ICEntry& entry = icEntryFromPC(pc); @@ -774,7 +761,7 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap if (stub->isSetProp_CallScripted() || stub->isSetProp_CallNative()) { ICSetPropCallSetter* nstub = static_cast(stub); bool isOwn = nstub->isOwnSetter(); - if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups)) + if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers)) return false; if (!*holder) { diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index 961df18aa..4a1791798 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -95,8 +95,7 @@ class BaselineInspector public: typedef Vector ReceiverVector; typedef Vector ObjectGroupVector; - MOZ_MUST_USE bool maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups); + MOZ_MUST_USE bool maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers); SetElemICInspector setElemICInspector(jsbytecode* pc) { return makeICInspector(pc, ICStub::SetElem_Fallback); @@ -131,12 +130,10 @@ class BaselineInspector MOZ_MUST_USE bool commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape, JSFunction** commonGetter, Shape** globalShape, - bool* isOwnProperty, ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups); + bool* isOwnProperty, ReceiverVector& receivers); MOZ_MUST_USE bool commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape, JSFunction** commonSetter, bool* isOwnProperty, - ReceiverVector& receivers, - ObjectGroupVector& convertUnboxedGroups); + ReceiverVector& receivers); MOZ_MUST_USE bool instanceOfData(jsbytecode* pc, Shape** shape, uint32_t* slot, JSObject** prototypeObject); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 54d05cac4..28fa53aa8 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -9012,8 +9012,6 @@ IonBuilder::jsop_getelem() } obj = maybeUnboxForPropertyAccess(obj); - if (obj->type() == MIRType::Object) - obj = convertUnboxedObjects(obj); bool emitted = false; @@ -10137,7 +10135,7 @@ IonBuilder::jsop_setelem() MDefinition* value = current->pop(); MDefinition* index = current->pop(); - MDefinition* object = convertUnboxedObjects(current->pop()); + MDefinition* object = current->pop(); trackTypeInfo(TrackedTypeSite::Receiver, object->type(), object->resultTypeSet()); trackTypeInfo(TrackedTypeSite::Index, index->type(), index->resultTypeSet()); @@ -11496,8 +11494,6 @@ IonBuilder::jsop_getprop(PropertyName* name) } obj = maybeUnboxForPropertyAccess(obj); - if (obj->type() == MIRType::Object) - obj = convertUnboxedObjects(obj); BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), obj, name, types); @@ -11939,49 +11935,6 @@ IonBuilder::getPropTryComplexPropOfTypedObject(bool* emitted, fieldPrediction, fieldTypeObj); } -MDefinition* -IonBuilder::convertUnboxedObjects(MDefinition* obj) -{ - // If obj might be in any particular unboxed group which should be - // converted to a native representation, perform that conversion. This does - // not guarantee the object will not have such a group afterwards, if the - // object's possible groups are not precisely known. - TemporaryTypeSet* types = obj->resultTypeSet(); - if (!types || types->unknownObject() || !types->objectOrSentinel()) - return obj; - - BaselineInspector::ObjectGroupVector list(alloc()); - for (size_t i = 0; i < types->getObjectCount(); i++) { - TypeSet::ObjectKey* key = obj->resultTypeSet()->getObject(i); - if (!key || !key->isGroup()) - continue; - - if (UnboxedLayout* layout = key->group()->maybeUnboxedLayout()) { - AutoEnterOOMUnsafeRegion oomUnsafe; - if (layout->nativeGroup() && !list.append(key->group())) - oomUnsafe.crash("IonBuilder::convertUnboxedObjects"); - } - } - - return convertUnboxedObjects(obj, list); -} - -MDefinition* -IonBuilder::convertUnboxedObjects(MDefinition* obj, - const BaselineInspector::ObjectGroupVector& list) -{ - for (size_t i = 0; i < list.length(); i++) { - ObjectGroup* group = list[i]; - if (TemporaryTypeSet* types = obj->resultTypeSet()) { - if (!types->hasType(TypeSet::ObjectType(group))) - continue; - } - obj = MConvertUnboxedObjectToNative::New(alloc(), obj, group); - current->add(obj->toInstruction()); - } - return obj; -} - bool IonBuilder::getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName* name, BarrierKind barrier, TemporaryTypeSet* types) @@ -12163,14 +12116,11 @@ IonBuilder::getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* nam MDefinition* IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape, const BaselineInspector::ReceiverVector& receivers, - const BaselineInspector::ObjectGroupVector& convertUnboxedGroups, bool isOwnProperty) { MOZ_ASSERT(holder); MOZ_ASSERT(holderShape); - obj = convertUnboxedObjects(obj, convertUnboxedGroups); - if (isOwnProperty) { MOZ_ASSERT(receivers.empty()); return addShapeGuard(obj, holderShape, Bailout_ShapeGuard); @@ -12194,10 +12144,8 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName JSObject* foundProto = nullptr; bool isOwnProperty = false; BaselineInspector::ReceiverVector receivers(alloc()); - BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc()); if (!inspector->commonGetPropFunction(pc, &foundProto, &lastProperty, &commonGetter, - &globalShape, &isOwnProperty, - receivers, convertUnboxedGroups)) + &globalShape, &isOwnProperty, receivers)) { return true; } @@ -12213,8 +12161,7 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName // If type information is bad, we can still optimize the getter if we // shape guard. obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty, - receivers, convertUnboxedGroups, - isOwnProperty); + receivers, isOwnProperty); if (!obj) return false; } @@ -12381,15 +12328,12 @@ IonBuilder::getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName MOZ_ASSERT(*emitted == false); BaselineInspector::ReceiverVector receivers(alloc()); - BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc()); - if (!inspector->maybeInfoForPropertyOp(pc, receivers, convertUnboxedGroups)) + if (!inspector->maybeInfoForPropertyOp(pc, receivers)) return false; if (!canInlinePropertyOpShapes(receivers)) return true; - obj = convertUnboxedObjects(obj, convertUnboxedGroups); - MIRType rvalType = types->getKnownMIRType(); if (barrier != BarrierKind::NoBarrier || IsNullOrUndefined(rvalType)) rvalType = MIRType::Value; @@ -12692,7 +12636,7 @@ bool IonBuilder::jsop_setprop(PropertyName* name) { MDefinition* value = current->pop(); - MDefinition* obj = convertUnboxedObjects(current->pop()); + MDefinition* obj = current->pop(); bool emitted = false; startTrackingOptimizations(); @@ -12765,10 +12709,8 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj, JSObject* foundProto = nullptr; bool isOwnProperty; BaselineInspector::ReceiverVector receivers(alloc()); - BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc()); if (!inspector->commonSetPropFunction(pc, &foundProto, &lastProperty, &commonSetter, - &isOwnProperty, - receivers, convertUnboxedGroups)) + &isOwnProperty, receivers)) { trackOptimizationOutcome(TrackedOutcome::NoProtoFound); return true; @@ -12783,8 +12725,7 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj, // If type information is bad, we can still optimize the setter if we // shape guard. obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty, - receivers, convertUnboxedGroups, - isOwnProperty); + receivers, isOwnProperty); if (!obj) return false; } @@ -13146,15 +13087,12 @@ IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj, } BaselineInspector::ReceiverVector receivers(alloc()); - BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc()); - if (!inspector->maybeInfoForPropertyOp(pc, receivers, convertUnboxedGroups)) + if (!inspector->maybeInfoForPropertyOp(pc, receivers)) return false; if (!canInlinePropertyOpShapes(receivers)) return true; - obj = convertUnboxedObjects(obj, convertUnboxedGroups); - if (receivers.length() == 1) { if (!receivers[0].group) { // Monomorphic store to a native object. @@ -13884,7 +13822,7 @@ IonBuilder::jsop_setaliasedvar(EnvironmentCoordinate ec) bool IonBuilder::jsop_in() { - MDefinition* obj = convertUnboxedObjects(current->pop()); + MDefinition* obj = current->pop(); MDefinition* id = current->pop(); bool emitted = false; diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index f24ef30c8..2880c7ea1 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -1041,7 +1041,6 @@ class IonBuilder MDefinition* addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape, const BaselineInspector::ReceiverVector& receivers, - const BaselineInspector::ObjectGroupVector& convertUnboxedGroups, bool isOwnProperty); MOZ_MUST_USE bool annotateGetPropertyCache(MDefinition* obj, PropertyName* name, @@ -1059,9 +1058,6 @@ class IonBuilder ResultWithOOM testNotDefinedProperty(MDefinition* obj, jsid id); uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed); - MDefinition* convertUnboxedObjects(MDefinition* obj); - MDefinition* convertUnboxedObjects(MDefinition* obj, - const BaselineInspector::ObjectGroupVector& list); uint32_t getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValueType* punboxedType); MInstruction* loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 01755094a..41ccd0ca7 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -615,7 +615,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) OBJECT_FLAG_LENGTH_OVERFLOW | OBJECT_FLAG_ITERATED; - MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); + MDefinition* obj = callInfo.thisArg(); TemporaryTypeSet* thisTypes = obj->resultTypeSet(); if (!thisTypes) return InliningStatus_NotInlined; @@ -743,7 +743,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) return InliningStatus_NotInlined; } - MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); + MDefinition* obj = callInfo.thisArg(); MDefinition* value = callInfo.getArg(0); if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, nullptr, &value, /* canModify = */ false)) @@ -822,7 +822,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) return InliningStatus_NotInlined; } - MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); + MDefinition* obj = callInfo.thisArg(); // Ensure |this| and result are objects. if (getInlineReturnType() != MIRType::Object) @@ -2152,7 +2152,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo) if (callInfo.argc() != 3) return InliningStatus_NotInlined; - MDefinition* obj = convertUnboxedObjects(callInfo.getArg(0)); + MDefinition* obj = callInfo.getArg(0); MDefinition* id = callInfo.getArg(1); MDefinition* value = callInfo.getArg(2); -- cgit v1.2.3 From d40bcc350ce47de4a92dd1dc7f7162dc1154678b Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 15 May 2019 13:18:33 +0000 Subject: Remove Unboxed Objects in ScalarReplacement A note about the Scalar Replacement Changes: The M{Load,Store}Unboxed* instructions in theory could be used to manipulate and analyze typed arrays. However, TypedArrays should already be excluded from eligibility because of the potential for cross-thread sharing in a SharedArrayBuffer world, and so the only support in Scalar Replacement here is for Unboxed Objects, meaning it can all be removed. --- js/src/jit/ScalarReplacement.cpp | 112 --------------------------------------- 1 file changed, 112 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index 4614b2162..2065c0371 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -13,7 +13,6 @@ #include "jit/MIR.h" #include "jit/MIRGenerator.h" #include "jit/MIRGraph.h" -#include "vm/UnboxedObject.h" #include "jsobjinlines.h" @@ -183,25 +182,6 @@ IsObjectEscaped(MInstruction* ins, JSObject* objDefault) JitSpewDef(JitSpew_Escape, "is escaped by\n", def); return true; - case MDefinition::Op_LoadUnboxedScalar: - case MDefinition::Op_StoreUnboxedScalar: - case MDefinition::Op_LoadUnboxedObjectOrNull: - case MDefinition::Op_StoreUnboxedObjectOrNull: - case MDefinition::Op_LoadUnboxedString: - case MDefinition::Op_StoreUnboxedString: - // Not escaped if it is the first argument. - if (def->indexOf(*i) != 0) { - JitSpewDef(JitSpew_Escape, "is escaped by\n", def); - return true; - } - - if (!def->getOperand(1)->isConstant()) { - JitSpewDef(JitSpew_Escape, "is addressed with unknown index\n", def); - return true; - } - - break; - case MDefinition::Op_PostWriteBarrier: break; @@ -305,12 +285,6 @@ class ObjectMemoryView : public MDefinitionVisitorDefaultNoop void visitGuardShape(MGuardShape* ins); void visitFunctionEnvironment(MFunctionEnvironment* ins); void visitLambda(MLambda* ins); - void visitStoreUnboxedScalar(MStoreUnboxedScalar* ins); - void visitLoadUnboxedScalar(MLoadUnboxedScalar* ins); - void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins); - void visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins); - void visitStoreUnboxedString(MStoreUnboxedString* ins); - void visitLoadUnboxedString(MLoadUnboxedString* ins); private: void storeOffset(MInstruction* ins, size_t offset, MDefinition* value); @@ -656,21 +630,6 @@ ObjectMemoryView::visitLambda(MLambda* ins) ins->setIncompleteObject(); } -static size_t -GetOffsetOf(MDefinition* index, size_t width, int32_t baseOffset) -{ - int32_t idx = index->toConstant()->toInt32(); - MOZ_ASSERT(idx >= 0); - MOZ_ASSERT(baseOffset >= 0 && size_t(baseOffset) >= UnboxedPlainObject::offsetOfData()); - return idx * width + baseOffset - UnboxedPlainObject::offsetOfData(); -} - -static size_t -GetOffsetOf(MDefinition* index, Scalar::Type type, int32_t baseOffset) -{ - return GetOffsetOf(index, Scalar::byteSize(type), baseOffset); -} - void ObjectMemoryView::storeOffset(MInstruction* ins, size_t offset, MDefinition* value) { @@ -700,77 +659,6 @@ ObjectMemoryView::loadOffset(MInstruction* ins, size_t offset) ins->block()->discard(ins); } -void -ObjectMemoryView::visitStoreUnboxedScalar(MStoreUnboxedScalar* ins) -{ - // Skip stores made on other objects. - if (ins->elements() != obj_) - return; - - size_t offset = GetOffsetOf(ins->index(), ins->storageType(), ins->offsetAdjustment()); - storeOffset(ins, offset, ins->value()); -} - -void -ObjectMemoryView::visitLoadUnboxedScalar(MLoadUnboxedScalar* ins) -{ - // Skip loads made on other objects. - if (ins->elements() != obj_) - return; - - // Replace load by the slot value. - size_t offset = GetOffsetOf(ins->index(), ins->storageType(), ins->offsetAdjustment()); - loadOffset(ins, offset); -} - -void -ObjectMemoryView::visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins) -{ - // Skip stores made on other objects. - if (ins->elements() != obj_) - return; - - // Clone the state and update the slot value. - size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment()); - storeOffset(ins, offset, ins->value()); -} - -void -ObjectMemoryView::visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins) -{ - // Skip loads made on other objects. - if (ins->elements() != obj_) - return; - - // Replace load by the slot value. - size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment()); - loadOffset(ins, offset); -} - -void -ObjectMemoryView::visitStoreUnboxedString(MStoreUnboxedString* ins) -{ - // Skip stores made on other objects. - if (ins->elements() != obj_) - return; - - // Clone the state and update the slot value. - size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment()); - storeOffset(ins, offset, ins->value()); -} - -void -ObjectMemoryView::visitLoadUnboxedString(MLoadUnboxedString* ins) -{ - // Skip loads made on other objects. - if (ins->elements() != obj_) - return; - - // Replace load by the slot value. - size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment()); - loadOffset(ins, offset); -} - static bool IndexOf(MDefinition* ins, int32_t* res) { -- cgit v1.2.3 From 543fa1674bcb4f8c40f0ef6e4c5514ea161def5a Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 16 May 2019 13:13:36 +0000 Subject: Remove Unboxed Objects from vm/ Part 1 + fix deprot --- js/src/jit/OptimizationTracking.cpp | 2 ++ js/src/jit/SharedIC.cpp | 1 + 2 files changed, 3 insertions(+) (limited to 'js/src/jit') diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index 308def041..b42634d43 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -15,9 +15,11 @@ #include "jit/JitcodeMap.h" #include "jit/JitSpewer.h" #include "js/TrackedOptimizationInfo.h" +#include "vm/UnboxedObject.h" #include "vm/ObjectGroup-inl.h" #include "vm/TypeInference-inl.h" +#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 767cff661..2475dfb22 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -27,6 +27,7 @@ #endif #include "jit/VMFunctions.h" #include "vm/Interpreter.h" +#include "vm/NativeObject-inl.h" #include "jit/MacroAssembler-inl.h" #include "vm/Interpreter-inl.h" -- cgit v1.2.3 From fa8bfa1a00ca88dd0ff5f8dcfb89dee5fd01c639 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 16 May 2019 19:54:19 +0000 Subject: Remove unboxed object code from jit, Part 1 --- js/src/jit/AliasAnalysisShared.cpp | 2 - js/src/jit/CodeGenerator.cpp | 61 ------------ js/src/jit/CodeGenerator.h | 3 - js/src/jit/IonAnalysis.cpp | 2 - js/src/jit/IonBuilder.cpp | 192 +----------------------------------- js/src/jit/IonBuilder.h | 6 -- js/src/jit/Lowering.cpp | 26 ----- js/src/jit/Lowering.h | 3 - js/src/jit/MIR.cpp | 161 +++++------------------------- js/src/jit/MIR.h | 131 ------------------------ js/src/jit/MOpcodes.h | 3 - js/src/jit/shared/LIR-shared.h | 48 --------- js/src/jit/shared/LOpcodes-shared.h | 3 - 13 files changed, 26 insertions(+), 615 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/AliasAnalysisShared.cpp b/js/src/jit/AliasAnalysisShared.cpp index 81c0fd067..3b83df74e 100644 --- a/js/src/jit/AliasAnalysisShared.cpp +++ b/js/src/jit/AliasAnalysisShared.cpp @@ -114,8 +114,6 @@ GetObject(const MDefinition* ins) case MDefinition::Op_GuardObjectGroup: case MDefinition::Op_GuardObjectIdentity: case MDefinition::Op_GuardClass: - case MDefinition::Op_GuardUnboxedExpando: - case MDefinition::Op_LoadUnboxedExpando: case MDefinition::Op_LoadSlot: case MDefinition::Op_StoreSlot: case MDefinition::Op_InArray: diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 16d026092..6d1fb6b9b 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3031,15 +3031,6 @@ GuardReceiver(MacroAssembler& masm, const ReceiverGuard& guard, { if (guard.group) { masm.branchTestObjGroup(Assembler::NotEqual, obj, guard.group, miss); - - Address expandoAddress(obj, UnboxedPlainObject::offsetOfExpando()); - if (guard.shape) { - masm.loadPtr(expandoAddress, scratch); - masm.branchPtr(Assembler::Equal, scratch, ImmWord(0), miss); - masm.branchTestObjShape(Assembler::NotEqual, scratch, guard.shape, miss); - } else if (checkNullExpando) { - masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), miss); - } } else { masm.branchTestObjShape(Assembler::NotEqual, obj, guard.shape, miss); } @@ -3077,13 +3068,6 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction* ins, Register obj, Regis masm.loadPtr(Address(target, NativeObject::offsetOfSlots()), scratch); masm.loadTypedOrValue(Address(scratch, offset), output); } - } else { - masm.comment("loadUnboxedProperty"); - const UnboxedLayout::Property* property = - receiver.group->unboxedLayout().lookup(mir->name()); - Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset); - - masm.loadUnboxedProperty(propertyAddr, property->type, output); } if (i == mir->numReceivers() - 1) { @@ -3124,8 +3108,6 @@ EmitUnboxedPreBarrier(MacroAssembler &masm, T address, JSValueType type) masm.patchableCallPreBarrier(address, MIRType::Object); else if (type == JSVAL_TYPE_STRING) masm.patchableCallPreBarrier(address, MIRType::String); - else - MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type)); } void @@ -3161,13 +3143,6 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction* ins, Register obj, Regis emitPreBarrier(addr); masm.storeConstantOrRegister(value, addr); } - } else { - const UnboxedLayout::Property* property = - receiver.group->unboxedLayout().lookup(mir->name()); - Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset); - - EmitUnboxedPreBarrier(masm, propertyAddr, property->type); - masm.storeUnboxedProperty(propertyAddr, property->type, value, nullptr); } if (i == mir->numReceivers() - 1) { @@ -3332,27 +3307,6 @@ CodeGenerator::visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir) masm.bind(&done); } -void -CodeGenerator::visitGuardUnboxedExpando(LGuardUnboxedExpando* lir) -{ - Label miss; - - Register obj = ToRegister(lir->object()); - masm.branchPtr(lir->mir()->requireExpando() ? Assembler::Equal : Assembler::NotEqual, - Address(obj, UnboxedPlainObject::offsetOfExpando()), ImmWord(0), &miss); - - bailoutFrom(&miss, lir->snapshot()); -} - -void -CodeGenerator::visitLoadUnboxedExpando(LLoadUnboxedExpando* lir) -{ - Register obj = ToRegister(lir->object()); - Register result = ToRegister(lir->getDef(0)); - - masm.loadPtr(Address(obj, UnboxedPlainObject::offsetOfExpando()), result); -} - void CodeGenerator::visitTypeBarrierV(LTypeBarrierV* lir) { @@ -8576,21 +8530,6 @@ static const VMFunction ConvertUnboxedArrayObjectToNativeInfo = FunctionInfo(UnboxedArrayObject::convertToNative, "UnboxedArrayObject::convertToNative"); -void -CodeGenerator::visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir) -{ - Register object = ToRegister(lir->getOperand(0)); - - OutOfLineCode* ool = oolCallVM(lir->mir()->group()->unboxedLayoutDontCheckGeneration().isArray() - ? ConvertUnboxedArrayObjectToNativeInfo - : ConvertUnboxedPlainObjectToNativeInfo, - lir, ArgList(object), StoreNothing()); - - masm.branchPtr(Assembler::Equal, Address(object, JSObject::offsetOfGroup()), - ImmGCPtr(lir->mir()->group()), ool->entry()); - masm.bind(ool->rejoin()); -} - typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue); static const VMFunction ArrayPopDenseInfo = FunctionInfo(jit::ArrayPopDense, "ArrayPopDense"); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index b226f6cc9..292f163b5 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -148,8 +148,6 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir); void visitGuardObjectIdentity(LGuardObjectIdentity* guard); void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir); - void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir); - void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir); void visitTypeBarrierV(LTypeBarrierV* lir); void visitTypeBarrierO(LTypeBarrierO* lir); void visitMonitorTypes(LMonitorTypes* lir); @@ -310,7 +308,6 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitFallibleStoreElementV(LFallibleStoreElementV* lir); void visitFallibleStoreElementT(LFallibleStoreElementT* lir); void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir); - void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir); void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj, Register elementsTemp, Register lengthTemp, TypedOrValueRegister out); void visitArrayPopShiftV(LArrayPopShiftV* lir); diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index d255c32a8..41c71c9c3 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -3515,8 +3515,6 @@ PassthroughOperand(MDefinition* def) return def->toConvertElementsToDoubles()->elements(); if (def->isMaybeCopyElementsForWrite()) return def->toMaybeCopyElementsForWrite()->object(); - if (def->isConvertUnboxedObjectToNative()) - return def->toConvertUnboxedObjectToNative()->object(); return nullptr; } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 28fa53aa8..af85011be 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -32,7 +32,6 @@ #include "vm/EnvironmentObject-inl.h" #include "vm/NativeObject-inl.h" #include "vm/ObjectGroup-inl.h" -#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; @@ -6392,7 +6391,7 @@ IonBuilder::createThisScriptedSingleton(JSFunction* target, MDefinition* callee) JSObject* templateObject = inspector->getTemplateObject(pc); if (!templateObject) return nullptr; - if (!templateObject->is() && !templateObject->is()) + if (!templateObject->is()) return nullptr; if (templateObject->staticPrototype() != proto) return nullptr; @@ -6429,7 +6428,7 @@ IonBuilder::createThisScriptedBaseline(MDefinition* callee) JSObject* templateObject = inspector->getTemplateObject(pc); if (!templateObject) return nullptr; - if (!templateObject->is() && !templateObject->is()) + if (!templateObject->is()) return nullptr; Shape* shape = target->lookupPure(compartment->runtime()->names().prototype); @@ -7718,8 +7717,6 @@ IonBuilder::jsop_initprop(PropertyName* name) if (templateObject->is()) { if (!templateObject->as().containsPure(name)) useSlowPath = true; - } else { - MOZ_ASSERT(templateObject->as().layout().lookup(name)); } } else { useSlowPath = true; @@ -8178,8 +8175,7 @@ IonBuilder::maybeMarkEmpty(MDefinition* ins) static bool ClassHasEffectlessLookup(const Class* clasp) { - return (clasp == &UnboxedPlainObject::class_) || - (clasp == &UnboxedArrayObject::class_) || + return (clasp == &UnboxedArrayObject::class_) || IsTypedObjectClass(clasp) || (clasp->isNative() && !clasp->getOpsLookupProperty()); } @@ -10970,11 +10966,8 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_ } // Definite slots will always be fixed slots when they are in the - // allowable range for fixed slots, except for objects which were - // converted from unboxed objects and have a smaller allocation size. + // allowable range for fixed slots. size_t nfixed = NativeObject::MAX_FIXED_SLOTS; - if (ObjectGroup* group = key->group()->maybeOriginalUnboxedGroup()) - nfixed = gc::GetGCKindSlots(group->unboxedLayout().getAllocKind()); uint32_t propertySlot = property.maybeTypes()->definiteSlot(); if (slot == UINT32_MAX) { @@ -11031,8 +11024,6 @@ IonBuilder::getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValu return UINT32_MAX; } - key->watchStateChangeForUnboxedConvertedToNative(constraints()); - if (offset == UINT32_MAX) { offset = property->offset; *punboxedType = property->type; @@ -11565,11 +11556,6 @@ IonBuilder::jsop_getprop(PropertyName* name) if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted) return emitted; - // Try to emit loads from unboxed objects. - trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed); - if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted) - return emitted; - // Try to inline a common property getter, or make a call. trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted) @@ -12085,34 +12071,6 @@ IonBuilder::loadUnboxedValue(MDefinition* elements, size_t elementsOffset, return load; } -bool -IonBuilder::getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name, - BarrierKind barrier, TemporaryTypeSet* types) -{ - MOZ_ASSERT(*emitted == false); - - JSValueType unboxedType; - uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType); - if (offset == UINT32_MAX) - return true; - - if (obj->type() != MIRType::Object) { - MGuardObject* guard = MGuardObject::New(alloc(), obj); - current->add(guard); - obj = guard; - } - - MInstruction* load = loadUnboxedProperty(obj, offset, unboxedType, barrier, types); - current->push(load); - - if (!pushTypeBarrier(load, types, barrier)) - return false; - - trackOptimizationSuccess(); - *emitted = true; - return true; -} - MDefinition* IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape, const BaselineInspector::ReceiverVector& receivers, @@ -12356,45 +12314,6 @@ IonBuilder::getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName return true; } - if (receivers[0].shape) { - // Monomorphic load from an unboxed object expando. - spew("Inlining monomorphic unboxed expando GETPROP"); - - obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard); - obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard); - - MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj); - current->add(expando); - - expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard); - - Shape* shape = receivers[0].shape->searchLinear(NameToId(name)); - MOZ_ASSERT(shape); - - if (!loadSlot(expando, shape, rvalType, barrier, types)) - return false; - - trackOptimizationOutcome(TrackedOutcome::Monomorphic); - *emitted = true; - return true; - } - - // Monomorphic load from an unboxed object. - ObjectGroup* group = receivers[0].group; - if (obj->resultTypeSet() && !obj->resultTypeSet()->hasType(TypeSet::ObjectType(group))) - return true; - - obj = addGroupGuard(obj, group, Bailout_ShapeGuard); - - const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name); - MInstruction* load = loadUnboxedProperty(obj, property->offset, property->type, barrier, types); - current->push(load); - - if (!pushTypeBarrier(load, types, barrier)) - return false; - - trackOptimizationOutcome(TrackedOutcome::Monomorphic); - *emitted = true; return true; } @@ -12669,13 +12588,6 @@ IonBuilder::jsop_setprop(PropertyName* name) bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value, /* canModify = */ true); - if (!forceInlineCaches()) { - // Try to emit stores to unboxed objects. - trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed); - if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; - } - // Add post barrier if needed. The instructions above manage any post // barriers they need directly. if (NeedsPostBarrier(value)) @@ -13040,40 +12952,6 @@ IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t e return store; } -bool -IonBuilder::setPropTryUnboxed(bool* emitted, MDefinition* obj, - PropertyName* name, MDefinition* value, - bool barrier, TemporaryTypeSet* objTypes) -{ - MOZ_ASSERT(*emitted == false); - - if (barrier) { - trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); - return true; - } - - JSValueType unboxedType; - uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType); - if (offset == UINT32_MAX) - return true; - - if (obj->type() != MIRType::Object) { - MGuardObject* guard = MGuardObject::New(alloc(), obj); - current->add(guard); - obj = guard; - } - - MInstruction* store = storeUnboxedProperty(obj, offset, unboxedType, value); - - current->push(value); - - if (!resumeAfter(store)) - return false; - - *emitted = true; - return true; -} - bool IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name, MDefinition* value, @@ -13112,46 +12990,6 @@ IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj, return true; } - if (receivers[0].shape) { - // Monomorphic store to an unboxed object expando. - spew("Inlining monomorphic unboxed expando SETPROP"); - - obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard); - obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard); - - MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj); - current->add(expando); - - expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard); - - Shape* shape = receivers[0].shape->searchLinear(NameToId(name)); - MOZ_ASSERT(shape); - - bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name)); - if (!storeSlot(expando, shape, value, needsBarrier)) - return false; - - trackOptimizationOutcome(TrackedOutcome::Monomorphic); - *emitted = true; - return true; - } - - // Monomorphic store to an unboxed object. - spew("Inlining monomorphic unboxed SETPROP"); - - ObjectGroup* group = receivers[0].group; - if (!objTypes->hasType(TypeSet::ObjectType(group))) - return true; - - obj = addGroupGuard(obj, group, Bailout_ShapeGuard); - - const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name); - storeUnboxedProperty(obj, property->offset, property->type, value); - - current->push(value); - - trackOptimizationOutcome(TrackedOutcome::Monomorphic); - *emitted = true; return true; } @@ -14178,19 +14016,6 @@ IonBuilder::addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bail return guard; } -MInstruction* -IonBuilder::addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind) -{ - MGuardUnboxedExpando* guard = MGuardUnboxedExpando::New(alloc(), obj, hasExpando, bailoutKind); - current->add(guard); - - // If a shape guard failed in the past, don't optimize group guards. - if (failedShapeGuard_) - guard->setNotMovable(); - - return guard; -} - MInstruction* IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj, const BaselineInspector::ReceiverVector& receivers) @@ -14200,15 +14025,6 @@ IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj, // Monomorphic guard on a native object. return addShapeGuard(obj, receivers[0].shape, Bailout_ShapeGuard); } - - if (!receivers[0].shape) { - // Guard on an unboxed object that does not have an expando. - obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard); - return addUnboxedExpandoGuard(obj, /* hasExpando = */ false, Bailout_ShapeGuard); - } - - // Monomorphic receiver guards are not yet supported when the receiver - // is an unboxed object with an expando. } MGuardReceiverPolymorphic* guard = MGuardReceiverPolymorphic::New(alloc(), obj); diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 2880c7ea1..77528ad37 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -401,7 +401,6 @@ class IonBuilder MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length); MInstruction* addShapeGuard(MDefinition* obj, Shape* const shape, BailoutKind bailoutKind); MInstruction* addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bailoutKind); - MInstruction* addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind); MInstruction* addSharedTypedArrayGuard(MDefinition* obj); MInstruction* @@ -441,8 +440,6 @@ class IonBuilder BarrierKind barrier, TemporaryTypeSet* types); MOZ_MUST_USE bool getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyName* name, BarrierKind barrier, TemporaryTypeSet* types); - MOZ_MUST_USE bool getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name, - BarrierKind barrier, TemporaryTypeSet* types); MOZ_MUST_USE bool getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName* name, TemporaryTypeSet* types); MOZ_MUST_USE bool getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name, @@ -475,9 +472,6 @@ class IonBuilder MOZ_MUST_USE bool setPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName* name, MDefinition* value, bool barrier, TemporaryTypeSet* objTypes); - MOZ_MUST_USE bool setPropTryUnboxed(bool* emitted, MDefinition* obj, - PropertyName* name, MDefinition* value, - bool barrier, TemporaryTypeSet* objTypes); MOZ_MUST_USE bool setPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name, MDefinition* value, bool barrier, TemporaryTypeSet* objTypes); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 709de9987..aafa57c09 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3251,14 +3251,6 @@ LIRGenerator::visitStoreUnboxedString(MStoreUnboxedString* ins) add(lir, ins); } -void -LIRGenerator::visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins) -{ - LInstruction* check = new(alloc()) LConvertUnboxedObjectToNative(useRegister(ins->object())); - add(check, ins); - assignSafepoint(check, ins); -} - void LIRGenerator::visitEffectiveAddress(MEffectiveAddress* ins) { @@ -3776,24 +3768,6 @@ LIRGenerator::visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins) redefine(ins, ins->object()); } -void -LIRGenerator::visitGuardUnboxedExpando(MGuardUnboxedExpando* ins) -{ - LGuardUnboxedExpando* guard = - new(alloc()) LGuardUnboxedExpando(useRegister(ins->object())); - assignSnapshot(guard, ins->bailoutKind()); - add(guard, ins); - redefine(ins, ins->object()); -} - -void -LIRGenerator::visitLoadUnboxedExpando(MLoadUnboxedExpando* ins) -{ - LLoadUnboxedExpando* lir = - new(alloc()) LLoadUnboxedExpando(useRegisterAtStart(ins->object())); - define(lir, ins); -} - void LIRGenerator::visitAssertRange(MAssertRange* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 9b4095aec..e36620bce 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -232,7 +232,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitFallibleStoreElement(MFallibleStoreElement* ins); void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins); void visitStoreUnboxedString(MStoreUnboxedString* ins); - void visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins); void visitEffectiveAddress(MEffectiveAddress* ins); void visitArrayPopShift(MArrayPopShift* ins); void visitArrayPush(MArrayPush* ins); @@ -256,8 +255,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitGuardObject(MGuardObject* ins); void visitGuardString(MGuardString* ins); void visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins); - void visitGuardUnboxedExpando(MGuardUnboxedExpando* ins); - void visitLoadUnboxedExpando(MLoadUnboxedExpando* ins); void visitPolyInlineGuard(MPolyInlineGuard* ins); void visitAssertRange(MAssertRange* ins); void visitCallGetProperty(MCallGetProperty* ins); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 287b87582..1f33b2174 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -4810,35 +4810,8 @@ MBeta::printOpcode(GenericPrinter& out) const bool MCreateThisWithTemplate::canRecoverOnBailout() const { - MOZ_ASSERT(templateObject()->is() || templateObject()->is()); - MOZ_ASSERT_IF(templateObject()->is(), - !templateObject()->as().denseElementsAreCopyOnWrite()); - return true; -} - -bool -OperandIndexMap::init(TempAllocator& alloc, JSObject* templateObject) -{ - const UnboxedLayout& layout = - templateObject->as().layoutDontCheckGeneration(); - - const UnboxedLayout::PropertyVector& properties = layout.properties(); - MOZ_ASSERT(properties.length() < 255); - - // Allocate an array of indexes, where the top of each field correspond to - // the index of the operand in the MObjectState instance. - if (!map.init(alloc, layout.size())) - return false; - - // Reset all indexes to 0, which is an error code. - for (size_t i = 0; i < map.length(); i++) - map[i] = 0; - - // Map the property offsets to the indexes of MObjectState operands. - uint8_t index = 1; - for (size_t i = 0; i < properties.length(); i++, index++) - map[properties[i].offset] = index; - + MOZ_ASSERT(templateObject()->is()); + MOZ_ASSERT(!templateObject()->as().denseElementsAreCopyOnWrite()); return true; } @@ -4858,17 +4831,11 @@ MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandInd setResultType(MIRType::Object); setRecoveredOnBailout(); - if (templateObject->is()) { - NativeObject* nativeObject = &templateObject->as(); - numSlots_ = nativeObject->slotSpan(); - numFixedSlots_ = nativeObject->numFixedSlots(); - } else { - const UnboxedLayout& layout = - templateObject->as().layoutDontCheckGeneration(); - // Same as UnboxedLayout::makeNativeGroup - numSlots_ = layout.properties().length(); - numFixedSlots_ = gc::GetGCKindSlots(layout.getAllocKind()); - } + MOZ_ASSERT(templateObject->is()); + + NativeObject* nativeObject = &templateObject->as(); + numSlots_ = nativeObject->slotSpan(); + numFixedSlots_ = nativeObject->numFixedSlots(); operandIndex_ = operandIndex; } @@ -4905,39 +4872,21 @@ MObjectState::initFromTemplateObject(TempAllocator& alloc, MDefinition* undefine // the template object. This is needed to account values which are baked in // the template objects and not visible in IonMonkey, such as the // uninitialized-lexical magic value of call objects. - if (templateObject->is()) { - UnboxedPlainObject& unboxedObject = templateObject->as(); - const UnboxedLayout& layout = unboxedObject.layoutDontCheckGeneration(); - const UnboxedLayout::PropertyVector& properties = layout.properties(); - - for (size_t i = 0; i < properties.length(); i++) { - Value val = unboxedObject.getValue(properties[i], /* maybeUninitialized = */ true); - MDefinition *def = undefinedVal; - if (!val.isUndefined()) { - MConstant* ins = val.isObject() ? - MConstant::NewConstraintlessObject(alloc, &val.toObject()) : - MConstant::New(alloc, val); - block()->insertBefore(this, ins); - def = ins; - } - initSlot(i, def); - } - } else { - NativeObject& nativeObject = templateObject->as(); - MOZ_ASSERT(nativeObject.slotSpan() == numSlots()); - - for (size_t i = 0; i < numSlots(); i++) { - Value val = nativeObject.getSlot(i); - MDefinition *def = undefinedVal; - if (!val.isUndefined()) { - MConstant* ins = val.isObject() ? - MConstant::NewConstraintlessObject(alloc, &val.toObject()) : - MConstant::New(alloc, val); - block()->insertBefore(this, ins); - def = ins; - } - initSlot(i, def); + NativeObject& nativeObject = templateObject->as(); + MOZ_ASSERT(nativeObject.slotSpan() == numSlots()); + + MOZ_ASSERT(templateObject->is()); + for (size_t i = 0; i < numSlots(); i++) { + Value val = nativeObject.getSlot(i); + MDefinition *def = undefinedVal; + if (!val.isUndefined()) { + MConstant* ins = val.isObject() ? + MConstant::NewConstraintlessObject(alloc, &val.toObject()) : + MConstant::New(alloc, val); + block()->insertBefore(this, ins); + def = ins; } + initSlot(i, def); } return true; } @@ -4948,14 +4897,7 @@ MObjectState::New(TempAllocator& alloc, MDefinition* obj) JSObject* templateObject = templateObjectOf(obj); MOZ_ASSERT(templateObject, "Unexpected object creation."); - OperandIndexMap* operandIndex = nullptr; - if (templateObject->is()) { - operandIndex = new(alloc) OperandIndexMap; - if (!operandIndex || !operandIndex->init(alloc, templateObject)) - return nullptr; - } - - MObjectState* res = new(alloc) MObjectState(templateObject, operandIndex); + MObjectState* res = new(alloc) MObjectState(templateObject, nullptr); if (!res || !res->init(alloc, obj)) return nullptr; return res; @@ -5862,35 +5804,6 @@ MGetFirstDollarIndex::foldsTo(TempAllocator& alloc) return MConstant::New(alloc, Int32Value(index)); } -MConvertUnboxedObjectToNative* -MConvertUnboxedObjectToNative::New(TempAllocator& alloc, MDefinition* obj, ObjectGroup* group) -{ - MConvertUnboxedObjectToNative* res = new(alloc) MConvertUnboxedObjectToNative(obj, group); - - ObjectGroup* nativeGroup = group->unboxedLayout().nativeGroup(); - - // Make a new type set for the result of this instruction which replaces - // the input group with the native group we will convert it to. - TemporaryTypeSet* types = obj->resultTypeSet(); - if (types && !types->unknownObject()) { - TemporaryTypeSet* newTypes = types->cloneWithoutObjects(alloc.lifoAlloc()); - if (newTypes) { - for (size_t i = 0; i < types->getObjectCount(); i++) { - TypeSet::ObjectKey* key = types->getObject(i); - if (!key) - continue; - if (key->unknownProperties() || !key->isGroup() || key->group() != group) - newTypes->addType(TypeSet::ObjectType(key), alloc.lifoAlloc()); - else - newTypes->addType(TypeSet::ObjectType(nativeGroup), alloc.lifoAlloc()); - } - res->setResultTypeSet(newTypes); - } - } - - return res; -} - bool jit::ElementAccessIsDenseNative(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id) @@ -5945,8 +5858,6 @@ jit::UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* o elementType = layout.elementType(); else return JSVAL_TYPE_MAGIC; - - key->watchStateChangeForUnboxedConvertedToNative(constraints); } return elementType; @@ -6579,23 +6490,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* } } - // Perform additional filtering to make sure that any unboxed property - // being written can accommodate the value. - for (size_t i = 0; i < types->getObjectCount(); i++) { - TypeSet::ObjectKey* key = types->getObject(i); - if (key && key->isGroup() && key->group()->maybeUnboxedLayout()) { - const UnboxedLayout& layout = key->group()->unboxedLayout(); - if (name) { - const UnboxedLayout::Property* property = layout.lookup(name); - if (property && !CanStoreUnboxedType(alloc, property->type, *pvalue)) - return true; - } else { - if (layout.isArray() && !CanStoreUnboxedType(alloc, layout.elementType(), *pvalue)) - return true; - } - } - } - if (success) return false; @@ -6626,17 +6520,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* MOZ_ASSERT(excluded); - // If the excluded object is a group with an unboxed layout, make sure it - // does not have a corresponding native group. Objects with the native - // group might appear even though they are not in the type set. - if (excluded->isGroup()) { - if (UnboxedLayout* layout = excluded->group()->maybeUnboxedLayout()) { - if (layout->nativeGroup()) - return true; - excluded->watchStateChangeForUnboxedConvertedToNative(constraints); - } - } - *pobj = AddGroupGuard(alloc, current, *pobj, excluded, /* bailOnEquality = */ true); return false; } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index fb0f22fc3..3e0421789 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -30,7 +30,6 @@ #include "vm/EnvironmentObject.h" #include "vm/SharedMem.h" #include "vm/TypedArrayCommon.h" -#include "vm/UnboxedObject.h" // Undo windows.h damage on Win64 #undef MemoryBarrier @@ -9742,59 +9741,6 @@ class MStoreUnboxedString ALLOW_CLONE(MStoreUnboxedString) }; -// Passes through an object, after ensuring it is converted from an unboxed -// object to a native representation. -class MConvertUnboxedObjectToNative - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - CompilerObjectGroup group_; - - explicit MConvertUnboxedObjectToNative(MDefinition* obj, ObjectGroup* group) - : MUnaryInstruction(obj), - group_(group) - { - setGuard(); - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(ConvertUnboxedObjectToNative) - NAMED_OPERANDS((0, object)) - - static MConvertUnboxedObjectToNative* New(TempAllocator& alloc, MDefinition* obj, - ObjectGroup* group); - - ObjectGroup* group() const { - return group_; - } - bool congruentTo(const MDefinition* ins) const override { - if (!congruentIfOperandsEqual(ins)) - return false; - return ins->toConvertUnboxedObjectToNative()->group() == group(); - } - AliasSet getAliasSet() const override { - // This instruction can read and write to all parts of the object, but - // is marked as non-effectful so it can be consolidated by LICM and GVN - // and avoid inhibiting other optimizations. - // - // This is valid to do because when unboxed objects might have a native - // group they can be converted to, we do not optimize accesses to the - // unboxed objects and do not guard on their group or shape (other than - // in this opcode). - // - // Later accesses can assume the object has a native representation - // and optimize accordingly. Those accesses cannot be reordered before - // this instruction, however. This is prevented by chaining this - // instruction with the object itself, in the same way as MBoundsCheck. - return AliasSet::None(); - } - bool appendRoots(MRootList& roots) const override { - return roots.append(group_); - } -}; - // Array.prototype.pop or Array.prototype.shift on a dense array. class MArrayPopShift : public MUnaryInstruction, @@ -11174,11 +11120,6 @@ class MGuardShape setMovable(); setResultType(MIRType::Object); setResultTypeSet(obj->resultTypeSet()); - - // Disallow guarding on unboxed object shapes. The group is better to - // guard on, and guarding on the shape can interact badly with - // MConvertUnboxedObjectToNative. - MOZ_ASSERT(shape->getObjectClass() != &UnboxedPlainObject::class_); } public: @@ -11273,11 +11214,6 @@ class MGuardObjectGroup setGuard(); setMovable(); setResultType(MIRType::Object); - - // Unboxed groups which might be converted to natives can't be guarded - // on, due to MConvertUnboxedObjectToNative. - MOZ_ASSERT_IF(group->maybeUnboxedLayoutDontCheckGeneration(), - !group->unboxedLayoutDontCheckGeneration().nativeGroup()); } public: @@ -11386,73 +11322,6 @@ class MGuardClass ALLOW_CLONE(MGuardClass) }; -// Guard on the presence or absence of an unboxed object's expando. -class MGuardUnboxedExpando - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - bool requireExpando_; - BailoutKind bailoutKind_; - - MGuardUnboxedExpando(MDefinition* obj, bool requireExpando, BailoutKind bailoutKind) - : MUnaryInstruction(obj), - requireExpando_(requireExpando), - bailoutKind_(bailoutKind) - { - setGuard(); - setMovable(); - setResultType(MIRType::Object); - } - - public: - INSTRUCTION_HEADER(GuardUnboxedExpando) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - bool requireExpando() const { - return requireExpando_; - } - BailoutKind bailoutKind() const { - return bailoutKind_; - } - bool congruentTo(const MDefinition* ins) const override { - if (!congruentIfOperandsEqual(ins)) - return false; - if (requireExpando() != ins->toGuardUnboxedExpando()->requireExpando()) - return false; - return true; - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } -}; - -// Load an unboxed plain object's expando. -class MLoadUnboxedExpando - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - private: - explicit MLoadUnboxedExpando(MDefinition* object) - : MUnaryInstruction(object) - { - setResultType(MIRType::Object); - setMovable(); - } - - public: - INSTRUCTION_HEADER(LoadUnboxedExpando) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - bool congruentTo(const MDefinition* ins) const override { - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } -}; - // Load from vp[slot] (slots that are not inline in an object). class MLoadSlot : public MUnaryInstruction, diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index fddc1e637..b80d1baf9 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -187,8 +187,6 @@ namespace jit { _(GuardObjectGroup) \ _(GuardObjectIdentity) \ _(GuardClass) \ - _(GuardUnboxedExpando) \ - _(LoadUnboxedExpando) \ _(ArrayLength) \ _(SetArrayLength) \ _(GetNextEntryForIterator) \ @@ -219,7 +217,6 @@ namespace jit { _(StoreUnboxedScalar) \ _(StoreUnboxedObjectOrNull) \ _(StoreUnboxedString) \ - _(ConvertUnboxedObjectToNative) \ _(ArrayPopShift) \ _(ArrayPush) \ _(ArraySlice) \ diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index f4adcc63c..f386d5256 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -5891,22 +5891,6 @@ class LStoreUnboxedPointer : public LInstructionHelper<0, 3, 0> } }; -// If necessary, convert an unboxed object in a particular group to its native -// representation. -class LConvertUnboxedObjectToNative : public LInstructionHelper<0, 1, 0> -{ - public: - LIR_HEADER(ConvertUnboxedObjectToNative) - - explicit LConvertUnboxedObjectToNative(const LAllocation& object) { - setOperand(0, object); - } - - MConvertUnboxedObjectToNative* mir() { - return mir_->toConvertUnboxedObjectToNative(); - } -}; - class LArrayPopShiftV : public LInstructionHelper { public: @@ -7429,38 +7413,6 @@ class LGuardReceiverPolymorphic : public LInstructionHelper<0, 1, 1> } }; -class LGuardUnboxedExpando : public LInstructionHelper<0, 1, 0> -{ - public: - LIR_HEADER(GuardUnboxedExpando) - - explicit LGuardUnboxedExpando(const LAllocation& in) { - setOperand(0, in); - } - const LAllocation* object() { - return getOperand(0); - } - const MGuardUnboxedExpando* mir() const { - return mir_->toGuardUnboxedExpando(); - } -}; - -class LLoadUnboxedExpando : public LInstructionHelper<1, 1, 0> -{ - public: - LIR_HEADER(LoadUnboxedExpando) - - explicit LLoadUnboxedExpando(const LAllocation& in) { - setOperand(0, in); - } - const LAllocation* object() { - return getOperand(0); - } - const MLoadUnboxedExpando* mir() const { - return mir_->toLoadUnboxedExpando(); - } -}; - // Guard that a value is in a TypeSet. class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1> { diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index fe2ab5ea3..6912e8904 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -258,8 +258,6 @@ _(GuardObjectGroup) \ _(GuardObjectIdentity) \ _(GuardClass) \ - _(GuardUnboxedExpando) \ - _(LoadUnboxedExpando) \ _(TypeBarrierV) \ _(TypeBarrierO) \ _(MonitorTypes) \ @@ -287,7 +285,6 @@ _(StoreElementT) \ _(StoreUnboxedScalar) \ _(StoreUnboxedPointer) \ - _(ConvertUnboxedObjectToNative) \ _(ArrayPopShiftV) \ _(ArrayPopShiftT) \ _(ArrayPushV) \ -- cgit v1.2.3 From c2b5f396eb4ed1bd9be5a6625bd823d7a3e63678 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 23 May 2019 02:48:13 +0000 Subject: Remove UnboxedArray code part 1 --- js/src/jit/AliasAnalysisShared.cpp | 4 - js/src/jit/BaselineCacheIR.cpp | 16 -- js/src/jit/BaselineIC.cpp | 146 +-------------- js/src/jit/CacheIR.cpp | 9 +- js/src/jit/CacheIR.h | 5 - js/src/jit/CodeGenerator.cpp | 341 ++++++++---------------------------- js/src/jit/CodeGenerator.h | 4 - js/src/jit/IonBuilder.cpp | 199 +++++++-------------- js/src/jit/IonBuilder.h | 12 +- js/src/jit/IonCaches.cpp | 135 ++------------ js/src/jit/Lowering.cpp | 30 ---- js/src/jit/Lowering.h | 4 - js/src/jit/MCallOptimize.cpp | 71 ++------ js/src/jit/MIR.cpp | 45 ----- js/src/jit/MIR.h | 176 ++----------------- js/src/jit/MOpcodes.h | 4 - js/src/jit/MacroAssembler.cpp | 35 ---- js/src/jit/MacroAssembler.h | 5 +- js/src/jit/ScalarReplacement.cpp | 5 - js/src/jit/SharedIC.cpp | 9 - js/src/jit/VMFunctions.cpp | 12 +- js/src/jit/shared/LIR-shared.h | 66 ------- js/src/jit/shared/LOpcodes-shared.h | 4 - 23 files changed, 199 insertions(+), 1138 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/AliasAnalysisShared.cpp b/js/src/jit/AliasAnalysisShared.cpp index 3b83df74e..0f0d4a66a 100644 --- a/js/src/jit/AliasAnalysisShared.cpp +++ b/js/src/jit/AliasAnalysisShared.cpp @@ -93,10 +93,6 @@ GetObject(const MDefinition* ins) case MDefinition::Op_Elements: case MDefinition::Op_MaybeCopyElementsForWrite: case MDefinition::Op_MaybeToDoubleElement: - case MDefinition::Op_UnboxedArrayLength: - case MDefinition::Op_UnboxedArrayInitializedLength: - case MDefinition::Op_IncrementUnboxedArrayInitializedLength: - case MDefinition::Op_SetUnboxedArrayInitializedLength: case MDefinition::Op_TypedArrayLength: case MDefinition::Op_SetTypedObjectOffset: case MDefinition::Op_SetDisjointTypedElements: diff --git a/js/src/jit/BaselineCacheIR.cpp b/js/src/jit/BaselineCacheIR.cpp index bf96932d1..7fb586811 100644 --- a/js/src/jit/BaselineCacheIR.cpp +++ b/js/src/jit/BaselineCacheIR.cpp @@ -787,9 +787,6 @@ BaselineCacheIRCompiler::emitGuardClass() case GuardClassKind::Array: clasp = &ArrayObject::class_; break; - case GuardClassKind::UnboxedArray: - clasp = &UnboxedArrayObject::class_; - break; case GuardClassKind::MappedArguments: clasp = &MappedArgumentsObject::class_; break; @@ -1003,19 +1000,6 @@ BaselineCacheIRCompiler::emitLoadInt32ArrayLengthResult() return true; } -bool -BaselineCacheIRCompiler::emitLoadUnboxedArrayLengthResult() -{ - Register obj = allocator.useRegister(masm, reader.objOperandId()); - masm.load32(Address(obj, UnboxedArrayObject::offsetOfLength()), R0.scratchReg()); - masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0); - - // The int32 type was monitored when attaching the stub, so we can - // just return. - emitReturnFromIC(); - return true; -} - bool BaselineCacheIRCompiler::emitLoadArgumentsObjectLengthResult() { diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 863c61161..f43fc5bf9 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -280,12 +280,6 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H RootedId id(cx); switch(stub->kind()) { - case ICStub::SetElem_DenseOrUnboxedArray: - case ICStub::SetElem_DenseOrUnboxedArrayAdd: { - id = JSID_VOID; - AddTypePropertyId(cx, obj, id, value); - break; - } case ICStub::SetProp_Native: case ICStub::SetProp_NativeAdd: case ICStub::SetProp_Unboxed: { @@ -1366,7 +1360,7 @@ IsNativeDenseElementAccess(HandleObject obj, HandleValue key) static bool IsNativeOrUnboxedDenseElementAccess(HandleObject obj, HandleValue key) { - if (!obj->isNative() && !obj->is()) + if (!obj->isNative()) return false; if (key.isInt32() && key.toInt32() >= 0 && !obj->is()) return true; @@ -1470,20 +1464,6 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ script = rootedScript; } - // Check for UnboxedArray[int] accesses. - if (obj->is() && rhs.isInt32() && rhs.toInt32() >= 0) { - JitSpew(JitSpew_BaselineIC, " Generating GetElem(UnboxedArray[Int32]) stub"); - ICGetElem_UnboxedArray::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), - obj->group()); - ICStub* unboxedStub = compiler.getStub(compiler.getStubSpace(script)); - if (!unboxedStub) - return false; - - stub->addNewStub(unboxedStub); - *attached = true; - return true; - } - // Check for TypedArray[int] => Number and TypedObject[int] => Number accesses. if ((obj->is() || IsPrimitiveArrayTypedObject(obj)) && rhs.isNumber() && @@ -2089,56 +2069,6 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm) return true; } -// -// GetElem_UnboxedArray -// - -bool -ICGetElem_UnboxedArray::Compiler::generateStubCode(MacroAssembler& masm) -{ - MOZ_ASSERT(engine_ == Engine::Baseline); - - Label failure; - masm.branchTestObject(Assembler::NotEqual, R0, &failure); - masm.branchTestInt32(Assembler::NotEqual, R1, &failure); - - AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); - Register scratchReg = regs.takeAny(); - - // Unbox R0 and group guard. - Register obj = masm.extractObject(R0, ExtractTemp0); - masm.loadPtr(Address(ICStubReg, ICGetElem_UnboxedArray::offsetOfGroup()), scratchReg); - masm.branchTestObjGroup(Assembler::NotEqual, obj, scratchReg, &failure); - - // Unbox key. - Register key = masm.extractInt32(R1, ExtractTemp1); - - // Bounds check. - masm.load32(Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()), - scratchReg); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg); - masm.branch32(Assembler::BelowOrEqual, scratchReg, key, &failure); - - // Load obj->elements. - masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg); - - // Load value. - size_t width = UnboxedTypeSize(elementType_); - BaseIndex addr(scratchReg, key, ScaleFromElemWidth(width)); - masm.loadUnboxedProperty(addr, elementType_, R0); - - // Only monitor the result if its type might change. - if (elementType_ == JSVAL_TYPE_OBJECT) - EmitEnterTypeMonitorIC(masm); - else - EmitReturnFromIC(masm); - - // Failure case - jump to next stub - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - // // GetElem_TypedArray // @@ -2447,10 +2377,6 @@ CanOptimizeDenseOrUnboxedArraySetElem(JSObject* obj, uint32_t index, if (initLength < oldInitLength || capacity < oldCapacity) return false; - // Unboxed arrays need to be able to emit floating point code. - if (obj->is() && !obj->runtimeFromMainThread()->jitSupportsFloatingPoint) - return false; - Shape* shape = obj->maybeShape(); // Cannot optimize if the shape changed. @@ -2871,29 +2797,6 @@ ICSetElem_DenseOrUnboxedArray::Compiler::generateStubCode(MacroAssembler& masm) masm.loadValue(valueAddr, tmpVal); EmitPreBarrier(masm, element, MIRType::Value); masm.storeValue(tmpVal, element); - } else { - // Set element on an unboxed array. - - // Bounds check. - Address initLength(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLength, scratchReg); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg); - masm.branch32(Assembler::BelowOrEqual, scratchReg, key, &failure); - - // Load obj->elements. - masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg); - - // Compute the address being written to. - BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_))); - - EmitUnboxedPreBarrierForBaseline(masm, address, unboxedType_); - - Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value)); - masm.Push(R0); - masm.loadValue(valueAddr, R0); - masm.storeUnboxedProperty(address, unboxedType_, - ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0); - masm.Pop(R0); } EmitReturnFromIC(masm); @@ -3087,40 +2990,6 @@ ICSetElemDenseOrUnboxedArrayAddCompiler::generateStubCode(MacroAssembler& masm) BaseIndex element(scratchReg, key, TimesEight); masm.loadValue(valueAddr, tmpVal); masm.storeValue(tmpVal, element); - } else { - // Adding element to an unboxed array. - - // Bounds check (key == initLength) - Address initLengthAddr(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLengthAddr, scratchReg); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg); - masm.branch32(Assembler::NotEqual, scratchReg, key, &failure); - - // Capacity check. - masm.checkUnboxedArrayCapacity(obj, RegisterOrInt32Constant(key), scratchReg, &failure); - - // Load obj->elements. - masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg); - - // Write the value first, since this can fail. No need for pre-barrier - // since we're not overwriting an old value. - masm.Push(R0); - Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value)); - masm.loadValue(valueAddr, R0); - BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_))); - masm.storeUnboxedProperty(address, unboxedType_, - ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0); - masm.Pop(R0); - - // Increment initialized length. - masm.add32(Imm32(1), initLengthAddr); - - // If length is now <= key, increment length. - Address lengthAddr(obj, UnboxedArrayObject::offsetOfLength()); - Label skipIncrementLength; - masm.branch32(Assembler::Above, lengthAddr, key, &skipIncrementLength); - masm.add32(Imm32(1), lengthAddr); - masm.bind(&skipIncrementLength); } EmitReturnFromIC(masm); @@ -8301,19 +8170,6 @@ ICGetElem_Dense::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorSt return New(cx, space, other.jitCode(), firstMonitorStub, other.shape_); } -ICGetElem_UnboxedArray::ICGetElem_UnboxedArray(JitCode* stubCode, ICStub* firstMonitorStub, - ObjectGroup *group) - : ICMonitoredStub(GetElem_UnboxedArray, stubCode, firstMonitorStub), - group_(group) -{ } - -/* static */ ICGetElem_UnboxedArray* -ICGetElem_UnboxedArray::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub, - ICGetElem_UnboxedArray& other) -{ - return New(cx, space, other.jitCode(), firstMonitorStub, other.group_); -} - ICGetElem_TypedArray::ICGetElem_TypedArray(JitCode* stubCode, Shape* shape, Scalar::Type type) : ICStub(GetElem_TypedArray, stubCode), shape_(shape) diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index f1061af70..6822a70af 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -175,7 +175,7 @@ TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOper } else { writer.guardNoUnboxedExpando(objId); } - } else if (obj->is() || obj->is()) { + } else if (obj->is()) { writer.guardGroup(objId, obj->group()); } else { Shape* shape = obj->maybeShape(); @@ -368,13 +368,6 @@ GetPropIRGenerator::tryAttachObjectLength(CacheIRWriter& writer, HandleObject ob return true; } - if (obj->is()) { - writer.guardClass(objId, GuardClassKind::UnboxedArray); - writer.loadUnboxedArrayLengthResult(objId); - emitted_ = true; - return true; - } - if (obj->is() && !obj->as().hasOverriddenLength()) { if (obj->is()) { writer.guardClass(objId, GuardClassKind::MappedArguments); diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index 51e55f48b..4fd8575f0 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -96,7 +96,6 @@ class ObjOperandId : public OperandId _(LoadUnboxedPropertyResult) \ _(LoadTypedObjectResult) \ _(LoadInt32ArrayLengthResult) \ - _(LoadUnboxedArrayLengthResult) \ _(LoadArgumentsObjectLengthResult) \ _(LoadUndefinedResult) @@ -128,7 +127,6 @@ struct StubField { enum class GuardClassKind { Array, - UnboxedArray, MappedArguments, UnmappedArguments, }; @@ -327,9 +325,6 @@ class MOZ_RAII CacheIRWriter void loadInt32ArrayLengthResult(ObjOperandId obj) { writeOpWithOperandId(CacheOp::LoadInt32ArrayLengthResult, obj); } - void loadUnboxedArrayLengthResult(ObjOperandId obj) { - writeOpWithOperandId(CacheOp::LoadUnboxedArrayLengthResult, obj); - } void loadArgumentsObjectLengthResult(ObjOperandId obj) { writeOpWithOperandId(CacheOp::LoadArgumentsObjectLengthResult, obj); } diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 6d1fb6b9b..bd275a2c1 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3183,9 +3183,7 @@ CodeGenerator::visitSetPropertyPolymorphicT(LSetPropertyPolymorphicT* ins) void CodeGenerator::visitElements(LElements* lir) { - Address elements(ToRegister(lir->object()), - lir->mir()->unboxed() ? UnboxedArrayObject::offsetOfElements() - : NativeObject::offsetOfElements()); + Address elements(ToRegister(lir->object()), NativeObject::offsetOfElements()); masm.loadPtr(elements, ToRegister(lir->output())); } @@ -5341,21 +5339,11 @@ CodeGenerator::visitNewArrayDynamicLength(LNewArrayDynamicLength* lir) bool canInline = true; size_t inlineLength = 0; - if (templateObject->is()) { - if (templateObject->as().hasFixedElements()) { - size_t numSlots = gc::GetGCKindSlots(templateObject->asTenured().getAllocKind()); - inlineLength = numSlots - ObjectElements::VALUES_PER_HEADER; - } else { - canInline = false; - } + if (templateObject->as().hasFixedElements()) { + size_t numSlots = gc::GetGCKindSlots(templateObject->asTenured().getAllocKind()); + inlineLength = numSlots - ObjectElements::VALUES_PER_HEADER; } else { - if (templateObject->as().hasInlineElements()) { - size_t nbytes = - templateObject->tenuredSizeOfThis() - UnboxedArrayObject::offsetOfInlineElements(); - inlineLength = nbytes / templateObject->as().elementSize(); - } else { - canInline = false; - } + canInline = false; } if (canInline) { @@ -7811,49 +7799,6 @@ CodeGenerator::visitSetInitializedLength(LSetInitializedLength* lir) masm.dec32(&index); } -void -CodeGenerator::visitUnboxedArrayLength(LUnboxedArrayLength* lir) -{ - Register obj = ToRegister(lir->object()); - Register result = ToRegister(lir->output()); - masm.load32(Address(obj, UnboxedArrayObject::offsetOfLength()), result); -} - -void -CodeGenerator::visitUnboxedArrayInitializedLength(LUnboxedArrayInitializedLength* lir) -{ - Register obj = ToRegister(lir->object()); - Register result = ToRegister(lir->output()); - masm.load32(Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()), result); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), result); -} - -void -CodeGenerator::visitIncrementUnboxedArrayInitializedLength(LIncrementUnboxedArrayInitializedLength* lir) -{ - Register obj = ToRegister(lir->object()); - masm.add32(Imm32(1), Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength())); -} - -void -CodeGenerator::visitSetUnboxedArrayInitializedLength(LSetUnboxedArrayInitializedLength* lir) -{ - Register obj = ToRegister(lir->object()); - RegisterOrInt32Constant key = ToRegisterOrInt32Constant(lir->length()); - Register temp = ToRegister(lir->temp()); - - Address initLengthAddr(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLengthAddr, temp); - masm.and32(Imm32(UnboxedArrayObject::CapacityMask), temp); - - if (key.isRegister()) - masm.or32(key.reg(), temp); - else - masm.or32(Imm32(key.constant()), temp); - - masm.store32(temp, initLengthAddr); -} - void CodeGenerator::visitNotO(LNotO* lir) { @@ -8150,46 +8095,19 @@ CodeGenerator::emitStoreElementHoleT(T* lir) OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir); addOutOfLineCode(ool, lir->mir()); - Register obj = ToRegister(lir->object()); Register elements = ToRegister(lir->elements()); const LAllocation* index = lir->index(); RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index); - JSValueType unboxedType = lir->mir()->unboxedType(); - if (unboxedType == JSVAL_TYPE_MAGIC) { - Address initLength(elements, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry()); - - if (lir->mir()->needsBarrier()) - emitPreBarrier(elements, index, 0); + Address initLength(elements, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry()); - masm.bind(ool->rejoinStore()); - emitStoreElementTyped(lir->value(), lir->mir()->value()->type(), lir->mir()->elementType(), - elements, index, 0); - } else { - Register temp = ToRegister(lir->getTemp(0)); - Address initLength(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLength, temp); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), temp); - masm.branch32(Assembler::BelowOrEqual, temp, key, ool->entry()); - - ConstantOrRegister v = ToConstantOrRegister(lir->value(), lir->mir()->value()->type()); - - if (index->isConstant()) { - Address address(elements, ToInt32(index) * UnboxedTypeSize(unboxedType)); - EmitUnboxedPreBarrier(masm, address, unboxedType); - - masm.bind(ool->rejoinStore()); - masm.storeUnboxedProperty(address, unboxedType, v, nullptr); - } else { - BaseIndex address(elements, ToRegister(index), - ScaleFromElemWidth(UnboxedTypeSize(unboxedType))); - EmitUnboxedPreBarrier(masm, address, unboxedType); + if (lir->mir()->needsBarrier()) + emitPreBarrier(elements, index, 0); - masm.bind(ool->rejoinStore()); - masm.storeUnboxedProperty(address, unboxedType, v, nullptr); - } - } + masm.bind(ool->rejoinStore()); + emitStoreElementTyped(lir->value(), lir->mir()->value()->type(), lir->mir()->elementType(), + elements, index, 0); masm.bind(ool->rejoin()); } @@ -8209,47 +8127,22 @@ CodeGenerator::emitStoreElementHoleV(T* lir) OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir); addOutOfLineCode(ool, lir->mir()); - Register obj = ToRegister(lir->object()); Register elements = ToRegister(lir->elements()); const LAllocation* index = lir->index(); const ValueOperand value = ToValue(lir, T::Value); RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index); - JSValueType unboxedType = lir->mir()->unboxedType(); - if (unboxedType == JSVAL_TYPE_MAGIC) { - Address initLength(elements, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry()); - - if (lir->mir()->needsBarrier()) - emitPreBarrier(elements, index, 0); + Address initLength(elements, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::BelowOrEqual, initLength, key, ool->entry()); - masm.bind(ool->rejoinStore()); - if (index->isConstant()) - masm.storeValue(value, Address(elements, ToInt32(index) * sizeof(js::Value))); - else - masm.storeValue(value, BaseIndex(elements, ToRegister(index), TimesEight)); - } else { - Register temp = ToRegister(lir->getTemp(0)); - Address initLength(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLength, temp); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), temp); - masm.branch32(Assembler::BelowOrEqual, temp, key, ool->entry()); - - if (index->isConstant()) { - Address address(elements, ToInt32(index) * UnboxedTypeSize(unboxedType)); - EmitUnboxedPreBarrier(masm, address, unboxedType); - - masm.bind(ool->rejoinStore()); - masm.storeUnboxedProperty(address, unboxedType, ConstantOrRegister(value), nullptr); - } else { - BaseIndex address(elements, ToRegister(index), - ScaleFromElemWidth(UnboxedTypeSize(unboxedType))); - EmitUnboxedPreBarrier(masm, address, unboxedType); + if (lir->mir()->needsBarrier()) + emitPreBarrier(elements, index, 0); - masm.bind(ool->rejoinStore()); - masm.storeUnboxedProperty(address, unboxedType, ConstantOrRegister(value), nullptr); - } - } + masm.bind(ool->rejoinStore()); + if (index->isConstant()) + masm.storeValue(value, Address(elements, ToInt32(index) * sizeof(js::Value))); + else + masm.storeValue(value, BaseIndex(elements, ToRegister(index), TimesEight)); masm.bind(ool->rejoin()); } @@ -8334,8 +8227,6 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) const LAllocation* index; MIRType valueType; ConstantOrRegister value; - JSValueType unboxedType; - LDefinition *temp = nullptr; if (ins->isStoreElementHoleV()) { LStoreElementHoleV* store = ins->toStoreElementHoleV(); @@ -8344,8 +8235,6 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) index = store->index(); valueType = store->mir()->value()->type(); value = TypedOrValueRegister(ToValue(store, LStoreElementHoleV::Value)); - unboxedType = store->mir()->unboxedType(); - temp = store->getTemp(0); } else if (ins->isFallibleStoreElementV()) { LFallibleStoreElementV* store = ins->toFallibleStoreElementV(); object = ToRegister(store->object()); @@ -8353,8 +8242,6 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) index = store->index(); valueType = store->mir()->value()->type(); value = TypedOrValueRegister(ToValue(store, LFallibleStoreElementV::Value)); - unboxedType = store->mir()->unboxedType(); - temp = store->getTemp(0); } else if (ins->isStoreElementHoleT()) { LStoreElementHoleT* store = ins->toStoreElementHoleT(); object = ToRegister(store->object()); @@ -8365,8 +8252,6 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) value = ConstantOrRegister(store->value()->toConstant()->toJSValue()); else value = TypedOrValueRegister(valueType, ToAnyRegister(store->value())); - unboxedType = store->mir()->unboxedType(); - temp = store->getTemp(0); } else { // ins->isFallibleStoreElementT() LFallibleStoreElementT* store = ins->toFallibleStoreElementT(); object = ToRegister(store->object()); @@ -8377,8 +8262,6 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) value = ConstantOrRegister(store->value()->toConstant()->toJSValue()); else value = TypedOrValueRegister(valueType, ToAnyRegister(store->value())); - unboxedType = store->mir()->unboxedType(); - temp = store->getTemp(0); } RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index); @@ -8389,54 +8272,32 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) Label callStub; #if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) // Had to reimplement for MIPS because there are no flags. - if (unboxedType == JSVAL_TYPE_MAGIC) { - Address initLength(elements, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::NotEqual, initLength, key, &callStub); - } else { - Address initLength(object, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - masm.load32(initLength, ToRegister(temp)); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), ToRegister(temp)); - masm.branch32(Assembler::NotEqual, ToRegister(temp), key, &callStub); - } + Address initLength(elements, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::NotEqual, initLength, key, &callStub); #else masm.j(Assembler::NotEqual, &callStub); #endif - if (unboxedType == JSVAL_TYPE_MAGIC) { - // Check array capacity. - masm.branch32(Assembler::BelowOrEqual, Address(elements, ObjectElements::offsetOfCapacity()), - key, &callStub); - - // Update initialized length. The capacity guard above ensures this won't overflow, - // due to MAX_DENSE_ELEMENTS_COUNT. - masm.inc32(&key); - masm.store32(key, Address(elements, ObjectElements::offsetOfInitializedLength())); - - // Update length if length < initializedLength. - Label dontUpdate; - masm.branch32(Assembler::AboveOrEqual, Address(elements, ObjectElements::offsetOfLength()), - key, &dontUpdate); - masm.store32(key, Address(elements, ObjectElements::offsetOfLength())); - masm.bind(&dontUpdate); + // Check array capacity. + masm.branch32(Assembler::BelowOrEqual, Address(elements, ObjectElements::offsetOfCapacity()), + key, &callStub); - masm.dec32(&key); - } else { - // Check array capacity. - masm.checkUnboxedArrayCapacity(object, key, ToRegister(temp), &callStub); + // Update initialized length. The capacity guard above ensures this won't overflow, + // due to MAX_DENSE_ELEMENTS_COUNT. + masm.inc32(&key); + masm.store32(key, Address(elements, ObjectElements::offsetOfInitializedLength())); - // Update initialized length. - masm.add32(Imm32(1), Address(object, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength())); + // Update length if length < initializedLength. + Label dontUpdate; + masm.branch32(Assembler::AboveOrEqual, Address(elements, ObjectElements::offsetOfLength()), + key, &dontUpdate); + masm.store32(key, Address(elements, ObjectElements::offsetOfLength())); + masm.bind(&dontUpdate); - // Update length if length < initializedLength. - Address lengthAddr(object, UnboxedArrayObject::offsetOfLength()); - Label dontUpdate; - masm.branch32(Assembler::Above, lengthAddr, key, &dontUpdate); - masm.add32(Imm32(1), lengthAddr); - masm.bind(&dontUpdate); - } + masm.dec32(&key); if ((ins->isStoreElementHoleT() || ins->isFallibleStoreElementT()) && - unboxedType == JSVAL_TYPE_MAGIC && valueType != MIRType::Double) + valueType != MIRType::Double) { // The inline path for StoreElementHoleT and FallibleStoreElementT does not always store // the type tag, so we do the store on the OOL path. We use MIRType::None for the element @@ -8526,9 +8387,6 @@ typedef bool (*ConvertUnboxedObjectToNativeFn)(JSContext*, JSObject*); static const VMFunction ConvertUnboxedPlainObjectToNativeInfo = FunctionInfo(UnboxedPlainObject::convertToNative, "UnboxedPlainObject::convertToNative"); -static const VMFunction ConvertUnboxedArrayObjectToNativeInfo = - FunctionInfo(UnboxedArrayObject::convertToNative, - "UnboxedArrayObject::convertToNative"); typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue); static const VMFunction ArrayPopDenseInfo = @@ -8554,20 +8412,11 @@ CodeGenerator::emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, R // Load elements and length, and VM call if length != initializedLength. RegisterOrInt32Constant key = RegisterOrInt32Constant(lengthTemp); - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp); - masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), lengthTemp); + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp); + masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), lengthTemp); - Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::NotEqual, initLength, key, ool->entry()); - } else { - masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), elementsTemp); - masm.load32(Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()), lengthTemp); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), lengthTemp); - - Address lengthAddr(obj, UnboxedArrayObject::offsetOfLength()); - masm.branch32(Assembler::NotEqual, lengthAddr, key, ool->entry()); - } + Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::NotEqual, initLength, key, ool->entry()); // Test for length != 0. On zero length either take a VM call or generate // an undefined value, depending on whether the call is known to produce @@ -8579,13 +8428,10 @@ CodeGenerator::emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, R // According to the spec we need to set the length 0 (which is already 0). // This is observable when the array length is made non-writable. - // Handle this case in the OOL. When freezing an unboxed array it is converted - // to an normal array. - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - Address elementFlags(elementsTemp, ObjectElements::offsetOfFlags()); - Imm32 bit(ObjectElements::NONWRITABLE_ARRAY_LENGTH); - masm.branchTest32(Assembler::NonZero, elementFlags, bit, ool->entry()); - } + // Handle this case in the OOL. + Address elementFlags(elementsTemp, ObjectElements::offsetOfFlags()); + Imm32 bit(ObjectElements::NONWRITABLE_ARRAY_LENGTH); + masm.branchTest32(Assembler::NonZero, elementFlags, bit, ool->entry()); masm.moveValue(UndefinedValue(), out.valueReg()); masm.jump(&done); @@ -8597,41 +8443,25 @@ CodeGenerator::emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, R masm.dec32(&key); if (mir->mode() == MArrayPopShift::Pop) { - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - BaseIndex addr(elementsTemp, lengthTemp, TimesEight); - masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry()); - } else { - size_t elemSize = UnboxedTypeSize(mir->unboxedType()); - BaseIndex addr(elementsTemp, lengthTemp, ScaleFromElemWidth(elemSize)); - masm.loadUnboxedProperty(addr, mir->unboxedType(), out); - } + BaseIndex addr(elementsTemp, lengthTemp, TimesEight); + masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry()); } else { MOZ_ASSERT(mir->mode() == MArrayPopShift::Shift); Address addr(elementsTemp, 0); - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) - masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry()); - else - masm.loadUnboxedProperty(addr, mir->unboxedType(), out); + masm.loadElementTypedOrValue(addr, out, mir->needsHoleCheck(), ool->entry()); } - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - // Handle the failure case when the array length is non-writable in the - // OOL path. (Unlike in the adding-an-element cases, we can't rely on the - // capacity <= length invariant for such arrays to avoid an explicit - // check.) - Address elementFlags(elementsTemp, ObjectElements::offsetOfFlags()); - Imm32 bit(ObjectElements::NONWRITABLE_ARRAY_LENGTH); - masm.branchTest32(Assembler::NonZero, elementFlags, bit, ool->entry()); + // Handle the failure case when the array length is non-writable in the + // OOL path. (Unlike in the adding-an-element cases, we can't rely on the + // capacity <= length invariant for such arrays to avoid an explicit + // check.) + Address elementFlags(elementsTemp, ObjectElements::offsetOfFlags()); + Imm32 bit(ObjectElements::NONWRITABLE_ARRAY_LENGTH); + masm.branchTest32(Assembler::NonZero, elementFlags, bit, ool->entry()); - // Now adjust length and initializedLength. - masm.store32(lengthTemp, Address(elementsTemp, ObjectElements::offsetOfLength())); - masm.store32(lengthTemp, Address(elementsTemp, ObjectElements::offsetOfInitializedLength())); - } else { - // Unboxed arrays always have writable lengths. Adjust length and - // initializedLength. - masm.store32(lengthTemp, Address(obj, UnboxedArrayObject::offsetOfLength())); - masm.add32(Imm32(-1), Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength())); - } + // Now adjust length and initializedLength. + masm.store32(lengthTemp, Address(elementsTemp, ObjectElements::offsetOfLength())); + masm.store32(lengthTemp, Address(elementsTemp, ObjectElements::offsetOfInitializedLength())); if (mir->mode() == MArrayPopShift::Shift) { // Don't save the temp registers. @@ -8681,50 +8511,27 @@ CodeGenerator::emitArrayPush(LInstruction* lir, const MArrayPush* mir, Register OutOfLineCode* ool = oolCallVM(ArrayPushDenseInfo, lir, ArgList(obj, value), StoreRegisterTo(length)); RegisterOrInt32Constant key = RegisterOrInt32Constant(length); - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - // Load elements and length. - masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp); - masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length); - - // Guard length == initializedLength. - Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength()); - masm.branch32(Assembler::NotEqual, initLength, key, ool->entry()); - // Guard length < capacity. - Address capacity(elementsTemp, ObjectElements::offsetOfCapacity()); - masm.branch32(Assembler::BelowOrEqual, capacity, key, ool->entry()); + // Load elements and length. + masm.loadPtr(Address(obj, NativeObject::offsetOfElements()), elementsTemp); + masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), length); - // Do the store. - masm.storeConstantOrRegister(value, BaseIndex(elementsTemp, length, TimesEight)); - } else { - // Load initialized length. - masm.load32(Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()), length); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), length); - - // Guard length == initializedLength. - Address lengthAddr(obj, UnboxedArrayObject::offsetOfLength()); - masm.branch32(Assembler::NotEqual, lengthAddr, key, ool->entry()); + // Guard length == initializedLength. + Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength()); + masm.branch32(Assembler::NotEqual, initLength, key, ool->entry()); - // Guard length < capacity. - masm.checkUnboxedArrayCapacity(obj, key, elementsTemp, ool->entry()); + // Guard length < capacity. + Address capacity(elementsTemp, ObjectElements::offsetOfCapacity()); + masm.branch32(Assembler::BelowOrEqual, capacity, key, ool->entry()); - // Load elements and do the store. - masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), elementsTemp); - size_t elemSize = UnboxedTypeSize(mir->unboxedType()); - BaseIndex addr(elementsTemp, length, ScaleFromElemWidth(elemSize)); - masm.storeUnboxedProperty(addr, mir->unboxedType(), value, nullptr); - } + // Do the store. + masm.storeConstantOrRegister(value, BaseIndex(elementsTemp, length, TimesEight)); masm.inc32(&key); // Update length and initialized length. - if (mir->unboxedType() == JSVAL_TYPE_MAGIC) { - masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfLength())); - masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfInitializedLength())); - } else { - masm.store32(length, Address(obj, UnboxedArrayObject::offsetOfLength())); - masm.add32(Imm32(1), Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength())); - } + masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfLength())); + masm.store32(length, Address(elementsTemp, ObjectElements::offsetOfInitializedLength())); masm.bind(ool->rejoin()); } @@ -10922,7 +10729,7 @@ CodeGenerator::visitInArray(LInArray* lir) } masm.branch32(Assembler::BelowOrEqual, initLength, Imm32(index), failedInitLength); - if (mir->needsHoleCheck() && mir->unboxedType() == JSVAL_TYPE_MAGIC) { + if (mir->needsHoleCheck()) { NativeObject::elementsSizeMustNotOverflow(); Address address = Address(elements, index * sizeof(Value)); masm.branchTestMagic(Assembler::Equal, address, &falseBranch); @@ -10935,7 +10742,7 @@ CodeGenerator::visitInArray(LInArray* lir) failedInitLength = &negativeIntCheck; masm.branch32(Assembler::BelowOrEqual, initLength, index, failedInitLength); - if (mir->needsHoleCheck() && mir->unboxedType() == JSVAL_TYPE_MAGIC) { + if (mir->needsHoleCheck()) { BaseIndex address = BaseIndex(elements, ToRegister(lir->index()), TimesEight); masm.branchTestMagic(Assembler::Equal, address, &falseBranch); } diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 292f163b5..b5f170d84 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -234,10 +234,6 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitSubstr(LSubstr* lir); void visitInitializedLength(LInitializedLength* lir); void visitSetInitializedLength(LSetInitializedLength* lir); - void visitUnboxedArrayLength(LUnboxedArrayLength* lir); - void visitUnboxedArrayInitializedLength(LUnboxedArrayInitializedLength* lir); - void visitIncrementUnboxedArrayInitializedLength(LIncrementUnboxedArrayInitializedLength* lir); - void visitSetUnboxedArrayInitializedLength(LSetUnboxedArrayInitializedLength* lir); void visitNotO(LNotO* ins); void visitNotV(LNotV* ins); void visitBoundsCheck(LBoundsCheck* lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index af85011be..3d964d1c6 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -7336,12 +7336,6 @@ IonBuilder::newArrayTryTemplateObject(bool* emitted, JSObject* templateObject, u if (!templateObject) return true; - if (templateObject->is()) { - MOZ_ASSERT(templateObject->as().capacity() >= length); - if (!templateObject->as().hasInlineElements()) - return true; - } - MOZ_ASSERT(length <= NativeObject::MAX_DENSE_ELEMENTS_COUNT); size_t arraySlots = @@ -7597,7 +7591,6 @@ IonBuilder::jsop_initelem_array() // intializer, and that arrays are marked as non-packed when writing holes // to them during initialization. bool needStub = false; - JSValueType unboxedType = JSVAL_TYPE_MAGIC; if (shouldAbortOnPreliminaryGroups(obj)) { needStub = true; } else if (!obj->resultTypeSet() || @@ -7608,12 +7601,6 @@ IonBuilder::jsop_initelem_array() } else { MOZ_ASSERT(obj->resultTypeSet()->getObjectCount() == 1); TypeSet::ObjectKey* initializer = obj->resultTypeSet()->getObject(0); - if (initializer->clasp() == &UnboxedArrayObject::class_) { - if (initializer->group()->unboxedLayout().nativeGroup()) - needStub = true; - else - unboxedType = initializer->group()->unboxedLayout().elementType(); - } if (value->type() == MIRType::MagicHole) { if (!initializer->hasFlags(constraints(), OBJECT_FLAG_NON_PACKED)) needStub = true; @@ -7633,60 +7620,46 @@ IonBuilder::jsop_initelem_array() return resumeAfter(store); } - return initializeArrayElement(obj, index, value, unboxedType, /* addResumePoint = */ true); + return initializeArrayElement(obj, index, value, /* addResumePoint = */ true); } bool IonBuilder::initializeArrayElement(MDefinition* obj, size_t index, MDefinition* value, - JSValueType unboxedType, bool addResumePointAndIncrementInitializedLength) { MConstant* id = MConstant::New(alloc(), Int32Value(index)); current->add(id); // Get the elements vector. - MElements* elements = MElements::New(alloc(), obj, unboxedType != JSVAL_TYPE_MAGIC); + MElements* elements = MElements::New(alloc(), obj); current->add(elements); - if (unboxedType != JSVAL_TYPE_MAGIC) { - // Note: storeUnboxedValue takes care of any post barriers on the value. - storeUnboxedValue(obj, elements, 0, id, unboxedType, value, /* preBarrier = */ false); - - if (addResumePointAndIncrementInitializedLength) { - MInstruction* increment = MIncrementUnboxedArrayInitializedLength::New(alloc(), obj); - current->add(increment); - - if (!resumeAfter(increment)) - return false; - } - } else { - if (NeedsPostBarrier(value)) - current->add(MPostWriteBarrier::New(alloc(), obj, value)); + if (NeedsPostBarrier(value)) + current->add(MPostWriteBarrier::New(alloc(), obj, value)); - if ((obj->isNewArray() && obj->toNewArray()->convertDoubleElements()) || - (obj->isNullarySharedStub() && - obj->resultTypeSet()->convertDoubleElements(constraints()) == TemporaryTypeSet::AlwaysConvertToDoubles)) - { - MInstruction* valueDouble = MToDouble::New(alloc(), value); - current->add(valueDouble); - value = valueDouble; - } + if ((obj->isNewArray() && obj->toNewArray()->convertDoubleElements()) || + (obj->isNullarySharedStub() && + obj->resultTypeSet()->convertDoubleElements(constraints()) == TemporaryTypeSet::AlwaysConvertToDoubles)) + { + MInstruction* valueDouble = MToDouble::New(alloc(), value); + current->add(valueDouble); + value = valueDouble; + } - // Store the value. - MStoreElement* store = MStoreElement::New(alloc(), elements, id, value, + // Store the value. + MStoreElement* store = MStoreElement::New(alloc(), elements, id, value, /* needsHoleCheck = */ false); - current->add(store); + current->add(store); - if (addResumePointAndIncrementInitializedLength) { - // Update the initialized length. (The template object for this - // array has the array's ultimate length, so the length field is - // already correct: no updating needed.) - MSetInitializedLength* initLength = MSetInitializedLength::New(alloc(), elements, id); - current->add(initLength); + if (addResumePointAndIncrementInitializedLength) { + // Update the initialized length. (The template object for this + // array has the array's ultimate length, so the length field is + // already correct: no updating needed.) + MSetInitializedLength* initLength = MSetInitializedLength::New(alloc(), elements, id); + current->add(initLength); - if (!resumeAfter(initLength)) - return false; - } + if (!resumeAfter(initLength)) + return false; } return true; @@ -8175,8 +8148,7 @@ IonBuilder::maybeMarkEmpty(MDefinition* ins) static bool ClassHasEffectlessLookup(const Class* clasp) { - return (clasp == &UnboxedArrayObject::class_) || - IsTypedObjectClass(clasp) || + return IsTypedObjectClass(clasp) || (clasp->isNative() && !clasp->getOpsLookupProperty()); } @@ -9452,12 +9424,9 @@ IonBuilder::getElemTryDense(bool* emitted, MDefinition* obj, MDefinition* index) { MOZ_ASSERT(*emitted == false); - JSValueType unboxedType = UnboxedArrayElementType(constraints(), obj, index); - if (unboxedType == JSVAL_TYPE_MAGIC) { - if (!ElementAccessIsDenseNative(constraints(), obj, index)) { - trackOptimizationOutcome(TrackedOutcome::AccessNotDense); - return true; - } + if (!ElementAccessIsDenseNative(constraints(), obj, index)) { + trackOptimizationOutcome(TrackedOutcome::AccessNotDense); + return true; } // Don't generate a fast path if there have been bounds check failures @@ -9474,7 +9443,7 @@ IonBuilder::getElemTryDense(bool* emitted, MDefinition* obj, MDefinition* index) return true; } - if (!jsop_getelem_dense(obj, index, unboxedType)) + if (!jsop_getelem_dense(obj, index)) return false; trackOptimizationSuccess(); @@ -9826,7 +9795,7 @@ IonBuilder::computeHeapType(const TemporaryTypeSet* objTypes, const jsid id) } bool -IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType unboxedType) +IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index) { TemporaryTypeSet* types = bytecodeTypes(pc); @@ -9850,7 +9819,7 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType !ElementAccessHasExtraIndexedProperty(this, obj); MIRType knownType = MIRType::Value; - if (unboxedType == JSVAL_TYPE_MAGIC && barrier == BarrierKind::NoBarrier) + if (barrier == BarrierKind::NoBarrier) knownType = GetElemKnownType(needsHoleCheck, types); // Ensure index is an integer. @@ -9859,13 +9828,13 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType index = idInt32; // Get the elements vector. - MInstruction* elements = MElements::New(alloc(), obj, unboxedType != JSVAL_TYPE_MAGIC); + MInstruction* elements = MElements::New(alloc(), obj); current->add(elements); // Note: to help GVN, use the original MElements instruction and not // MConvertElementsToDoubles as operand. This is fine because converting // elements to double does not change the initialized length. - MInstruction* initLength = initializedLength(obj, elements, unboxedType); + MInstruction* initLength = initializedLength(obj, elements); // If we can load the element as a definite double, make sure to check that // the array has been converted to homogenous doubles first. @@ -9881,7 +9850,6 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType } bool loadDouble = - unboxedType == JSVAL_TYPE_MAGIC && barrier == BarrierKind::NoBarrier && loopDepth_ && inBounds && @@ -9900,18 +9868,13 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType // hoisting. index = addBoundsCheck(index, initLength); - if (unboxedType != JSVAL_TYPE_MAGIC) { - load = loadUnboxedValue(elements, 0, index, unboxedType, barrier, types); - } else { - load = MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble); - current->add(load); - } + load = MLoadElement::New(alloc(), elements, index, needsHoleCheck, loadDouble); + current->add(load); } else { // This load may return undefined, so assume that we *can* read holes, // or that we can read out-of-bounds accesses. In this case, the bounds // check is part of the opcode. - load = MLoadElementHole::New(alloc(), elements, index, initLength, - unboxedType, needsHoleCheck); + load = MLoadElementHole::New(alloc(), elements, index, initLength, needsHoleCheck); current->add(load); // If maybeUndefined was true, the typeset must have undefined, and @@ -9921,8 +9884,7 @@ IonBuilder::jsop_getelem_dense(MDefinition* obj, MDefinition* index, JSValueType } if (knownType != MIRType::Value) { - if (unboxedType == JSVAL_TYPE_MAGIC) - load->setResultType(knownType); + load->setResultType(knownType); load->setResultTypeSet(types); } @@ -10369,12 +10331,9 @@ IonBuilder::setElemTryDense(bool* emitted, MDefinition* object, { MOZ_ASSERT(*emitted == false); - JSValueType unboxedType = UnboxedArrayElementType(constraints(), object, index); - if (unboxedType == JSVAL_TYPE_MAGIC) { - if (!ElementAccessIsDenseNative(constraints(), object, index)) { - trackOptimizationOutcome(TrackedOutcome::AccessNotDense); - return true; - } + if (!ElementAccessIsDenseNative(constraints(), object, index)) { + trackOptimizationOutcome(TrackedOutcome::AccessNotDense); + return true; } if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, @@ -10408,7 +10367,7 @@ IonBuilder::setElemTryDense(bool* emitted, MDefinition* object, } // Emit dense setelem variant. - if (!jsop_setelem_dense(conversion, object, index, value, unboxedType, writeHole, emitted)) + if (!jsop_setelem_dense(conversion, object, index, value, writeHole, emitted)) return false; if (!*emitted) { @@ -10498,13 +10457,11 @@ IonBuilder::setElemTryCache(bool* emitted, MDefinition* object, bool IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion, MDefinition* obj, MDefinition* id, MDefinition* value, - JSValueType unboxedType, bool writeHole, bool* emitted) + bool writeHole, bool* emitted) { MOZ_ASSERT(*emitted == false); - MIRType elementType = MIRType::None; - if (unboxedType == JSVAL_TYPE_MAGIC) - elementType = DenseNativeElementType(constraints(), obj); + MIRType elementType = DenseNativeElementType(constraints(), obj); bool packed = ElementAccessIsPacked(constraints(), obj); // Writes which are on holes in the object do not have to bail out if they @@ -10534,7 +10491,7 @@ IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion, obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); // Get the elements vector. - MElements* elements = MElements::New(alloc(), obj, unboxedType != JSVAL_TYPE_MAGIC); + MElements* elements = MElements::New(alloc(), obj); current->add(elements); // Ensure the value is a double, if double conversion might be needed. @@ -10571,7 +10528,7 @@ IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion, MInstruction* store; MStoreElementCommon* common = nullptr; if (writeHole && hasNoExtraIndexedProperty && !mayBeFrozen) { - MStoreElementHole* ins = MStoreElementHole::New(alloc(), obj, elements, id, newValue, unboxedType); + MStoreElementHole* ins = MStoreElementHole::New(alloc(), obj, elements, id, newValue); store = ins; common = ins; @@ -10583,27 +10540,23 @@ IonBuilder::jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion, bool strict = IsStrictSetPC(pc); MFallibleStoreElement* ins = MFallibleStoreElement::New(alloc(), obj, elements, id, - newValue, unboxedType, strict); + newValue, strict); store = ins; common = ins; current->add(ins); current->push(value); } else { - MInstruction* initLength = initializedLength(obj, elements, unboxedType); + MInstruction* initLength = initializedLength(obj, elements); id = addBoundsCheck(id, initLength); bool needsHoleCheck = !packed && !hasNoExtraIndexedProperty; - if (unboxedType != JSVAL_TYPE_MAGIC) { - store = storeUnboxedValue(obj, elements, 0, id, unboxedType, newValue); - } else { - MStoreElement* ins = MStoreElement::New(alloc(), elements, id, newValue, needsHoleCheck); - store = ins; - common = ins; + MStoreElement* ins = MStoreElement::New(alloc(), elements, id, newValue, needsHoleCheck); + store = ins; + common = ins; - current->add(store); - } + current->add(store); current->push(value); } @@ -10721,18 +10674,6 @@ IonBuilder::jsop_length_fastPath() return true; } - // Compute the length for unboxed array objects. - if (UnboxedArrayElementType(constraints(), obj, nullptr) != JSVAL_TYPE_MAGIC && - !objTypes->hasObjectFlags(constraints(), OBJECT_FLAG_LENGTH_OVERFLOW)) - { - current->pop(); - - MUnboxedArrayLength* length = MUnboxedArrayLength::New(alloc(), obj); - current->add(length); - current->push(length); - return true; - } - // Compute the length for array typed objects. TypedObjectPrediction prediction = typedObjectPrediction(obj); if (!prediction.isUseless()) { @@ -13687,11 +13628,8 @@ IonBuilder::inTryDense(bool* emitted, MDefinition* obj, MDefinition* id) if (shouldAbortOnPreliminaryGroups(obj)) return true; - JSValueType unboxedType = UnboxedArrayElementType(constraints(), obj, id); - if (unboxedType == JSVAL_TYPE_MAGIC) { - if (!ElementAccessIsDenseNative(constraints(), obj, id)) - return true; - } + if (!ElementAccessIsDenseNative(constraints(), obj, id)) + return true; if (ElementAccessHasExtraIndexedProperty(this, obj)) return true; @@ -13706,10 +13644,10 @@ IonBuilder::inTryDense(bool* emitted, MDefinition* obj, MDefinition* id) id = idInt32; // Get the elements vector. - MElements* elements = MElements::New(alloc(), obj, unboxedType != JSVAL_TYPE_MAGIC); + MElements* elements = MElements::New(alloc(), obj); current->add(elements); - MInstruction* initLength = initializedLength(obj, elements, unboxedType); + MInstruction* initLength = initializedLength(obj, elements); // If there are no holes, speculate the InArray check will not fail. if (!needsHoleCheck && !failedBoundsCheck_) { @@ -13719,8 +13657,7 @@ IonBuilder::inTryDense(bool* emitted, MDefinition* obj, MDefinition* id) } // Check if id < initLength and elem[id] not a hole. - MInArray* ins = MInArray::New(alloc(), elements, id, initLength, obj, needsHoleCheck, - unboxedType); + MInArray* ins = MInArray::New(alloc(), elements, id, initLength, obj, needsHoleCheck); current->add(ins); current->push(ins); @@ -14398,32 +14335,24 @@ IonBuilder::constantInt(int32_t i) } MInstruction* -IonBuilder::initializedLength(MDefinition* obj, MDefinition* elements, JSValueType unboxedType) +IonBuilder::initializedLength(MDefinition* obj, MDefinition* elements) { - MInstruction* res; - if (unboxedType != JSVAL_TYPE_MAGIC) - res = MUnboxedArrayInitializedLength::New(alloc(), obj); - else - res = MInitializedLength::New(alloc(), elements); + MInstruction* res = MInitializedLength::New(alloc(), elements); current->add(res); return res; } MInstruction* -IonBuilder::setInitializedLength(MDefinition* obj, JSValueType unboxedType, size_t count) +IonBuilder::setInitializedLength(MDefinition* obj, size_t count) { MOZ_ASSERT(count); - MInstruction* res; - if (unboxedType != JSVAL_TYPE_MAGIC) { - res = MSetUnboxedArrayInitializedLength::New(alloc(), obj, constant(Int32Value(count))); - } else { - // MSetInitializedLength takes the index of the last element, rather - // than the count itself. - MInstruction* elements = MElements::New(alloc(), obj, /* unboxed = */ false); - current->add(elements); - res = MSetInitializedLength::New(alloc(), elements, constant(Int32Value(count - 1))); - } + // MSetInitializedLength takes the index of the last element, rather + // than the count itself. + MInstruction* elements = MElements::New(alloc(), obj, /* unboxed = */ false); + current->add(elements); + MInstruction* res = + MSetInitializedLength::New(alloc(), elements, constant(Int32Value(count - 1))); current->add(res); return res; } diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 77528ad37..1b97c4743 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -346,9 +346,8 @@ class IonBuilder MConstant* constant(const Value& v); MConstant* constantInt(int32_t i); - MInstruction* initializedLength(MDefinition* obj, MDefinition* elements, - JSValueType unboxedType); - MInstruction* setInitializedLength(MDefinition* obj, JSValueType unboxedType, size_t count); + MInstruction* initializedLength(MDefinition* obj, MDefinition* elements); + MInstruction* setInitializedLength(MDefinition* obj, size_t count); // Improve the type information at tests MOZ_MUST_USE bool improveTypesAtTest(MDefinition* ins, bool trueBranch, MTest* test); @@ -611,7 +610,6 @@ class IonBuilder TypedObjectPrediction elemTypeReprs, uint32_t elemSize); MOZ_MUST_USE bool initializeArrayElement(MDefinition* obj, size_t index, MDefinition* value, - JSValueType unboxedType, bool addResumePointAndIncrementInitializedLength); // jsop_getelem() helpers. @@ -723,15 +721,13 @@ class IonBuilder MOZ_MUST_USE bool jsop_bindname(PropertyName* name); MOZ_MUST_USE bool jsop_bindvar(); MOZ_MUST_USE bool jsop_getelem(); - MOZ_MUST_USE bool jsop_getelem_dense(MDefinition* obj, MDefinition* index, - JSValueType unboxedType); + MOZ_MUST_USE bool jsop_getelem_dense(MDefinition* obj, MDefinition* index); MOZ_MUST_USE bool jsop_getelem_typed(MDefinition* obj, MDefinition* index, ScalarTypeDescr::Type arrayType); MOZ_MUST_USE bool jsop_setelem(); MOZ_MUST_USE bool jsop_setelem_dense(TemporaryTypeSet::DoubleConversion conversion, MDefinition* object, MDefinition* index, - MDefinition* value, JSValueType unboxedType, - bool writeHole, bool* emitted); + MDefinition* value, bool writeHole, bool* emitted); MOZ_MUST_USE bool jsop_setelem_typed(ScalarTypeDescr::Type arrayType, MDefinition* object, MDefinition* index, MDefinition* value); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 96e488ea8..0a53f178f 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -638,9 +638,6 @@ TestMatchingReceiver(MacroAssembler& masm, IonCache::StubAttacher& attacher, } else { masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure); } - } else if (obj->is()) { - MOZ_ASSERT(failure); - masm.branchTestObjGroup(Assembler::NotEqual, object, obj->group(), failure); } else if (obj->is()) { attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), @@ -1187,39 +1184,6 @@ GenerateArrayLength(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& return true; } -static void -GenerateUnboxedArrayLength(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher, - JSObject* array, Register object, TypedOrValueRegister output, - Label* failures) -{ - Register outReg; - if (output.hasValue()) { - outReg = output.valueReg().scratchReg(); - } else { - MOZ_ASSERT(output.type() == MIRType::Int32); - outReg = output.typedReg().gpr(); - } - MOZ_ASSERT(object != outReg); - - TestMatchingReceiver(masm, attacher, object, array, failures); - - // Load length. - masm.load32(Address(object, UnboxedArrayObject::offsetOfLength()), outReg); - - // Check for a length that fits in an int32. - masm.branchTest32(Assembler::Signed, outReg, outReg, failures); - - if (output.hasValue()) - masm.tagValue(JSVAL_TYPE_INT32, outReg, output.valueReg()); - - // Success. - attacher.jumpRejoin(masm); - - // Failure. - masm.bind(failures); - attacher.jumpNextStub(masm); -} - // In this case, the code for TypedArray and SharedTypedArray is not the same, // because the code embeds pointers to the respective class arrays. Code that // caches the stub code must distinguish between the two cases. @@ -1593,40 +1557,6 @@ GetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, JS::TrackedOutcome::ICGetPropStub_UnboxedReadExpando); } -bool -GetPropertyIC::tryAttachUnboxedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, void* returnAddr, - bool* emitted) -{ - MOZ_ASSERT(canAttachStub()); - MOZ_ASSERT(!*emitted); - MOZ_ASSERT(outerScript->ionScript() == ion); - - if (!obj->is()) - return true; - - if (!JSID_IS_ATOM(id, cx->names().length)) - return true; - - if (obj->as().length() > INT32_MAX) - return true; - - if (!allowArrayLength(cx)) - return true; - - *emitted = true; - - MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); - - Label failures; - emitIdGuard(masm, id, &failures); - - StubAttacher attacher(*this); - GenerateUnboxedArrayLength(cx, masm, attacher, obj, object(), output(), &failures); - return linkAndAttachStub(cx, masm, attacher, ion, "unboxed array length", - JS::TrackedOutcome::ICGetPropStub_UnboxedArrayLength); -} - bool GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion, HandleObject obj, HandleId id, bool* emitted) @@ -2202,9 +2132,6 @@ GetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, returnAddr, emitted)) return false; - if (!*emitted && !tryAttachUnboxedArrayLength(cx, outerScript, ion, obj, id, returnAddr, emitted)) - return false; - if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, id, emitted)) return false; } @@ -4025,7 +3952,7 @@ GetPropertyIC::tryAttachDenseElementHole(JSContext* cx, HandleScript outerScript GetPropertyIC::canAttachTypedOrUnboxedArrayElement(JSObject* obj, const Value& idval, TypedOrValueRegister output) { - if (!obj->is() && !obj->is()) + if (!obj->is()) return false; MOZ_ASSERT(idval.isInt32() || idval.isString()); @@ -4056,13 +3983,6 @@ GetPropertyIC::canAttachTypedOrUnboxedArrayElement(JSObject* obj, const Value& i return output.hasValue() || !output.typedReg().isFloat(); } - if (index >= obj->as().initializedLength()) - return false; - - JSValueType elementType = obj->as().elementType(); - if (elementType == JSVAL_TYPE_DOUBLE) - return output.hasValue(); - return output.hasValue() || !output.typedReg().isFloat(); } @@ -4139,46 +4059,27 @@ GenerateGetTypedOrUnboxedArrayElement(JSContext* cx, MacroAssembler& masm, Label popObjectAndFail; - if (array->is()) { - // Guard on the initialized length. - Address length(object, TypedArrayObject::lengthOffset()); - masm.branch32(Assembler::BelowOrEqual, length, indexReg, &failures); + // Guard on the initialized length. + Address length(object, TypedArrayObject::lengthOffset()); + masm.branch32(Assembler::BelowOrEqual, length, indexReg, &failures); - // Save the object register on the stack in case of failure. - Register elementReg = object; - masm.push(object); + // Save the object register on the stack in case of failure. + Register elementReg = object; + masm.push(object); - // Load elements vector. - masm.loadPtr(Address(object, TypedArrayObject::dataOffset()), elementReg); + // Load elements vector. + masm.loadPtr(Address(object, TypedArrayObject::dataOffset()), elementReg); - // Load the value. We use an invalid register because the destination - // register is necessary a non double register. - Scalar::Type arrayType = array->as().type(); - int width = Scalar::byteSize(arrayType); - BaseIndex source(elementReg, indexReg, ScaleFromElemWidth(width)); - if (output.hasValue()) { - masm.loadFromTypedArray(arrayType, source, output.valueReg(), allowDoubleResult, - elementReg, &popObjectAndFail); - } else { - masm.loadFromTypedArray(arrayType, source, output.typedReg(), elementReg, &popObjectAndFail); - } + // Load the value. We use an invalid register because the destination + // register is necessary a non double register. + Scalar::Type arrayType = array->as().type(); + int width = Scalar::byteSize(arrayType); + BaseIndex source(elementReg, indexReg, ScaleFromElemWidth(width)); + if (output.hasValue()) { + masm.loadFromTypedArray(arrayType, source, output.valueReg(), allowDoubleResult, + elementReg, &popObjectAndFail); } else { - // Save the object register on the stack in case of failure. - masm.push(object); - - // Guard on the initialized length. - masm.load32(Address(object, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()), object); - masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), object); - masm.branch32(Assembler::BelowOrEqual, object, indexReg, &popObjectAndFail); - - // Load elements vector. - Register elementReg = object; - masm.loadPtr(Address(masm.getStackPointer(), 0), object); - masm.loadPtr(Address(object, UnboxedArrayObject::offsetOfElements()), elementReg); - - JSValueType elementType = array->as().elementType(); - BaseIndex source(elementReg, indexReg, ScaleFromElemWidth(UnboxedTypeSize(elementType))); - masm.loadUnboxedProperty(source, elementType, output); + masm.loadFromTypedArray(arrayType, source, output.typedReg(), elementReg, &popObjectAndFail); } masm.pop(object); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index aafa57c09..e185b5746 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2888,32 +2888,6 @@ LIRGenerator::visitSetInitializedLength(MSetInitializedLength* ins) useRegisterOrConstant(ins->index())), ins); } -void -LIRGenerator::visitUnboxedArrayLength(MUnboxedArrayLength* ins) -{ - define(new(alloc()) LUnboxedArrayLength(useRegisterAtStart(ins->object())), ins); -} - -void -LIRGenerator::visitUnboxedArrayInitializedLength(MUnboxedArrayInitializedLength* ins) -{ - define(new(alloc()) LUnboxedArrayInitializedLength(useRegisterAtStart(ins->object())), ins); -} - -void -LIRGenerator::visitIncrementUnboxedArrayInitializedLength(MIncrementUnboxedArrayInitializedLength* ins) -{ - add(new(alloc()) LIncrementUnboxedArrayInitializedLength(useRegister(ins->object())), ins); -} - -void -LIRGenerator::visitSetUnboxedArrayInitializedLength(MSetUnboxedArrayInitializedLength* ins) -{ - add(new(alloc()) LSetUnboxedArrayInitializedLength(useRegister(ins->object()), - useRegisterOrConstant(ins->length()), - temp()), ins); -} - void LIRGenerator::visitNot(MNot* ins) { @@ -3165,8 +3139,6 @@ LIRGenerator::visitStoreElementHole(MStoreElementHole* ins) // Use a temp register when adding new elements to unboxed arrays. LDefinition tempDef = LDefinition::BogusTemp(); - if (ins->unboxedType() != JSVAL_TYPE_MAGIC) - tempDef = temp(); LInstruction* lir; switch (ins->value()->type()) { @@ -3199,8 +3171,6 @@ LIRGenerator::visitFallibleStoreElement(MFallibleStoreElement* ins) // Use a temp register when adding new elements to unboxed arrays. LDefinition tempDef = LDefinition::BogusTemp(); - if (ins->unboxedType() != JSVAL_TYPE_MAGIC) - tempDef = temp(); LInstruction* lir; switch (ins->value()->type()) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index e36620bce..b096bb143 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -216,10 +216,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitTypedObjectDescr(MTypedObjectDescr* ins); void visitInitializedLength(MInitializedLength* ins); void visitSetInitializedLength(MSetInitializedLength* ins); - void visitUnboxedArrayLength(MUnboxedArrayLength* ins); - void visitUnboxedArrayInitializedLength(MUnboxedArrayInitializedLength* ins); - void visitIncrementUnboxedArrayInitializedLength(MIncrementUnboxedArrayInitializedLength* ins); - void visitSetUnboxedArrayInitializedLength(MSetUnboxedArrayInitializedLength* ins); void visitNot(MNot* ins); void visitBoundsCheck(MBoundsCheck* ins); void visitBoundsCheckLower(MBoundsCheckLower* ins); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 41ccd0ca7..7283497ea 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -475,11 +475,6 @@ IonBuilder::inlineArray(CallInfo& callInfo) return InliningStatus_NotInlined; } - if (templateObject->is()) { - if (templateObject->group()->unboxedLayout().nativeGroup()) - return InliningStatus_NotInlined; - } - // Multiple arguments imply array initialization, not just construction. if (callInfo.argc() >= 2) { initLength = callInfo.argc(); @@ -542,16 +537,15 @@ IonBuilder::inlineArray(CallInfo& callInfo) MDefinition* array = current->peek(-1); if (callInfo.argc() >= 2) { - JSValueType unboxedType = GetBoxedOrUnboxedType(templateObject); for (uint32_t i = 0; i < initLength; i++) { if (!alloc().ensureBallast()) return InliningStatus_Error; MDefinition* value = callInfo.getArg(i); - if (!initializeArrayElement(array, i, value, unboxedType, /* addResumePoint = */ false)) + if (!initializeArrayElement(array, i, /* addResumePoint = */ false)) return InliningStatus_Error; } - MInstruction* setLength = setInitializedLength(array, unboxedType, initLength); + MInstruction* setLength = setInitializedLength(array, initLength); if (!resumeAfter(setLength)) return InliningStatus_Error; } @@ -620,7 +614,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) if (!thisTypes) return InliningStatus_NotInlined; const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) + if (clasp != &ArrayObject::class_) return InliningStatus_NotInlined; if (thisTypes->hasObjectFlags(constraints(), unhandledFlags)) { trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags); @@ -632,17 +626,9 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) return InliningStatus_NotInlined; } - JSValueType unboxedType = JSVAL_TYPE_MAGIC; - if (clasp == &UnboxedArrayObject::class_) { - unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); - if (unboxedType == JSVAL_TYPE_MAGIC) - return InliningStatus_NotInlined; - } - callInfo.setImplicitlyUsedUnchecked(); - if (clasp == &ArrayObject::class_) - obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); + obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); TemporaryTypeSet* returnTypes = getInlineReturnTypeSet(); bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_NON_PACKED); @@ -653,8 +639,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) if (barrier != BarrierKind::NoBarrier) returnType = MIRType::Value; - MArrayPopShift* ins = MArrayPopShift::New(alloc(), obj, mode, - unboxedType, needsHoleCheck, maybeUndefined); + MArrayPopShift* ins = MArrayPopShift::New(alloc(), obj, mode, needsHoleCheck, maybeUndefined); current->add(ins); current->push(ins); ins->setResultType(returnType); @@ -761,7 +746,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) if (!thisTypes) return InliningStatus_NotInlined; const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) + if (clasp != &ArrayObject::class_) return InliningStatus_NotInlined; if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES | OBJECT_FLAG_LENGTH_OVERFLOW)) @@ -782,13 +767,6 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) return InliningStatus_NotInlined; } - JSValueType unboxedType = JSVAL_TYPE_MAGIC; - if (clasp == &UnboxedArrayObject::class_) { - unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); - if (unboxedType == JSVAL_TYPE_MAGIC) - return InliningStatus_NotInlined; - } - callInfo.setImplicitlyUsedUnchecked(); if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles || @@ -799,13 +777,12 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) value = valueDouble; } - if (unboxedType == JSVAL_TYPE_MAGIC) - obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); + obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); if (NeedsPostBarrier(value)) current->add(MPostWriteBarrier::New(alloc(), obj, value)); - MArrayPush* ins = MArrayPush::New(alloc(), obj, value, unboxedType); + MArrayPush* ins = MArrayPush::New(alloc(), obj, value); current->add(ins); current->push(ins); @@ -846,7 +823,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) return InliningStatus_NotInlined; const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) + if (clasp != &ArrayObject::class_) return InliningStatus_NotInlined; if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES | OBJECT_FLAG_LENGTH_OVERFLOW)) @@ -855,13 +832,6 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) return InliningStatus_NotInlined; } - JSValueType unboxedType = JSVAL_TYPE_MAGIC; - if (clasp == &UnboxedArrayObject::class_) { - unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); - if (unboxedType == JSVAL_TYPE_MAGIC) - return InliningStatus_NotInlined; - } - // Watch out for indexed properties on the prototype. if (ArrayPrototypeHasIndexedProperty(this, script())) { trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); @@ -882,15 +852,8 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) if (!templateObj) return InliningStatus_NotInlined; - if (unboxedType == JSVAL_TYPE_MAGIC) { - if (!templateObj->is()) - return InliningStatus_NotInlined; - } else { - if (!templateObj->is()) - return InliningStatus_NotInlined; - if (templateObj->as().elementType() != unboxedType) - return InliningStatus_NotInlined; - } + if (!templateObj->is()) + return InliningStatus_NotInlined; callInfo.setImplicitlyUsedUnchecked(); @@ -909,16 +872,12 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) end = MArrayLength::New(alloc(), elements); current->add(end->toInstruction()); - } else { - end = MUnboxedArrayLength::New(alloc(), obj); - current->add(end->toInstruction()); } MArraySlice* ins = MArraySlice::New(alloc(), constraints(), obj, begin, end, templateObj, - templateObj->group()->initialHeap(constraints()), - unboxedType); + templateObj->group()->initialHeap(constraints())); current->add(ins); current->push(ins); @@ -1500,8 +1459,6 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) return InliningStatus_Inlined; } - JSValueType unboxedType = GetBoxedOrUnboxedType(templateObject); - // Store all values, no need to initialize the length after each as // jsop_initelem_array is doing because we do not expect to bailout // because the memory is supposed to be allocated by now. @@ -1512,11 +1469,11 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) MConstant* value = arrayValues[i]; current->add(value); - if (!initializeArrayElement(array, i, value, unboxedType, /* addResumePoint = */ false)) + if (!initializeArrayElement(array, i, value, /* addResumePoint = */ false)) return InliningStatus_Error; } - MInstruction* setLength = setInitializedLength(array, unboxedType, initLength); + MInstruction* setLength = setInitializedLength(array, initLength); if (!resumeAfter(setLength)) return InliningStatus_Error; diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 1f33b2174..6aa46be4b 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -5823,46 +5823,6 @@ jit::ElementAccessIsDenseNative(CompilerConstraintList* constraints, return clasp && clasp->isNative() && !IsTypedArrayClass(clasp); } -JSValueType -jit::UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* obj, - MDefinition* id) -{ - if (obj->mightBeType(MIRType::String)) - return JSVAL_TYPE_MAGIC; - - if (id && id->type() != MIRType::Int32 && id->type() != MIRType::Double) - return JSVAL_TYPE_MAGIC; - - TemporaryTypeSet* types = obj->resultTypeSet(); - if (!types || types->unknownObject()) - return JSVAL_TYPE_MAGIC; - - JSValueType elementType = JSVAL_TYPE_MAGIC; - for (unsigned i = 0; i < types->getObjectCount(); i++) { - TypeSet::ObjectKey* key = types->getObject(i); - if (!key) - continue; - - if (key->unknownProperties() || !key->isGroup()) - return JSVAL_TYPE_MAGIC; - - if (key->clasp() != &UnboxedArrayObject::class_) - return JSVAL_TYPE_MAGIC; - - const UnboxedLayout &layout = key->group()->unboxedLayout(); - - if (layout.nativeGroup()) - return JSVAL_TYPE_MAGIC; - - if (elementType == layout.elementType() || elementType == JSVAL_TYPE_MAGIC) - elementType = layout.elementType(); - else - return JSVAL_TYPE_MAGIC; - } - - return elementType; -} - bool jit::ElementAccessIsTypedArray(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id, @@ -6022,11 +5982,6 @@ ObjectSubsumes(TypeSet::ObjectKey* first, TypeSet::ObjectKey* second) firstElements.maybeTypes()->equals(secondElements.maybeTypes()); } - if (first->clasp() == &UnboxedArrayObject::class_) { - return first->group()->unboxedLayout().elementType() == - second->group()->unboxedLayout().elementType(); - } - return false; } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 3e0421789..cdd737b56 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -375,8 +375,7 @@ class AliasSet { Element = 1 << 1, // A Value member of obj->elements or // a typed object. UnboxedElement = 1 << 2, // An unboxed scalar or reference member of - // a typed array, typed object, or unboxed - // object. + // typed object or unboxed object. DynamicSlot = 1 << 3, // A Value member of obj->slots. FixedSlot = 1 << 4, // A Value member of obj->fixedSlots(). DOMProperty = 1 << 5, // A DOM property @@ -433,9 +432,6 @@ class AliasSet { MOZ_ASSERT(flags && !(flags & Store_)); return AliasSet(flags | Store_); } - static uint32_t BoxedOrUnboxedElements(JSValueType type) { - return (type == JSVAL_TYPE_MAGIC) ? Element : UnboxedElement; - } }; typedef Vector MDefinitionVector; @@ -8745,102 +8741,6 @@ class MSetInitializedLength ALLOW_CLONE(MSetInitializedLength) }; -// Load the length from an unboxed array. -class MUnboxedArrayLength - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - explicit MUnboxedArrayLength(MDefinition* object) - : MUnaryInstruction(object) - { - setResultType(MIRType::Int32); - setMovable(); - } - - public: - INSTRUCTION_HEADER(UnboxedArrayLength) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - bool congruentTo(const MDefinition* ins) const override { - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } - - ALLOW_CLONE(MUnboxedArrayLength) -}; - -// Load the initialized length from an unboxed array. -class MUnboxedArrayInitializedLength - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - explicit MUnboxedArrayInitializedLength(MDefinition* object) - : MUnaryInstruction(object) - { - setResultType(MIRType::Int32); - setMovable(); - } - - public: - INSTRUCTION_HEADER(UnboxedArrayInitializedLength) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - bool congruentTo(const MDefinition* ins) const override { - return congruentIfOperandsEqual(ins); - } - AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::ObjectFields); - } - - ALLOW_CLONE(MUnboxedArrayInitializedLength) -}; - -// Increment the initialized length of an unboxed array object. -class MIncrementUnboxedArrayInitializedLength - : public MUnaryInstruction, - public SingleObjectPolicy::Data -{ - explicit MIncrementUnboxedArrayInitializedLength(MDefinition* obj) - : MUnaryInstruction(obj) - {} - - public: - INSTRUCTION_HEADER(IncrementUnboxedArrayInitializedLength) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object)) - - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields); - } - - ALLOW_CLONE(MIncrementUnboxedArrayInitializedLength) -}; - -// Set the initialized length of an unboxed array object. -class MSetUnboxedArrayInitializedLength - : public MBinaryInstruction, - public SingleObjectPolicy::Data -{ - explicit MSetUnboxedArrayInitializedLength(MDefinition* obj, MDefinition* length) - : MBinaryInstruction(obj, length) - {} - - public: - INSTRUCTION_HEADER(SetUnboxedArrayInitializedLength) - TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, object), (1, length)) - - AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields); - } - - ALLOW_CLONE(MSetUnboxedArrayInitializedLength) -}; - // Load the array length from an elements header. class MArrayLength : public MUnaryInstruction, @@ -9341,16 +9241,12 @@ class MLoadElementHole : public MTernaryInstruction, public SingleObjectPolicy::Data { - // Unboxed element type, JSVAL_TYPE_MAGIC for dense native elements. - JSValueType unboxedType_; - bool needsNegativeIntCheck_; bool needsHoleCheck_; MLoadElementHole(MDefinition* elements, MDefinition* index, MDefinition* initLength, JSValueType unboxedType, bool needsHoleCheck) : MTernaryInstruction(elements, index, initLength), - unboxedType_(unboxedType), needsNegativeIntCheck_(true), needsHoleCheck_(needsHoleCheck) { @@ -9372,9 +9268,6 @@ class MLoadElementHole TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, elements), (1, index), (2, initLength)) - JSValueType unboxedType() const { - return unboxedType_; - } bool needsNegativeIntCheck() const { return needsNegativeIntCheck_; } @@ -9385,8 +9278,6 @@ class MLoadElementHole if (!ins->isLoadElementHole()) return false; const MLoadElementHole* other = ins->toLoadElementHole(); - if (unboxedType() != other->unboxedType()) - return false; if (needsHoleCheck() != other->needsHoleCheck()) return false; if (needsNegativeIntCheck() != other->needsNegativeIntCheck()) @@ -9394,7 +9285,7 @@ class MLoadElementHole return congruentIfOperandsEqual(other); } AliasSet getAliasSet() const override { - return AliasSet::Load(AliasSet::BoxedOrUnboxedElements(unboxedType())); + return AliasSet::Load(AliasSet::Element); } void collectRangeInfoPreTrunc() override; @@ -9583,11 +9474,8 @@ class MStoreElementHole public MStoreElementCommon, public MixPolicy >::Data { - JSValueType unboxedType_; - MStoreElementHole(MDefinition* object, MDefinition* elements, - MDefinition* index, MDefinition* value, JSValueType unboxedType) - : unboxedType_(unboxedType) + MDefinition* index, MDefinition* value) { initOperand(0, object); initOperand(1, elements); @@ -9602,14 +9490,10 @@ class MStoreElementHole TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, elements), (2, index), (3, value)) - JSValueType unboxedType() const { - return unboxedType_; - } AliasSet getAliasSet() const override { // StoreElementHole can update the initialized length, the array length // or reallocate obj->elements. - return AliasSet::Store(AliasSet::ObjectFields | - AliasSet::BoxedOrUnboxedElements(unboxedType())); + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); } ALLOW_CLONE(MStoreElementHole) @@ -9622,13 +9506,11 @@ class MFallibleStoreElement public MStoreElementCommon, public MixPolicy >::Data { - JSValueType unboxedType_; bool strict_; MFallibleStoreElement(MDefinition* object, MDefinition* elements, MDefinition* index, MDefinition* value, - JSValueType unboxedType, bool strict) - : unboxedType_(unboxedType) + bool strict) { initOperand(0, object); initOperand(1, elements); @@ -9644,12 +9526,8 @@ class MFallibleStoreElement TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, elements), (2, index), (3, value)) - JSValueType unboxedType() const { - return unboxedType_; - } AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | - AliasSet::BoxedOrUnboxedElements(unboxedType())); + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); } bool strict() const { return strict_; @@ -9754,13 +9632,12 @@ class MArrayPopShift private: Mode mode_; - JSValueType unboxedType_; bool needsHoleCheck_; bool maybeUndefined_; - MArrayPopShift(MDefinition* object, Mode mode, JSValueType unboxedType, + MArrayPopShift(MDefinition* object, Mode mode, bool needsHoleCheck, bool maybeUndefined) - : MUnaryInstruction(object), mode_(mode), unboxedType_(unboxedType), + : MUnaryInstruction(object), mode_(mode), needsHoleCheck_(needsHoleCheck), maybeUndefined_(maybeUndefined) { } @@ -9778,12 +9655,8 @@ class MArrayPopShift bool mode() const { return mode_; } - JSValueType unboxedType() const { - return unboxedType_; - } AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | - AliasSet::BoxedOrUnboxedElements(unboxedType())); + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); } ALLOW_CLONE(MArrayPopShift) @@ -9794,10 +9667,8 @@ class MArrayPush : public MBinaryInstruction, public MixPolicy >::Data { - JSValueType unboxedType_; - - MArrayPush(MDefinition* object, MDefinition* value, JSValueType unboxedType) - : MBinaryInstruction(object, value), unboxedType_(unboxedType) + MArrayPush(MDefinition* object, MDefinition* value) + : MBinaryInstruction(object, value) { setResultType(MIRType::Int32); } @@ -9807,12 +9678,8 @@ class MArrayPush TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, object), (1, value)) - JSValueType unboxedType() const { - return unboxedType_; - } AliasSet getAliasSet() const override { - return AliasSet::Store(AliasSet::ObjectFields | - AliasSet::BoxedOrUnboxedElements(unboxedType())); + return AliasSet::Store(AliasSet::ObjectFields | AliasSet::Element); } void computeRange(TempAllocator& alloc) override; @@ -9826,15 +9693,13 @@ class MArraySlice { CompilerObject templateObj_; gc::InitialHeap initialHeap_; - JSValueType unboxedType_; MArraySlice(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* begin, MDefinition* end, - JSObject* templateObj, gc::InitialHeap initialHeap, JSValueType unboxedType) + JSObject* templateObj, gc::InitialHeap initialHeap) : MTernaryInstruction(obj, begin, end), templateObj_(templateObj), - initialHeap_(initialHeap), - unboxedType_(unboxedType) + initialHeap_(initialHeap) { setResultType(MIRType::Object); } @@ -12224,15 +12089,13 @@ class MInArray { bool needsHoleCheck_; bool needsNegativeIntCheck_; - JSValueType unboxedType_; MInArray(MDefinition* elements, MDefinition* index, MDefinition* initLength, MDefinition* object, - bool needsHoleCheck, JSValueType unboxedType) + bool needsHoleCheck) : MQuaternaryInstruction(elements, index, initLength, object), needsHoleCheck_(needsHoleCheck), - needsNegativeIntCheck_(true), - unboxedType_(unboxedType) + needsNegativeIntCheck_(true) { setResultType(MIRType::Boolean); setMovable(); @@ -12252,9 +12115,6 @@ class MInArray bool needsNegativeIntCheck() const { return needsNegativeIntCheck_; } - JSValueType unboxedType() const { - return unboxedType_; - } void collectRangeInfoPreTrunc() override; AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::Element); @@ -12267,8 +12127,6 @@ class MInArray return false; if (needsNegativeIntCheck() != other->needsNegativeIntCheck()) return false; - if (unboxedType() != other->unboxedType()) - return false; return congruentIfOperandsEqual(other); } }; @@ -14169,8 +14027,6 @@ MDefinition::maybeConstantValue() bool ElementAccessIsDenseNative(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id); -JSValueType UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* obj, - MDefinition* id); bool ElementAccessIsTypedArray(CompilerConstraintList* constraints, MDefinition* obj, MDefinition* id, Scalar::Type* arrayType); diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index b80d1baf9..ab37604b4 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -198,10 +198,6 @@ namespace jit { _(SetTypedObjectOffset) \ _(InitializedLength) \ _(SetInitializedLength) \ - _(UnboxedArrayLength) \ - _(UnboxedArrayInitializedLength) \ - _(IncrementUnboxedArrayInitializedLength) \ - _(SetUnboxedArrayInitializedLength) \ _(Not) \ _(BoundsCheck) \ _(BoundsCheckLower) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index f633b9b7b..e50f68722 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -705,31 +705,6 @@ template void MacroAssembler::storeUnboxedProperty(BaseIndex address, JSValueType type, const ConstantOrRegister& value, Label* failure); -void -MacroAssembler::checkUnboxedArrayCapacity(Register obj, const RegisterOrInt32Constant& index, - Register temp, Label* failure) -{ - Address initLengthAddr(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()); - Address lengthAddr(obj, UnboxedArrayObject::offsetOfLength()); - - Label capacityIsIndex, done; - load32(initLengthAddr, temp); - branchTest32(Assembler::NonZero, temp, Imm32(UnboxedArrayObject::CapacityMask), &capacityIsIndex); - branch32(Assembler::BelowOrEqual, lengthAddr, index, failure); - jump(&done); - bind(&capacityIsIndex); - - // Do a partial shift so that we can get an absolute offset from the base - // of CapacityArray to use. - JS_STATIC_ASSERT(sizeof(UnboxedArrayObject::CapacityArray[0]) == 4); - rshiftPtr(Imm32(UnboxedArrayObject::CapacityShift - 2), temp); - and32(Imm32(~0x3), temp); - - addPtr(ImmPtr(&UnboxedArrayObject::CapacityArray), temp); - branch32(Assembler::BelowOrEqual, Address(temp, 0), index, failure); - bind(&done); -} - // Inlined version of gc::CheckAllocatorState that checks the bare essentials // and bails for anything that cannot be handled with our jit allocators. void @@ -1281,16 +1256,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj, storePtr(ImmWord(0), Address(obj, UnboxedPlainObject::offsetOfExpando())); if (initContents) initUnboxedObjectContents(obj, &templateObj->as()); - } else if (templateObj->is()) { - MOZ_ASSERT(templateObj->as().hasInlineElements()); - int elementsOffset = UnboxedArrayObject::offsetOfInlineElements(); - computeEffectiveAddress(Address(obj, elementsOffset), temp); - storePtr(temp, Address(obj, UnboxedArrayObject::offsetOfElements())); - store32(Imm32(templateObj->as().length()), - Address(obj, UnboxedArrayObject::offsetOfLength())); - uint32_t capacityIndex = templateObj->as().capacityIndex(); - store32(Imm32(capacityIndex << UnboxedArrayObject::CapacityShift), - Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength())); } else { MOZ_CRASH("Unknown object"); } diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index b6616321c..6ee989463 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -1626,7 +1626,7 @@ class MacroAssembler : public MacroAssemblerSpecific void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address& dest, unsigned numElems = 0); - // Load a property from an UnboxedPlainObject or UnboxedArrayObject. + // Load a property from an UnboxedPlainObject. template void loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output); @@ -1637,9 +1637,6 @@ class MacroAssembler : public MacroAssemblerSpecific void storeUnboxedProperty(T address, JSValueType type, const ConstantOrRegister& value, Label* failure); - void checkUnboxedArrayCapacity(Register obj, const RegisterOrInt32Constant& index, - Register temp, Label* failure); - Register extractString(const Address& address, Register scratch) { return extractObject(address, scratch); } diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index 2065c0371..be9ceee2e 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -795,11 +795,6 @@ IsArrayEscaped(MInstruction* ins) return true; } - if (obj->is()) { - JitSpew(JitSpew_Escape, "Template object is an unboxed plain object."); - return true; - } - if (length >= 16) { JitSpew(JitSpew_Escape, "Array has too many elements"); return true; diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 2475dfb22..313957462 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -286,11 +286,6 @@ ICStub::trace(JSTracer* trc) TraceEdge(trc, &getElemStub->shape(), "baseline-getelem-dense-shape"); break; } - case ICStub::GetElem_UnboxedArray: { - ICGetElem_UnboxedArray* getElemStub = toGetElem_UnboxedArray(); - TraceEdge(trc, &getElemStub->group(), "baseline-getelem-unboxed-array-group"); - break; - } case ICStub::GetElem_TypedArray: { ICGetElem_TypedArray* getElemStub = toGetElem_TypedArray(); TraceEdge(trc, &getElemStub->shape(), "baseline-getelem-typedarray-shape"); @@ -2250,7 +2245,6 @@ IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy) if (obj == holder) return false; if (!obj->is() && - !obj->is() && !obj->is()) { return false; @@ -2582,9 +2576,6 @@ CheckHasNoSuchProperty(JSContext* cx, JSObject* obj, PropertyName* name, } else if (curObj->is()) { if (curObj->as().containsUnboxedOrExpandoProperty(cx, NameToId(name))) return false; - } else if (curObj->is()) { - if (name == cx->names().length) - return false; } else if (curObj->is()) { if (curObj->as().typeDescr().hasProperty(cx->names(), NameToId(name))) return false; diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 77b9e3647..0717bb86d 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -318,7 +318,7 @@ ArraySpliceDense(JSContext* cx, HandleObject obj, uint32_t start, uint32_t delet bool ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval) { - MOZ_ASSERT(obj->is() || obj->is()); + MOZ_ASSERT(obj->is()); AutoDetectInvalidation adi(cx, rval); @@ -341,8 +341,8 @@ ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length) { *length = GetAnyBoxedOrUnboxedArrayLength(obj); DenseElementResult result = - SetOrExtendAnyBoxedOrUnboxedDenseElements(cx, obj, *length, v.address(), 1, - ShouldUpdateTypes::DontUpdate); + SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, *length, v.address(), 1, + ShouldUpdateTypes::DontUpdate); if (result != DenseElementResult::Incomplete) { (*length)++; return result == DenseElementResult::Success; @@ -362,7 +362,7 @@ ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length) bool ArrayShiftDense(JSContext* cx, HandleObject obj, MutableHandleValue rval) { - MOZ_ASSERT(obj->is() || obj->is()); + MOZ_ASSERT(obj->is()); AutoDetectInvalidation adi(cx, rval); @@ -1151,8 +1151,8 @@ SetDenseOrUnboxedArrayElement(JSContext* cx, HandleObject obj, int32_t index, // no type changes are needed. DenseElementResult result = - SetOrExtendAnyBoxedOrUnboxedDenseElements(cx, obj, index, value.address(), 1, - ShouldUpdateTypes::DontUpdate); + SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, index, value.address(), 1, + ShouldUpdateTypes::DontUpdate); if (result != DenseElementResult::Incomplete) return result == DenseElementResult::Success; diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index f386d5256..35c7e7442 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -5165,72 +5165,6 @@ class LSetInitializedLength : public LInstructionHelper<0, 2, 0> } }; -class LUnboxedArrayLength : public LInstructionHelper<1, 1, 0> -{ - public: - LIR_HEADER(UnboxedArrayLength) - - explicit LUnboxedArrayLength(const LAllocation& object) { - setOperand(0, object); - } - - const LAllocation* object() { - return getOperand(0); - } -}; - -class LUnboxedArrayInitializedLength : public LInstructionHelper<1, 1, 0> -{ - public: - LIR_HEADER(UnboxedArrayInitializedLength) - - explicit LUnboxedArrayInitializedLength(const LAllocation& object) { - setOperand(0, object); - } - - const LAllocation* object() { - return getOperand(0); - } -}; - -class LIncrementUnboxedArrayInitializedLength : public LInstructionHelper<0, 1, 0> -{ - public: - LIR_HEADER(IncrementUnboxedArrayInitializedLength) - - explicit LIncrementUnboxedArrayInitializedLength(const LAllocation& object) { - setOperand(0, object); - } - - const LAllocation* object() { - return getOperand(0); - } -}; - -class LSetUnboxedArrayInitializedLength : public LInstructionHelper<0, 2, 1> -{ - public: - LIR_HEADER(SetUnboxedArrayInitializedLength) - - explicit LSetUnboxedArrayInitializedLength(const LAllocation& object, - const LAllocation& length, - const LDefinition& temp) { - setOperand(0, object); - setOperand(1, length); - setTemp(0, temp); - } - - const LAllocation* object() { - return getOperand(0); - } - const LAllocation* length() { - return getOperand(1); - } - const LDefinition* temp() { - return getTemp(0); - } -}; - // Load the length from an elements header. class LArrayLength : public LInstructionHelper<1, 1, 0> { diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index 6912e8904..deae92839 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -267,10 +267,6 @@ _(PostWriteElementBarrierV) \ _(InitializedLength) \ _(SetInitializedLength) \ - _(UnboxedArrayLength) \ - _(UnboxedArrayInitializedLength) \ - _(IncrementUnboxedArrayInitializedLength) \ - _(SetUnboxedArrayInitializedLength) \ _(BoundsCheck) \ _(BoundsCheckRange) \ _(BoundsCheckLower) \ -- cgit v1.2.3 From c8300fbd6ae08925736c32f8b02c980ce1531f3f Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 23 May 2019 10:51:09 +0000 Subject: Remove UnboxedArray code part 2 --- js/src/jit/BaselineIC.cpp | 8 ++++++- js/src/jit/BaselineIC.h | 56 ++------------------------------------------ js/src/jit/CodeGenerator.cpp | 19 ++++----------- js/src/jit/MCallOptimize.cpp | 4 ++-- js/src/jit/MIR.h | 6 +---- 5 files changed, 16 insertions(+), 77 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index f43fc5bf9..1d230e083 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -280,6 +280,12 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H RootedId id(cx); switch(stub->kind()) { + case ICStub::SetElem_DenseOrUnboxedArray: + case ICStub::SetElem_DenseOrUnboxedArrayAdd: { + id = JSID_VOID; + AddTypePropertyId(cx, obj, id, value); + break; + } case ICStub::SetProp_Native: case ICStub::SetProp_NativeAdd: case ICStub::SetProp_Unboxed: { @@ -5763,7 +5769,7 @@ CopyArray(JSContext* cx, HandleObject obj, MutableHandleValue result) if (!nobj) return false; EnsureArrayGroupAnalyzed(cx, nobj); - CopyAnyBoxedOrUnboxedDenseElements(cx, nobj, obj, 0, 0, length); + CopyBoxedOrUnboxedDenseElements(cx, nobj, obj, 0, 0, length); result.setObject(*nobj); return true; diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index a57556d99..afbea3b69 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -892,54 +892,6 @@ class ICGetElem_Dense : public ICMonitoredStub }; }; -class ICGetElem_UnboxedArray : public ICMonitoredStub -{ - friend class ICStubSpace; - - GCPtrObjectGroup group_; - - ICGetElem_UnboxedArray(JitCode* stubCode, ICStub* firstMonitorStub, ObjectGroup* group); - - public: - static ICGetElem_UnboxedArray* Clone(JSContext* cx, ICStubSpace* space, - ICStub* firstMonitorStub, ICGetElem_UnboxedArray& other); - - static size_t offsetOfGroup() { - return offsetof(ICGetElem_UnboxedArray, group_); - } - - GCPtrObjectGroup& group() { - return group_; - } - - class Compiler : public ICStubCompiler { - ICStub* firstMonitorStub_; - RootedObjectGroup group_; - JSValueType elementType_; - - protected: - MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm); - - virtual int32_t getKey() const { - return static_cast(engine_) | - (static_cast(kind) << 1) | - (static_cast(elementType_) << 17); - } - - public: - Compiler(JSContext* cx, ICStub* firstMonitorStub, ObjectGroup* group) - : ICStubCompiler(cx, ICStub::GetElem_UnboxedArray, Engine::Baseline), - firstMonitorStub_(firstMonitorStub), - group_(cx, group), - elementType_(group->unboxedLayoutDontCheckGeneration().elementType()) - {} - - ICStub* getStub(ICStubSpace* space) { - return newStub(space, getStubCode(), firstMonitorStub_, group_); - } - }; -}; - // Accesses scalar elements of a typed array or typed object. class ICGetElem_TypedArray : public ICStub { @@ -1115,9 +1067,7 @@ class ICSetElem_DenseOrUnboxedArray : public ICUpdatedStub : ICStubCompiler(cx, ICStub::SetElem_DenseOrUnboxedArray, Engine::Baseline), shape_(cx, shape), group_(cx, group), - unboxedType_(shape - ? JSVAL_TYPE_MAGIC - : group->unboxedLayoutDontCheckGeneration().elementType()) + unboxedType_(JSVAL_TYPE_MAGIC) {} ICUpdatedStub* getStub(ICStubSpace* space) { @@ -1225,9 +1175,7 @@ class ICSetElemDenseOrUnboxedArrayAddCompiler : public ICStubCompiler { : ICStubCompiler(cx, ICStub::SetElem_DenseOrUnboxedArrayAdd, Engine::Baseline), obj_(cx, obj), protoChainDepth_(protoChainDepth), - unboxedType_(obj->is() - ? obj->as().elementType() - : JSVAL_TYPE_MAGIC) + unboxedType_(JSVAL_TYPE_MAGIC) {} template diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index bd275a2c1..485e881fe 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -10336,22 +10336,11 @@ CodeGenerator::visitLoadElementHole(LLoadElementHole* lir) else masm.branch32(Assembler::BelowOrEqual, initLength, ToRegister(lir->index()), &undefined); - if (mir->unboxedType() != JSVAL_TYPE_MAGIC) { - size_t width = UnboxedTypeSize(mir->unboxedType()); - if (lir->index()->isConstant()) { - Address addr(elements, ToInt32(lir->index()) * width); - masm.loadUnboxedProperty(addr, mir->unboxedType(), out); - } else { - BaseIndex addr(elements, ToRegister(lir->index()), ScaleFromElemWidth(width)); - masm.loadUnboxedProperty(addr, mir->unboxedType(), out); - } + if (lir->index()->isConstant()) { + NativeObject::elementsSizeMustNotOverflow(); + masm.loadValue(Address(elements, ToInt32(lir->index()) * sizeof(Value)), out); } else { - if (lir->index()->isConstant()) { - NativeObject::elementsSizeMustNotOverflow(); - masm.loadValue(Address(elements, ToInt32(lir->index()) * sizeof(Value)), out); - } else { - masm.loadValue(BaseObjectElementIndex(elements, ToRegister(lir->index())), out); - } + masm.loadValue(BaseObjectElementIndex(elements, ToRegister(lir->index())), out); } // If a hole check is needed, and the value wasn't a hole, we're done. diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 7283497ea..748a70973 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -541,7 +541,7 @@ IonBuilder::inlineArray(CallInfo& callInfo) if (!alloc().ensureBallast()) return InliningStatus_Error; MDefinition* value = callInfo.getArg(i); - if (!initializeArrayElement(array, i, /* addResumePoint = */ false)) + if (!initializeArrayElement(array, i, value, /* addResumePoint = */ false)) return InliningStatus_Error; } @@ -578,7 +578,7 @@ IonBuilder::inlineArrayIsArray(CallInfo& callInfo) if (!clasp || clasp->isProxy()) return InliningStatus_NotInlined; - isArray = (clasp == &ArrayObject::class_ || clasp == &UnboxedArrayObject::class_); + isArray = (clasp == &ArrayObject::class_); } pushConstant(BooleanValue(isArray)); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index cdd737b56..f316827dc 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9245,7 +9245,7 @@ class MLoadElementHole bool needsHoleCheck_; MLoadElementHole(MDefinition* elements, MDefinition* index, MDefinition* initLength, - JSValueType unboxedType, bool needsHoleCheck) + bool needsHoleCheck) : MTernaryInstruction(elements, index, initLength), needsNegativeIntCheck_(true), needsHoleCheck_(needsHoleCheck) @@ -9717,10 +9717,6 @@ class MArraySlice return initialHeap_; } - JSValueType unboxedType() const { - return unboxedType_; - } - bool possiblyCalls() const override { return true; } -- cgit v1.2.3 From a24d62130932b8104f931f925288d3abc9105684 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Sat, 25 May 2019 15:41:06 +0200 Subject: [js, ARM] Always check error return from BufferOffset::diffB. We were missing error checks at two points. In one case an error return is meaningful; in another case it is not, as the problem should have been guarded against at a higher level by emitting far jump islands soon enough during pasteup of compiled code. --- js/src/jit/arm/Assembler-arm.cpp | 7 ++++++- js/src/jit/arm/MacroAssembler-arm.cpp | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 2830f0695..1e20da1c8 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -2401,7 +2401,12 @@ Assembler::as_b(Label* l, Condition c) if (oom()) return BufferOffset(); - as_b(BufferOffset(l).diffB(ret), c, ret); + BOffImm off = BufferOffset(l).diffB(ret); + if (off.isInvalid()) { + m_buffer.fail_bail(); + return BufferOffset(); + } + as_b(off, c, ret); #ifdef JS_DISASM_ARM spewBranch(m_buffer.getInstOrNull(ret), l); #endif diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index d40578514..a4161ab00 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -5012,7 +5012,10 @@ void MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset) { BufferOffset inst(callerOffset - 4); - as_bl(BufferOffset(calleeOffset).diffB(inst), Always, inst); + BOffImm off = BufferOffset(calleeOffset).diffB(inst); + MOZ_RELEASE_ASSERT(!off.isInvalid(), + "Failed to insert necessary far jump islands"); + as_bl(off, Always, inst); } CodeOffset -- cgit v1.2.3 From 50062bdfc004c8e24e3344ffe6991894ee0e6d09 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 29 May 2019 11:08:31 +0200 Subject: Fix #1091 deprot --- js/src/jit/IonCaches.cpp | 1 + js/src/jit/Recover.cpp | 1 + 2 files changed, 2 insertions(+) (limited to 'js/src/jit') diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 96e488ea8..0208db6ae 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -31,6 +31,7 @@ #include "jit/shared/Lowering-shared-inl.h" #include "vm/Interpreter-inl.h" #include "vm/Shape-inl.h" +#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 13bf9224b..6fd71f377 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -30,6 +30,7 @@ #include "vm/Interpreter-inl.h" #include "vm/NativeObject-inl.h" +#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; -- cgit v1.2.3 From e34920575d6dac353cb3d8a5d1b9c11ae05c5a8c Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 10 Jun 2019 16:49:47 +0000 Subject: Inline combined methods for NativeObject and UnboxedArrayObject accesses. --- js/src/jit/BaselineIC.cpp | 34 +++++++++++++++------------------- js/src/jit/BaselineIC.h | 12 ++++++------ js/src/jit/BaselineInspector.cpp | 2 +- js/src/jit/BaselineInspector.h | 2 +- js/src/jit/MCallOptimize.cpp | 10 +++++----- js/src/jit/VMFunctions.cpp | 2 +- 6 files changed, 29 insertions(+), 33 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 1d230e083..28e263ac7 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -2373,8 +2373,8 @@ CanOptimizeDenseOrUnboxedArraySetElem(JSObject* obj, uint32_t index, Shape* oldShape, uint32_t oldCapacity, uint32_t oldInitLength, bool* isAddingCaseOut, size_t* protoDepthOut) { - uint32_t initLength = GetAnyBoxedOrUnboxedInitializedLength(obj); - uint32_t capacity = GetAnyBoxedOrUnboxedCapacity(obj); + uint32_t initLength = obj->as().getDenseInitializedLength(); + uint32_t capacity = obj->as().getDenseCapacity(); *isAddingCaseOut = false; *protoDepthOut = 0; @@ -2464,8 +2464,8 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_ uint32_t oldCapacity = 0; uint32_t oldInitLength = 0; if (index.isInt32() && index.toInt32() >= 0) { - oldCapacity = GetAnyBoxedOrUnboxedCapacity(obj); - oldInitLength = GetAnyBoxedOrUnboxedInitializedLength(obj); + oldCapacity = obj->as().getDenseCapacity(); + oldInitLength = obj->as().getDenseInitializedLength(); } if (op == JSOP_INITELEM || op == JSOP_INITHIDDENELEM) { @@ -5762,14 +5762,14 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb } static bool -CopyArray(JSContext* cx, HandleObject obj, MutableHandleValue result) +CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) { - uint32_t length = GetAnyBoxedOrUnboxedArrayLength(obj); - JSObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, obj, length, TenuredObject); + uint32_t length = arr->length(); + JSObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject); if (!nobj) return false; EnsureArrayGroupAnalyzed(cx, nobj); - CopyBoxedOrUnboxedDenseElements(cx, nobj, obj, 0, 0, length); + CopyBoxedOrUnboxedDenseElements(cx, nobj, arr, 0, 0, length); result.setObject(*nobj); return true; @@ -5801,26 +5801,22 @@ TryAttachStringSplit(JSContext* cx, ICCall_Fallback* stub, HandleScript script, RootedValue arr(cx); // Copy the array before storing in stub. - if (!CopyArray(cx, obj, &arr)) + if (!CopyArray(cx, obj.as(), &arr)) return false; // Atomize all elements of the array. - RootedObject arrObj(cx, &arr.toObject()); - uint32_t initLength = GetAnyBoxedOrUnboxedArrayLength(arrObj); + RootedArrayObject arrObj(cx, &arr.toObject().as()); + uint32_t initLength = arrObj->length(); for (uint32_t i = 0; i < initLength; i++) { - JSAtom* str = js::AtomizeString(cx, GetAnyBoxedOrUnboxedDenseElement(arrObj, i).toString()); + JSAtom* str = js::AtomizeString(cx, arrObj->getDenseElement(i).toString()); if (!str) return false; - if (!SetAnyBoxedOrUnboxedDenseElement(cx, arrObj, i, StringValue(str))) { - // The value could not be stored to an unboxed dense element. - return true; - } + arrObj->setDenseElementWithType(cx, i, StringValue(str)); } ICCall_StringSplit::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), - script->pcToOffset(pc), str, sep, - arr); + script->pcToOffset(pc), str, sep, arrObj); ICStub* newStub = compiler.getStub(compiler.getStubSpace(script)); if (!newStub) return false; @@ -6705,7 +6701,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler& masm) return true; } -typedef bool (*CopyArrayFn)(JSContext*, HandleObject, MutableHandleValue); +typedef bool (*CopyArrayFn)(JSContext*, HandleArrayObject, MutableHandleValue); static const VMFunction CopyArrayInfo = FunctionInfo(CopyArray, "CopyArray"); bool diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index afbea3b69..901fca9cc 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -2818,10 +2818,10 @@ class ICCall_StringSplit : public ICMonitoredStub uint32_t pcOffset_; GCPtrString expectedStr_; GCPtrString expectedSep_; - GCPtrObject templateObject_; + GCPtrArrayObject templateObject_; ICCall_StringSplit(JitCode* stubCode, ICStub* firstMonitorStub, uint32_t pcOffset, JSString* str, - JSString* sep, JSObject* templateObject) + JSString* sep, ArrayObject* templateObject) : ICMonitoredStub(ICStub::Call_StringSplit, stubCode, firstMonitorStub), pcOffset_(pcOffset), expectedStr_(str), expectedSep_(sep), templateObject_(templateObject) @@ -2848,7 +2848,7 @@ class ICCall_StringSplit : public ICMonitoredStub return expectedSep_; } - GCPtrObject& templateObject() { + GCPtrArrayObject& templateObject() { return templateObject_; } @@ -2858,7 +2858,7 @@ class ICCall_StringSplit : public ICMonitoredStub uint32_t pcOffset_; RootedString expectedStr_; RootedString expectedSep_; - RootedObject templateObject_; + RootedArrayObject templateObject_; MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm); @@ -2869,13 +2869,13 @@ class ICCall_StringSplit : public ICMonitoredStub public: Compiler(JSContext* cx, ICStub* firstMonitorStub, uint32_t pcOffset, HandleString str, - HandleString sep, HandleValue templateObject) + HandleString sep, HandleArrayObject templateObject) : ICCallStubCompiler(cx, ICStub::Call_StringSplit), firstMonitorStub_(firstMonitorStub), pcOffset_(pcOffset), expectedStr_(cx, str), expectedSep_(cx, sep), - templateObject_(cx, &templateObject.toObject()) + templateObject_(cx, templateObject) { } ICStub* getStub(ICStubSpace* space) { diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index 9c7b88fb2..bcb527516 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -580,7 +580,7 @@ BaselineInspector::getTemplateObjectForNative(jsbytecode* pc, Native native) bool BaselineInspector::isOptimizableCallStringSplit(jsbytecode* pc, JSString** strOut, JSString** sepOut, - JSObject** objOut) + ArrayObject** objOut) { if (!hasBaselineScript()) return false; diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h index 4a1791798..1ed4b5547 100644 --- a/js/src/jit/BaselineInspector.h +++ b/js/src/jit/BaselineInspector.h @@ -113,7 +113,7 @@ class BaselineInspector bool hasSeenNonStringIterMore(jsbytecode* pc); MOZ_MUST_USE bool isOptimizableCallStringSplit(jsbytecode* pc, JSString** strOut, - JSString** sepOut, JSObject** objOut); + JSString** sepOut, ArrayObject** objOut); JSObject* getTemplateObject(jsbytecode* pc); JSObject* getTemplateObjectForNative(jsbytecode* pc, Native native); JSObject* getTemplateObjectForClassHook(jsbytecode* pc, const Class* clasp); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 748a70973..0d5779cee 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -522,7 +522,7 @@ IonBuilder::inlineArray(CallInfo& callInfo) // Make sure initLength matches the template object's length. This is // not guaranteed to be the case, for instance if we're inlining the // MConstant may come from an outer script. - if (initLength != GetAnyBoxedOrUnboxedArrayLength(templateObject)) + if (initLength != templateObject->as().length()) return InliningStatus_NotInlined; // Don't inline large allocations. @@ -1396,7 +1396,7 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) // Check if exist a template object in stub. JSString* stringStr = nullptr; JSString* stringSep = nullptr; - JSObject* templateObject = nullptr; + ArrayObject* templateObject = nullptr; if (!inspector->isOptimizableCallStringSplit(pc, &stringStr, &stringSep, &templateObject)) return InliningStatus_NotInlined; @@ -1422,13 +1422,13 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) if (!key.maybeTypes()->hasType(TypeSet::StringType())) return InliningStatus_NotInlined; - uint32_t initLength = GetAnyBoxedOrUnboxedArrayLength(templateObject); - if (GetAnyBoxedOrUnboxedInitializedLength(templateObject) != initLength) + uint32_t initLength = templateObject->length(); + if (templateObject->getDenseInitializedLength() != initLength) return InliningStatus_NotInlined; Vector arrayValues; for (uint32_t i = 0; i < initLength; i++) { - Value str = GetAnyBoxedOrUnboxedDenseElement(templateObject, i); + Value str = templateObject->getDenseElement(i); MOZ_ASSERT(str.toString()->isAtom()); MConstant* value = MConstant::New(alloc().fallible(), str, constraints()); if (!value) diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 0717bb86d..7b1e1cad6 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -339,7 +339,7 @@ ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval) bool ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length) { - *length = GetAnyBoxedOrUnboxedArrayLength(obj); + *length = obj->as().length(); DenseElementResult result = SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, *length, v.address(), 1, ShouldUpdateTypes::DontUpdate); -- cgit v1.2.3 From e95089d84ac71276bd059e52293ab42c2259d89e Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 12 Jun 2019 03:19:09 +0000 Subject: Make use of ArrayObjects in favor of generic JS objects. ArrayObjects has been a thing for years but been under-used. About time they are used where prudent. --- js/src/jit/BaselineCompiler.cpp | 6 +++--- js/src/jit/BaselineIC.cpp | 8 ++++---- js/src/jit/CodeGenerator.cpp | 8 ++++---- js/src/jit/Recover.cpp | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 3fa5a80ed..93e3759b9 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2055,7 +2055,7 @@ BaselineCompiler::emit_JSOP_SPREADCALLARRAY() return emit_JSOP_NEWARRAY(); } -typedef JSObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject, gc::InitialHeap); +typedef ArrayObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject, gc::InitialHeap); const VMFunction jit::NewArrayCopyOnWriteInfo = FunctionInfo(js::NewDenseCopyOnWriteArray, "NewDenseCopyOnWriteArray"); @@ -4136,14 +4136,14 @@ BaselineCompiler::emit_JSOP_REST() { frame.syncStack(0); - JSObject* templateObject = + ArrayObject* templateObject = ObjectGroup::newArrayObject(cx, nullptr, 0, TenuredObject, ObjectGroup::NewArrayKind::UnknownIndex); if (!templateObject) return false; // Call IC. - ICRest_Fallback::Compiler compiler(cx, &templateObject->as()); + ICRest_Fallback::Compiler compiler(cx, templateObject); if (!emitOpIC(compiler.getStub(&stubSpace_))) return false; diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 28e263ac7..2b0822655 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -5765,10 +5765,10 @@ static bool CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) { uint32_t length = arr->length(); - JSObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject); + ArrayObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject); if (!nobj) return false; - EnsureArrayGroupAnalyzed(cx, nobj); + EnsureArrayGroupAnalyzed(cx, nobj); //XXX CopyBoxedOrUnboxedDenseElements(cx, nobj, arr, 0, 0, length); result.setObject(*nobj); @@ -8547,8 +8547,8 @@ static bool DoRestFallback(JSContext* cx, BaselineFrame* frame, ICRest_Fallback* unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0; Value* rest = frame->argv() + numFormals; - JSObject* obj = ObjectGroup::newArrayObject(cx, rest, numRest, GenericObject, - ObjectGroup::NewArrayKind::UnknownIndex); + ArrayObject* obj = ObjectGroup::newArrayObject(cx, rest, numRest, GenericObject, + ObjectGroup::NewArrayKind::UnknownIndex); if (!obj) return false; res.setObject(*obj); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 485e881fe..ae9c61031 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -5169,11 +5169,11 @@ static JSObject* NewArrayWithGroup(JSContext* cx, uint32_t length, HandleObjectGroup group, bool convertDoubleElements) { - JSObject* res = NewFullyAllocatedArrayTryUseGroup(cx, group, length); + ArrayObject* res = NewFullyAllocatedArrayTryUseGroup(cx, group, length); if (!res) return nullptr; if (convertDoubleElements) - res->as().setShouldConvertDoubleElements(); + res->setShouldConvertDoubleElements(); return res; } @@ -5319,7 +5319,7 @@ CodeGenerator::visitNewArrayCopyOnWrite(LNewArrayCopyOnWrite* lir) masm.bind(ool->rejoin()); } -typedef JSObject* (*ArrayConstructorOneArgFn)(JSContext*, HandleObjectGroup, int32_t length); +typedef ArrayObject* (*ArrayConstructorOneArgFn)(JSContext*, HandleObjectGroup, int32_t length); static const VMFunction ArrayConstructorOneArgInfo = FunctionInfo(ArrayConstructorOneArg, "ArrayConstructorOneArg"); @@ -7765,7 +7765,7 @@ CodeGenerator::visitSinCos(LSinCos *lir) masm.freeStack(sizeof(double) * 2); } -typedef JSObject* (*StringSplitFn)(JSContext*, HandleObjectGroup, HandleString, HandleString, uint32_t); +typedef ArrayObject* (*StringSplitFn)(JSContext*, HandleObjectGroup, HandleString, HandleString, uint32_t); static const VMFunction StringSplitInfo = FunctionInfo(js::str_split_string, "str_split_string"); diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 6fd71f377..8fe6ee3fb 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -1355,7 +1355,7 @@ RNewArray::recover(JSContext* cx, SnapshotIterator& iter) const RootedValue result(cx); RootedObjectGroup group(cx, templateObject->group()); - JSObject* resultObject = NewFullyAllocatedArrayTryUseGroup(cx, group, count_); + ArrayObject* resultObject = NewFullyAllocatedArrayTryUseGroup(cx, group, count_); if (!resultObject) return false; -- cgit v1.2.3 From 93ce7c7372b20f6e6c6778f9c196b723a1df27a8 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 12 Jun 2019 09:09:53 +0000 Subject: Remove unused LIR temp register for unboxed arrays. --- js/src/jit/Lowering.cpp | 16 ++++------------ js/src/jit/shared/LIR-shared.h | 24 ++++++++---------------- 2 files changed, 12 insertions(+), 28 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index e185b5746..68417138b 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3137,20 +3137,16 @@ LIRGenerator::visitStoreElementHole(MStoreElementHole* ins) const LUse elements = useRegister(ins->elements()); const LAllocation index = useRegisterOrConstant(ins->index()); - // Use a temp register when adding new elements to unboxed arrays. - LDefinition tempDef = LDefinition::BogusTemp(); - LInstruction* lir; switch (ins->value()->type()) { case MIRType::Value: - lir = new(alloc()) LStoreElementHoleV(object, elements, index, useBox(ins->value()), - tempDef); + lir = new(alloc()) LStoreElementHoleV(object, elements, index, useBox(ins->value())); break; default: { const LAllocation value = useRegisterOrNonDoubleConstant(ins->value()); - lir = new(alloc()) LStoreElementHoleT(object, elements, index, value, tempDef); + lir = new(alloc()) LStoreElementHoleT(object, elements, index, value); break; } } @@ -3169,18 +3165,14 @@ LIRGenerator::visitFallibleStoreElement(MFallibleStoreElement* ins) const LUse elements = useRegister(ins->elements()); const LAllocation index = useRegisterOrConstant(ins->index()); - // Use a temp register when adding new elements to unboxed arrays. - LDefinition tempDef = LDefinition::BogusTemp(); - LInstruction* lir; switch (ins->value()->type()) { case MIRType::Value: - lir = new(alloc()) LFallibleStoreElementV(object, elements, index, useBox(ins->value()), - tempDef); + lir = new(alloc()) LFallibleStoreElementV(object, elements, index, useBox(ins->value())); break; default: const LAllocation value = useRegisterOrNonDoubleConstant(ins->value()); - lir = new(alloc()) LFallibleStoreElementT(object, elements, index, value, tempDef); + lir = new(alloc()) LFallibleStoreElementT(object, elements, index, value); break; } diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index 35c7e7442..ffa4d8367 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -5669,19 +5669,17 @@ class LStoreElementT : public LInstructionHelper<0, 3, 0> }; // Like LStoreElementV, but supports indexes >= initialized length. -class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> +class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 0> { public: LIR_HEADER(StoreElementHoleV) LStoreElementHoleV(const LAllocation& object, const LAllocation& elements, - const LAllocation& index, const LBoxAllocation& value, - const LDefinition& temp) { + const LAllocation& index, const LBoxAllocation& value) { setOperand(0, object); setOperand(1, elements); setOperand(2, index); setBoxOperand(Value, value); - setTemp(0, temp); } static const size_t Value = 3; @@ -5701,19 +5699,17 @@ class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> }; // Like LStoreElementT, but supports indexes >= initialized length. -class LStoreElementHoleT : public LInstructionHelper<0, 4, 1> +class LStoreElementHoleT : public LInstructionHelper<0, 4, 0> { public: LIR_HEADER(StoreElementHoleT) LStoreElementHoleT(const LAllocation& object, const LAllocation& elements, - const LAllocation& index, const LAllocation& value, - const LDefinition& temp) { + const LAllocation& index, const LAllocation& value) { setOperand(0, object); setOperand(1, elements); setOperand(2, index); setOperand(3, value); - setTemp(0, temp); } const MStoreElementHole* mir() const { @@ -5734,19 +5730,17 @@ class LStoreElementHoleT : public LInstructionHelper<0, 4, 1> }; // Like LStoreElementV, but can just ignore assignment (for eg. frozen objects) -class LFallibleStoreElementV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> +class LFallibleStoreElementV : public LInstructionHelper<0, 3 + BOX_PIECES, 0> { public: LIR_HEADER(FallibleStoreElementV) LFallibleStoreElementV(const LAllocation& object, const LAllocation& elements, - const LAllocation& index, const LBoxAllocation& value, - const LDefinition& temp) { + const LAllocation& index, const LBoxAllocation& value) { setOperand(0, object); setOperand(1, elements); setOperand(2, index); setBoxOperand(Value, value); - setTemp(0, temp); } static const size_t Value = 3; @@ -5766,19 +5760,17 @@ class LFallibleStoreElementV : public LInstructionHelper<0, 3 + BOX_PIECES, 1> }; // Like LStoreElementT, but can just ignore assignment (for eg. frozen objects) -class LFallibleStoreElementT : public LInstructionHelper<0, 4, 1> +class LFallibleStoreElementT : public LInstructionHelper<0, 4, 0> { public: LIR_HEADER(FallibleStoreElementT) LFallibleStoreElementT(const LAllocation& object, const LAllocation& elements, - const LAllocation& index, const LAllocation& value, - const LDefinition& temp) { + const LAllocation& index, const LAllocation& value) { setOperand(0, object); setOperand(1, elements); setOperand(2, index); setOperand(3, value); - setTemp(0, temp); } const MFallibleStoreElement* mir() const { -- cgit v1.2.3 From 3c878b1e3bbb043b22ab032bce1fe111b8062ca9 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 17 Jun 2019 18:37:23 +0000 Subject: Convert CopyBoxedOrUnboxedDenseElements to something that doesn't crash. --- js/src/jit/BaselineIC.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 2b0822655..17fdb1807 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -5769,8 +5769,18 @@ CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) if (!nobj) return false; EnsureArrayGroupAnalyzed(cx, nobj); //XXX - CopyBoxedOrUnboxedDenseElements(cx, nobj, arr, 0, 0, length); - + + MOZ_ASSERT(arr->isNative()); + MOZ_ASSERT(nobj->isNative()); + MOZ_ASSERT(nobj->as().getDenseInitializedLength() == 0); + MOZ_ASSERT(arr->as().getDenseInitializedLength() >= length); + MOZ_ASSERT(nobj->as().getDenseCapacity() >= length); + + nobj->as().setDenseInitializedLength(length); + + const Value* vp = arr->as().getDenseElements(); + nobj->as().initDenseElements(0, vp, length); + result.setObject(*nobj); return true; } -- cgit v1.2.3 From 85f9a95ddbc39a1b120eeb8280685e1ae40dc5dc Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 14 Jun 2019 11:33:28 +0000 Subject: Replace SetOrExtendBoxedOrUnboxedDenseElements with direct calls. --- js/src/jit/CodeGenerator.cpp | 13 ++++++------- js/src/jit/VMFunctions.cpp | 23 ++++++++++------------- js/src/jit/VMFunctions.h | 6 +++--- 3 files changed, 19 insertions(+), 23 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index ae9c61031..e0b8a7f28 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8213,11 +8213,10 @@ CodeGenerator::visitFallibleStoreElementV(LFallibleStoreElementV* lir) masm.bind(&isFrozen); } -typedef bool (*SetDenseOrUnboxedArrayElementFn)(JSContext*, HandleObject, int32_t, - HandleValue, bool strict); -static const VMFunction SetDenseOrUnboxedArrayElementInfo = - FunctionInfo(SetDenseOrUnboxedArrayElement, - "SetDenseOrUnboxedArrayElement"); +typedef bool (*SetDenseElementFn)(JSContext*, HandleNativeObject, int32_t, HandleValue, + bool strict); +static const VMFunction SetDenseElementInfo = + FunctionInfo(jit::SetDenseElement, "SetDenseElement"); void CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) @@ -8326,7 +8325,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool) else pushArg(ToRegister(index)); pushArg(object); - callVM(SetDenseOrUnboxedArrayElementInfo, ins); + callVM(SetDenseElementInfo, ins); restoreLive(ins); masm.jump(ool->rejoin()); @@ -8500,7 +8499,7 @@ CodeGenerator::visitArrayPopShiftT(LArrayPopShiftT* lir) emitArrayPopShift(lir, lir->mir(), obj, elements, length, out); } -typedef bool (*ArrayPushDenseFn)(JSContext*, HandleObject, HandleValue, uint32_t*); +typedef bool (*ArrayPushDenseFn)(JSContext*, HandleArrayObject, HandleValue, uint32_t*); static const VMFunction ArrayPushDenseInfo = FunctionInfo(jit::ArrayPushDense, "ArrayPushDense"); diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 7b1e1cad6..297357b1e 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -337,12 +337,11 @@ ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval) } bool -ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length) +ArrayPushDense(JSContext* cx, HandleArrayObject arr, HandleValue v, uint32_t* length) { - *length = obj->as().length(); - DenseElementResult result = - SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, *length, v.address(), 1, - ShouldUpdateTypes::DontUpdate); + *length = arr->length(); + DenseElementResult result = arr->setOrExtendDenseElements(cx, *length, v.address(), 1, + ShouldUpdateTypes::DontUpdate); if (result != DenseElementResult::Incomplete) { (*length)++; return result == DenseElementResult::Success; @@ -350,7 +349,7 @@ ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length) JS::AutoValueArray<3> argv(cx); argv[0].setUndefined(); - argv[1].setObject(*obj); + argv[1].setObject(*arr); argv[2].set(v); if (!js::array_push(cx, 1, argv.begin())) return false; @@ -1143,16 +1142,14 @@ Recompile(JSContext* cx) } bool -SetDenseOrUnboxedArrayElement(JSContext* cx, HandleObject obj, int32_t index, - HandleValue value, bool strict) +SetDenseElement(JSContext* cx, HandleNativeObject obj, int32_t index, HandleValue value, bool strict) { // This function is called from Ion code for StoreElementHole's OOL path. - // In this case we know the object is native or an unboxed array and that - // no type changes are needed. + // In this case we know the object is native and that no type changes are + // needed. - DenseElementResult result = - SetOrExtendBoxedOrUnboxedDenseElements(cx, obj, index, value.address(), 1, - ShouldUpdateTypes::DontUpdate); + DenseElementResult result = obj->setOrExtendDenseElements(cx, index, value.address(), 1, + ShouldUpdateTypes::DontUpdate); if (result != DenseElementResult::Incomplete) return result == DenseElementResult::Success; diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 572f05373..9a2edd0f3 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -622,7 +622,7 @@ template bool StringsEqual(JSContext* cx, HandleString left, HandleString right, bool* res); MOZ_MUST_USE bool ArrayPopDense(JSContext* cx, HandleObject obj, MutableHandleValue rval); -MOZ_MUST_USE bool ArrayPushDense(JSContext* cx, HandleObject obj, HandleValue v, uint32_t* length); +MOZ_MUST_USE bool ArrayPushDense(JSContext* cx, HandleArrayObject obj, HandleValue v, uint32_t* length); MOZ_MUST_USE bool ArrayShiftDense(JSContext* cx, HandleObject obj, MutableHandleValue rval); JSString* ArrayJoin(JSContext* cx, HandleObject array, HandleString sep); @@ -748,8 +748,8 @@ ForcedRecompile(JSContext* cx); JSString* StringReplace(JSContext* cx, HandleString string, HandleString pattern, HandleString repl); -MOZ_MUST_USE bool SetDenseOrUnboxedArrayElement(JSContext* cx, HandleObject obj, int32_t index, - HandleValue value, bool strict); +MOZ_MUST_USE bool SetDenseElement(JSContext* cx, HandleNativeObject obj, int32_t index, + HandleValue value, bool strict); void AssertValidObjectPtr(JSContext* cx, JSObject* obj); void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj); -- cgit v1.2.3 From e9aac71c6d7fa67c7581e2bd75accae5a9699165 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 16 Jun 2019 19:55:05 +0000 Subject: Remove and clean up more code. --- js/src/jit/BaselineIC.cpp | 23 +++-------------------- js/src/jit/MIR.h | 10 +++++----- 2 files changed, 8 insertions(+), 25 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 17fdb1807..9151d9634 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -5365,13 +5365,6 @@ GetTemplateObjectForSimd(JSContext* cx, JSFunction* target, MutableHandleObject return true; } -static void -EnsureArrayGroupAnalyzed(JSContext* cx, JSObject* obj) -{ - if (PreliminaryObjectArrayWithTemplate* objects = obj->group()->maybePreliminaryObjects()) - objects->maybeAnalyze(cx, obj->group(), /* forceAnalyze = */ true); -} - static bool GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& args, MutableHandleObject res, bool* skipAttach) @@ -5403,10 +5396,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& // With this and other array templates, analyze the group so that // we don't end up with a template whose structure might change later. res.set(NewFullyAllocatedArrayForCallingAllocationSite(cx, count, TenuredObject)); - if (!res) - return false; - EnsureArrayGroupAnalyzed(cx, res); - return true; + return !!res; } } @@ -5432,10 +5422,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& } res.set(NewFullyAllocatedArrayTryReuseGroup(cx, &args.thisv().toObject(), 0, TenuredObject)); - if (!res) - return false; - EnsureArrayGroupAnalyzed(cx, res); - return true; + return !!res; } } } @@ -5452,10 +5439,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& } res.set(NewFullyAllocatedArrayForCallingAllocationSite(cx, 0, TenuredObject)); - if (!res) - return false; - EnsureArrayGroupAnalyzed(cx, res); - return true; + return !!res; } if (native == StringConstructor) { @@ -5768,7 +5752,6 @@ CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) ArrayObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject); if (!nobj) return false; - EnsureArrayGroupAnalyzed(cx, nobj); //XXX MOZ_ASSERT(arr->isNative()); MOZ_ASSERT(nobj->isNative()); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index f316827dc..4bedfb268 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9234,7 +9234,7 @@ class MLoadElement ALLOW_CLONE(MLoadElement) }; -// Load a value from the elements vector for a dense native or unboxed array. +// Load a value from the elements vector of a native object. // If the index is out-of-bounds, or the indexed slot has a hole, undefined is // returned instead. class MLoadElementHole @@ -9465,10 +9465,10 @@ class MStoreElement ALLOW_CLONE(MStoreElement) }; -// Like MStoreElement, but supports indexes >= initialized length, and can -// handle unboxed arrays. The downside is that we cannot hoist the elements -// vector and bounds check, since this instruction may update the (initialized) -// length and reallocate the elements vector. +// Like MStoreElement, but supports indexes >= initialized length. The downside +// is that we cannot hoist the elements vector and bounds check, since this +// instruction may update the (initialized) length and reallocate the elements +// vector. class MStoreElementHole : public MAryInstruction<4>, public MStoreElementCommon, -- cgit v1.2.3 From 772cd4b188fd9f30521d4983f60363f4a830e2aa Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 16 Jun 2019 23:13:47 +0000 Subject: Remove JSOP_SPREADCALLARRAY and just use JSOP_NEWARRAY again. --- js/src/jit/BaselineCompiler.cpp | 6 ------ js/src/jit/BaselineCompiler.h | 1 - js/src/jit/IonBuilder.cpp | 2 ++ 3 files changed, 2 insertions(+), 7 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 93e3759b9..6b64bfb44 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -2049,12 +2049,6 @@ BaselineCompiler::emit_JSOP_NEWARRAY() return true; } -bool -BaselineCompiler::emit_JSOP_SPREADCALLARRAY() -{ - return emit_JSOP_NEWARRAY(); -} - typedef ArrayObject* (*NewArrayCopyOnWriteFn)(JSContext*, HandleArrayObject, gc::InitialHeap); const VMFunction jit::NewArrayCopyOnWriteInfo = FunctionInfo(js::NewDenseCopyOnWriteArray, "NewDenseCopyOnWriteArray"); diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 6b5bf009e..910a52980 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -100,7 +100,6 @@ namespace jit { _(JSOP_BITNOT) \ _(JSOP_NEG) \ _(JSOP_NEWARRAY) \ - _(JSOP_SPREADCALLARRAY) \ _(JSOP_NEWARRAY_COPYONWRITE) \ _(JSOP_INITELEM_ARRAY) \ _(JSOP_NEWOBJECT) \ diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 3d964d1c6..fc864a197 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2218,6 +2218,8 @@ IonBuilder::inspectOpcode(JSOp op) // update that stale value. #endif default: + // Any unused opcodes and JSOP_LIMIT will end up here without having + // to explicitly specify break; } -- cgit v1.2.3 From fcc11b2fec61c37c90ffe40e8f406eba64654a9c Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 18 Jun 2019 12:59:22 +0000 Subject: Tabs -> Spaces (no code change) --- js/src/jit/BaselineIC.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 9151d9634..64cdf01a6 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -5752,7 +5752,7 @@ CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) ArrayObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject); if (!nobj) return false; - + MOZ_ASSERT(arr->isNative()); MOZ_ASSERT(nobj->isNative()); MOZ_ASSERT(nobj->as().getDenseInitializedLength() == 0); @@ -5763,7 +5763,7 @@ CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result) const Value* vp = arr->as().getDenseElements(); nobj->as().initDenseElements(0, vp, length); - + result.setObject(*nobj); return true; } -- cgit v1.2.3 From 32d13a1648a64fe26be66de026bffca8c1afa88f Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 20 Jun 2019 12:56:32 +0200 Subject: Call a more generic function when inlining array natives. This simplifies the code a bit because ElementAccessHasExtraIndexedProperty checks for length-overflow (directly) and sparse-indexes (through TypeCanHaveExtraIndexedProperties) so the callers don't have to do that anymore. --- js/src/jit/MCallOptimize.cpp | 21 +++++---------------- js/src/jit/MIR.cpp | 9 --------- js/src/jit/MIR.h | 1 - 3 files changed, 5 insertions(+), 26 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 0d5779cee..fed5aefe5 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -621,7 +621,8 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) return InliningStatus_NotInlined; } - if (ArrayPrototypeHasIndexedProperty(this, script())) { + // Watch out for extra indexed properties on the object or its prototype. + if (ElementAccessHasExtraIndexedProperty(this, obj)) { trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); return InliningStatus_NotInlined; } @@ -748,14 +749,8 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) const Class* clasp = thisTypes->getKnownClass(constraints()); if (clasp != &ArrayObject::class_) return InliningStatus_NotInlined; - if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES | - OBJECT_FLAG_LENGTH_OVERFLOW)) - { - trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags); - return InliningStatus_NotInlined; - } - if (ArrayPrototypeHasIndexedProperty(this, script())) { + if (ElementAccessHasExtraIndexedProperty(this, obj)) { trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); return InliningStatus_NotInlined; } @@ -825,15 +820,9 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) const Class* clasp = thisTypes->getKnownClass(constraints()); if (clasp != &ArrayObject::class_) return InliningStatus_NotInlined; - if (thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_SPARSE_INDEXES | - OBJECT_FLAG_LENGTH_OVERFLOW)) - { - trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags); - return InliningStatus_NotInlined; - } - // Watch out for indexed properties on the prototype. - if (ArrayPrototypeHasIndexedProperty(this, script())) { + // Watch out for indexed properties on the object or its prototype. + if (ElementAccessHasExtraIndexedProperty(this, obj)) { trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); return InliningStatus_NotInlined; } diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 6aa46be4b..190b40bb2 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -6221,15 +6221,6 @@ PrototypeHasIndexedProperty(IonBuilder* builder, JSObject* obj) return false; } -// Whether Array.prototype, or an object on its proto chain, has an indexed property. -bool -jit::ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script) -{ - if (JSObject* proto = script->global().maybeGetArrayPrototype()) - return PrototypeHasIndexedProperty(builder, proto); - return true; -} - // Whether obj or any of its prototypes have an indexed property. bool jit::TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types) diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 4bedfb268..6526e0931 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -14054,7 +14054,6 @@ bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* MBasicBlock* current, MDefinition** pobj, PropertyName* name, MDefinition** pvalue, bool canModify, MIRType implicitType = MIRType::None); -bool ArrayPrototypeHasIndexedProperty(IonBuilder* builder, JSScript* script); bool TypeCanHaveExtraIndexedProperties(IonBuilder* builder, TemporaryTypeSet* types); inline MIRType -- cgit v1.2.3 From 6cebf2549e9c7b9eea978332e58b55589da6274f Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 23 Jun 2019 19:41:16 +0000 Subject: Remove Unboxed Object code from jit, Part 2. --- js/src/jit/BaselineCacheIR.cpp | 52 +------- js/src/jit/BaselineIC.cpp | 114 ----------------- js/src/jit/BaselineInspector.cpp | 46 +------ js/src/jit/CacheIR.cpp | 72 +---------- js/src/jit/CacheIR.h | 20 --- js/src/jit/IonCaches.cpp | 262 -------------------------------------- js/src/jit/IonCaches.h | 12 -- js/src/jit/MacroAssembler.cpp | 264 --------------------------------------- js/src/jit/MacroAssembler.h | 14 --- 9 files changed, 7 insertions(+), 849 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineCacheIR.cpp b/js/src/jit/BaselineCacheIR.cpp index 7fb586811..67c80473b 100644 --- a/js/src/jit/BaselineCacheIR.cpp +++ b/js/src/jit/BaselineCacheIR.cpp @@ -16,7 +16,7 @@ using namespace js; using namespace js::jit; // OperandLocation represents the location of an OperandId. The operand is -// either in a register or on the stack, and is either boxed or unboxed. +// either in a register or on the stack. class OperandLocation { public: @@ -814,36 +814,6 @@ BaselineCacheIRCompiler::emitGuardSpecificObject() return true; } -bool -BaselineCacheIRCompiler::emitGuardNoUnboxedExpando() -{ - Register obj = allocator.useRegister(masm, reader.objOperandId()); - - FailurePath* failure; - if (!addFailurePath(&failure)) - return false; - - Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando()); - masm.branchPtr(Assembler::NotEqual, expandoAddr, ImmWord(0), failure->label()); - return true; -} - -bool -BaselineCacheIRCompiler::emitGuardAndLoadUnboxedExpando() -{ - Register obj = allocator.useRegister(masm, reader.objOperandId()); - Register output = allocator.defineRegister(masm, reader.objOperandId()); - - FailurePath* failure; - if (!addFailurePath(&failure)) - return false; - - Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando()); - masm.loadPtr(expandoAddr, output); - masm.branchTestPtr(Assembler::Zero, output, output, failure->label()); - return true; -} - bool BaselineCacheIRCompiler::emitLoadFixedSlotResult() { @@ -870,26 +840,6 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult() return true; } -bool -BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult() -{ - Register obj = allocator.useRegister(masm, reader.objOperandId()); - AutoScratchRegister scratch(allocator, masm); - - JSValueType fieldType = reader.valueType(); - - Address fieldOffset(stubAddress(reader.stubOffset())); - masm.load32(fieldOffset, scratch); - masm.loadUnboxedProperty(BaseIndex(obj, scratch, TimesOne), fieldType, R0); - - if (fieldType == JSVAL_TYPE_OBJECT) - emitEnterTypeMonitorIC(); - else - emitReturnFromIC(); - - return true; -} - bool BaselineCacheIRCompiler::emitGuardNoDetachedTypedObjects() { diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 64cdf01a6..ba855dac9 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -1920,13 +1920,6 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler& masm) if (popR1) masm.addToStackPtr(ImmWord(sizeof(size_t))); - } else if (acctype_ == ICGetElemNativeStub::UnboxedProperty) { - masm.load32(Address(ICStubReg, ICGetElemNativeSlotStub::offsetOfOffset()), - scratchReg); - masm.loadUnboxedProperty(BaseIndex(objReg, scratchReg, TimesOne), unboxedType_, - TypedOrValueRegister(R0)); - if (popR1) - masm.addToStackPtr(ImmWord(sizeof(size_t))); } else { MOZ_ASSERT(acctype_ == ICGetElemNativeStub::NativeGetter || acctype_ == ICGetElemNativeStub::ScriptedGetter); @@ -4292,40 +4285,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc, return true; } -static bool -TryAttachUnboxedSetPropStub(JSContext* cx, HandleScript script, - ICSetProp_Fallback* stub, HandleId id, - HandleObject obj, HandleValue rhs, bool* attached) -{ - MOZ_ASSERT(!*attached); - - if (!cx->runtime()->jitSupportsFloatingPoint) - return true; - - if (!obj->is()) - return true; - - const UnboxedLayout::Property* property = obj->as().layout().lookup(id); - if (!property) - return true; - - ICSetProp_Unboxed::Compiler compiler(cx, obj->group(), - property->offset + UnboxedPlainObject::offsetOfData(), - property->type); - ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub) - return false; - if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs)) - return false; - - stub->addNewStub(newStub); - - StripPreliminaryObjectStubs(cx, stub); - - *attached = true; - return true; -} - static bool TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script, ICSetProp_Fallback* stub, HandleId id, @@ -4485,15 +4444,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ if (attached) return true; - if (!attached && - lhs.isObject() && - !TryAttachUnboxedSetPropStub(cx, script, stub, id, obj, rhs, &attached)) - { - return false; - } - if (attached) - return true; - if (!attached && lhs.isObject() && !TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached)) @@ -4828,70 +4778,6 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm) return true; } -bool -ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm) -{ - MOZ_ASSERT(engine_ == Engine::Baseline); - - Label failure; - - // Guard input is an object. - masm.branchTestObject(Assembler::NotEqual, R0, &failure); - - AllocatableGeneralRegisterSet regs(availableGeneralRegs(2)); - Register scratch = regs.takeAny(); - - // Unbox and group guard. - Register object = masm.extractObject(R0, ExtractTemp0); - masm.loadPtr(Address(ICStubReg, ICSetProp_Unboxed::offsetOfGroup()), scratch); - masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch, - &failure); - - if (needsUpdateStubs()) { - // Stow both R0 and R1 (object and value). - EmitStowICValues(masm, 2); - - // Move RHS into R0 for TypeUpdate check. - masm.moveValue(R1, R0); - - // Call the type update stub. - if (!callTypeUpdateIC(masm, sizeof(Value))) - return false; - - // Unstow R0 and R1 (object and key) - EmitUnstowICValues(masm, 2); - - // The TypeUpdate IC may have smashed object. Rederive it. - masm.unboxObject(R0, object); - - // Trigger post barriers here on the values being written. Fields which - // objects can be written to also need update stubs. - LiveGeneralRegisterSet saveRegs; - saveRegs.add(R0); - saveRegs.add(R1); - saveRegs.addUnchecked(object); - saveRegs.add(ICStubReg); - emitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs); - } - - // Compute the address being written to. - masm.load32(Address(ICStubReg, ICSetProp_Unboxed::offsetOfFieldOffset()), scratch); - BaseIndex address(object, scratch, TimesOne); - - EmitUnboxedPreBarrierForBaseline(masm, address, fieldType_); - masm.storeUnboxedProperty(address, fieldType_, - ConstantOrRegister(TypedOrValueRegister(R1)), &failure); - - // The RHS has to be in R0. - masm.moveValue(R1, R0); - - EmitReturnFromIC(masm); - - masm.bind(&failure); - EmitStubGuardFailure(masm); - return true; -} - bool ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm) { diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp index bcb527516..3b852debf 100644 --- a/js/src/jit/BaselineInspector.cpp +++ b/js/src/jit/BaselineInspector.cpp @@ -104,19 +104,11 @@ AddReceiver(const ReceiverGuard& receiver, static bool GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver) { - // We match either: + // We match: // // GuardIsObject 0 // GuardShape 0 // LoadFixedSlotResult 0 or LoadDynamicSlotResult 0 - // - // or - // - // GuardIsObject 0 - // GuardGroup 0 - // 1: GuardAndLoadUnboxedExpando 0 - // GuardShape 1 - // LoadFixedSlotResult 1 or LoadDynamicSlotResult 1 *receiver = ReceiverGuard(); CacheIRReader reader(stub->stubInfo()); @@ -125,14 +117,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re if (!reader.matchOp(CacheOp::GuardIsObject, objId)) return false; - if (reader.matchOp(CacheOp::GuardGroup, objId)) { - receiver->group = stub->stubInfo()->getStubField(stub, reader.stubOffset()); - - if (!reader.matchOp(CacheOp::GuardAndLoadUnboxedExpando, objId)) - return false; - objId = reader.objOperandId(); - } - if (reader.matchOp(CacheOp::GuardShape, objId)) { receiver->shape = stub->stubInfo()->getStubField(stub, reader.stubOffset()); return reader.matchOpEither(CacheOp::LoadFixedSlotResult, CacheOp::LoadDynamicSlotResult); @@ -141,29 +125,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re return false; } -static bool -GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* receiver) -{ - // We match: - // - // GuardIsObject 0 - // GuardGroup 0 - // LoadUnboxedPropertyResult 0 .. - - *receiver = ReceiverGuard(); - CacheIRReader reader(stub->stubInfo()); - - ObjOperandId objId = ObjOperandId(0); - if (!reader.matchOp(CacheOp::GuardIsObject, objId)) - return false; - - if (!reader.matchOp(CacheOp::GuardGroup, objId)) - return false; - receiver->group = stub->stubInfo()->getStubField(stub, reader.stubOffset()); - - return reader.matchOp(CacheOp::LoadUnboxedPropertyResult, objId); -} - bool BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers) { @@ -182,8 +143,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv while (stub->next()) { ReceiverGuard receiver; if (stub->isCacheIR_Monitored()) { - if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver) && - !GetCacheIRReceiverForUnboxedProperty(stub->toCacheIR_Monitored(), &receiver)) + if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver)) { receivers.clear(); return true; @@ -191,8 +151,6 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv } else if (stub->isSetProp_Native()) { receiver = ReceiverGuard(stub->toSetProp_Native()->group(), stub->toSetProp_Native()->shape()); - } else if (stub->isSetProp_Unboxed()) { - receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr); } else { receivers.clear(); return true; diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index 6822a70af..d184ea40c 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -10,8 +10,7 @@ #include "jit/IonCaches.h" #include "jsobjinlines.h" - -#include "vm/UnboxedObject-inl.h" +#include "vm/NativeObject-inl.h" using namespace js; using namespace js::jit; @@ -60,10 +59,6 @@ GetPropIRGenerator::tryAttachStub(Maybe& writer) return false; if (!emitted_ && !tryAttachNative(*writer, obj, objId)) return false; - if (!emitted_ && !tryAttachUnboxed(*writer, obj, objId)) - return false; - if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId)) - return false; if (!emitted_ && !tryAttachTypedObject(*writer, obj, objId)) return false; if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId)) @@ -163,19 +158,9 @@ GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder, } static void -TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId, - Maybe* expandoId) +TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId) { - if (obj->is()) { - writer.guardGroup(objId, obj->group()); - - if (UnboxedExpandoObject* expando = obj->as().maybeExpando()) { - expandoId->emplace(writer.guardAndLoadUnboxedExpando(objId)); - writer.guardShape(expandoId->ref(), expando->lastProperty()); - } else { - writer.guardNoUnboxedExpando(objId); - } - } else if (obj->is()) { + if (obj->is()) { writer.guardGroup(objId, obj->group()); } else { Shape* shape = obj->maybeShape(); @@ -188,8 +173,7 @@ static void EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder, Shape* shape, ObjOperandId objId) { - Maybe expandoId; - TestMatchingReceiver(writer, obj, shape, objId, &expandoId); + TestMatchingReceiver(writer, obj, shape, objId); ObjOperandId holderId; if (obj != holder) { @@ -212,9 +196,6 @@ EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder, lastObjId = protoId; } } - } else if (obj->is()) { - holder = obj->as().maybeExpando(); - holderId = *expandoId; } else { holderId = objId; } @@ -265,51 +246,6 @@ GetPropIRGenerator::tryAttachNative(CacheIRWriter& writer, HandleObject obj, Obj return true; } -bool -GetPropIRGenerator::tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId) -{ - MOZ_ASSERT(!emitted_); - - if (!obj->is()) - return true; - - const UnboxedLayout::Property* property = obj->as().layout().lookup(name_); - if (!property) - return true; - - if (!cx_->runtime()->jitSupportsFloatingPoint) - return true; - - writer.guardGroup(objId, obj->group()); - writer.loadUnboxedPropertyResult(objId, property->type, - UnboxedPlainObject::offsetOfData() + property->offset); - emitted_ = true; - preliminaryObjectAction_ = PreliminaryObjectAction::Unlink; - return true; -} - -bool -GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId) -{ - MOZ_ASSERT(!emitted_); - - if (!obj->is()) - return true; - - UnboxedExpandoObject* expando = obj->as().maybeExpando(); - if (!expando) - return true; - - Shape* shape = expando->lookup(cx_, NameToId(name_)); - if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot()) - return true; - - emitted_ = true; - - EmitReadSlotResult(writer, obj, obj, shape, objId); - return true; -} - bool GetPropIRGenerator::tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId) { diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h index 4fd8575f0..ae55cfebb 100644 --- a/js/src/jit/CacheIR.h +++ b/js/src/jit/CacheIR.h @@ -87,13 +87,10 @@ class ObjOperandId : public OperandId _(GuardClass) \ _(GuardSpecificObject) \ _(GuardNoDetachedTypedObjects) \ - _(GuardNoUnboxedExpando) \ - _(GuardAndLoadUnboxedExpando) \ _(LoadObject) \ _(LoadProto) \ _(LoadFixedSlotResult) \ _(LoadDynamicSlotResult) \ - _(LoadUnboxedPropertyResult) \ _(LoadTypedObjectResult) \ _(LoadInt32ArrayLengthResult) \ _(LoadArgumentsObjectLengthResult) \ @@ -274,15 +271,6 @@ class MOZ_RAII CacheIRWriter void guardNoDetachedTypedObjects() { writeOp(CacheOp::GuardNoDetachedTypedObjects); } - void guardNoUnboxedExpando(ObjOperandId obj) { - writeOpWithOperandId(CacheOp::GuardNoUnboxedExpando, obj); - } - ObjOperandId guardAndLoadUnboxedExpando(ObjOperandId obj) { - ObjOperandId res(nextOperandId_++); - writeOpWithOperandId(CacheOp::GuardAndLoadUnboxedExpando, obj); - writeOperandId(res); - return res; - } ObjOperandId loadObject(JSObject* obj) { ObjOperandId res(nextOperandId_++); @@ -308,11 +296,6 @@ class MOZ_RAII CacheIRWriter writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj); addStubWord(offset, StubField::GCType::NoGCThing); } - void loadUnboxedPropertyResult(ObjOperandId obj, JSValueType type, size_t offset) { - writeOpWithOperandId(CacheOp::LoadUnboxedPropertyResult, obj); - buffer_.writeByte(uint32_t(type)); - addStubWord(offset, StubField::GCType::NoGCThing); - } void loadTypedObjectResult(ObjOperandId obj, uint32_t offset, TypedThingLayout layout, uint32_t typeDescr) { MOZ_ASSERT(uint32_t(layout) <= UINT8_MAX); @@ -406,9 +389,6 @@ class MOZ_RAII GetPropIRGenerator PreliminaryObjectAction preliminaryObjectAction_; MOZ_MUST_USE bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId); - MOZ_MUST_USE bool tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId); - MOZ_MUST_USE bool tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, - ObjOperandId objId); MOZ_MUST_USE bool tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId); MOZ_MUST_USE bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj, diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 81cf9d9bb..1ef25cbd5 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -867,30 +867,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm, attacher.jumpNextStub(masm); } -static void -GenerateReadUnboxed(JSContext* cx, IonScript* ion, MacroAssembler& masm, - IonCache::StubAttacher& attacher, JSObject* obj, - const UnboxedLayout::Property* property, - Register object, TypedOrValueRegister output, - Label* failures = nullptr) -{ - // Guard on the group of the object. - attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, - Address(object, JSObject::offsetOfGroup()), - ImmGCPtr(obj->group()), failures); - - Address address(object, UnboxedPlainObject::offsetOfData() + property->offset); - - masm.loadUnboxedProperty(address, property->type, output); - - attacher.jumpRejoin(masm); - - if (failures) { - masm.bind(failures); - attacher.jumpNextStub(masm); - } -} - static bool EmitGetterCall(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher, JSObject* obj, @@ -1497,67 +1473,6 @@ GetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip return linkAndAttachStub(cx, masm, attacher, ion, attachKind, outcome); } -bool -GetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, void* returnAddr, bool* emitted) -{ - MOZ_ASSERT(canAttachStub()); - MOZ_ASSERT(!*emitted); - MOZ_ASSERT(outerScript->ionScript() == ion); - - if (!obj->is()) - return true; - const UnboxedLayout::Property* property = obj->as().layout().lookup(id); - if (!property) - return true; - - *emitted = true; - - MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); - - Label failures; - emitIdGuard(masm, id, &failures); - Label* maybeFailures = failures.used() ? &failures : nullptr; - - StubAttacher attacher(*this); - GenerateReadUnboxed(cx, ion, masm, attacher, obj, property, object(), output(), maybeFailures); - return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed", - JS::TrackedOutcome::ICGetPropStub_UnboxedRead); -} - -bool -GetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, void* returnAddr, bool* emitted) -{ - MOZ_ASSERT(canAttachStub()); - MOZ_ASSERT(!*emitted); - MOZ_ASSERT(outerScript->ionScript() == ion); - - if (!obj->is()) - return true; - Rooted expando(cx, obj->as().maybeExpando()); - if (!expando) - return true; - - Shape* shape = expando->lookup(cx, id); - if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot()) - return true; - - *emitted = true; - - MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); - - Label failures; - emitIdGuard(masm, id, &failures); - Label* maybeFailures = failures.used() ? &failures : nullptr; - - StubAttacher attacher(*this); - GenerateReadSlot(cx, ion, masm, attacher, DontCheckTDZ, obj, obj, - shape, object(), output(), maybeFailures); - return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed expando", - JS::TrackedOutcome::ICGetPropStub_UnboxedReadExpando); -} - bool GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion, HandleObject obj, HandleId id, bool* emitted) @@ -2127,12 +2042,6 @@ GetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, returnAddr, emitted)) return false; - if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, returnAddr, emitted)) - return false; - - if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, returnAddr, emitted)) - return false; - if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, id, emitted)) return false; } @@ -3298,141 +3207,6 @@ CanAttachNativeSetProp(JSContext* cx, HandleObject obj, HandleId id, const Const return SetPropertyIC::CanAttachNone; } -static void -GenerateSetUnboxed(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher, - JSObject* obj, jsid id, uint32_t unboxedOffset, JSValueType unboxedType, - Register object, Register tempReg, const ConstantOrRegister& value, - bool checkTypeset, Label* failures) -{ - // Guard on the type of the object. - masm.branchPtr(Assembler::NotEqual, - Address(object, JSObject::offsetOfGroup()), - ImmGCPtr(obj->group()), failures); - - if (checkTypeset) - CheckTypeSetForWrite(masm, obj, id, tempReg, value, failures); - - Address address(object, UnboxedPlainObject::offsetOfData() + unboxedOffset); - - if (cx->zone()->needsIncrementalBarrier()) { - if (unboxedType == JSVAL_TYPE_OBJECT) - masm.callPreBarrier(address, MIRType::Object); - else if (unboxedType == JSVAL_TYPE_STRING) - masm.callPreBarrier(address, MIRType::String); - else - MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(unboxedType)); - } - - masm.storeUnboxedProperty(address, unboxedType, value, failures); - - attacher.jumpRejoin(masm); - - masm.bind(failures); - attacher.jumpNextStub(masm); -} - -static bool -CanAttachSetUnboxed(JSContext* cx, HandleObject obj, HandleId id, const ConstantOrRegister& val, - bool needsTypeBarrier, bool* checkTypeset, - uint32_t* unboxedOffset, JSValueType* unboxedType) -{ - if (!obj->is()) - return false; - - const UnboxedLayout::Property* property = obj->as().layout().lookup(id); - if (property) { - *checkTypeset = false; - if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset)) - return false; - *unboxedOffset = property->offset; - *unboxedType = property->type; - return true; - } - - return false; -} - -static bool -CanAttachSetUnboxedExpando(JSContext* cx, HandleObject obj, HandleId id, - const ConstantOrRegister& val, - bool needsTypeBarrier, bool* checkTypeset, Shape** pshape) -{ - if (!obj->is()) - return false; - - Rooted expando(cx, obj->as().maybeExpando()); - if (!expando) - return false; - - Shape* shape = expando->lookupPure(id); - if (!shape || !shape->hasDefaultSetter() || !shape->hasSlot() || !shape->writable()) - return false; - - *checkTypeset = false; - if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset)) - return false; - - *pshape = shape; - return true; -} - -static bool -CanAttachAddUnboxedExpando(JSContext* cx, HandleObject obj, HandleShape oldShape, - HandleId id, const ConstantOrRegister& val, - bool needsTypeBarrier, bool* checkTypeset) -{ - if (!obj->is()) - return false; - - Rooted expando(cx, obj->as().maybeExpando()); - if (!expando || expando->inDictionaryMode()) - return false; - - Shape* newShape = expando->lastProperty(); - if (newShape->isEmptyShape() || newShape->propid() != id || newShape->previous() != oldShape) - return false; - - MOZ_ASSERT(newShape->hasDefaultSetter() && newShape->hasSlot() && newShape->writable()); - - if (PrototypeChainShadowsPropertyAdd(cx, obj, id)) - return false; - - *checkTypeset = false; - if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset)) - return false; - - return true; -} - -bool -SetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, bool* emitted) -{ - MOZ_ASSERT(!*emitted); - - bool checkTypeset = false; - uint32_t unboxedOffset; - JSValueType unboxedType; - if (!CanAttachSetUnboxed(cx, obj, id, value(), needsTypeBarrier(), &checkTypeset, - &unboxedOffset, &unboxedType)) - { - return true; - } - - *emitted = true; - - MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); - StubAttacher attacher(*this); - - Label failures; - emitIdGuard(masm, id, &failures); - - GenerateSetUnboxed(cx, masm, attacher, obj, id, unboxedOffset, unboxedType, - object(), temp(), value(), checkTypeset, &failures); - return linkAndAttachStub(cx, masm, attacher, ion, "set_unboxed", - JS::TrackedOutcome::ICSetPropStub_SetUnboxed); -} - bool SetPropertyIC::tryAttachProxy(JSContext* cx, HandleScript outerScript, IonScript* ion, HandleObject obj, HandleId id, bool* emitted) @@ -3513,26 +3287,6 @@ SetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip MOZ_CRASH("Unreachable"); } -bool -SetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, bool* emitted) -{ - MOZ_ASSERT(!*emitted); - - RootedShape shape(cx); - bool checkTypeset = false; - if (!CanAttachSetUnboxedExpando(cx, obj, id, value(), needsTypeBarrier(), - &checkTypeset, shape.address())) - { - return true; - } - - if (!attachSetSlot(cx, outerScript, ion, obj, shape, checkTypeset)) - return false; - *emitted = true; - return true; -} - bool SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* ion, HandleObject obj, HandleValue idval, HandleValue value, @@ -3558,12 +3312,6 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, emitted, tryNativeAddSlot)) return false; - - if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, emitted)) - return false; - - if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, emitted)) - return false; } if (idval.isInt32()) { @@ -3615,16 +3363,6 @@ SetPropertyIC::tryAttachAddSlot(JSContext* cx, HandleScript outerScript, IonScri return true; } - checkTypeset = false; - if (CanAttachAddUnboxedExpando(cx, obj, oldShape, id, value(), needsTypeBarrier(), - &checkTypeset)) - { - if (!attachAddSlot(cx, outerScript, ion, obj, id, oldShape, oldGroup, checkTypeset)) - return false; - *emitted = true; - return true; - } - return true; } diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 173e06c6b..b00646538 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -529,18 +529,6 @@ class GetPropertyIC : public IonCache HandleObject obj, HandleId id, void* returnAddr, bool* emitted); - MOZ_MUST_USE bool tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion, - HandleObject obj, HandleId id, void* returnAddr, - bool* emitted); - - MOZ_MUST_USE bool tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, - IonScript* ion, HandleObject obj, HandleId id, - void* returnAddr, bool* emitted); - - MOZ_MUST_USE bool tryAttachUnboxedArrayLength(JSContext* cx, HandleScript outerScript, - IonScript* ion, HandleObject obj, HandleId id, - void* returnAddr, bool* emitted); - MOZ_MUST_USE bool tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion, HandleObject obj, HandleId id, bool* emitted); diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index e50f68722..bc04e85cf 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -468,243 +468,6 @@ template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const A template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex& src, const ValueOperand& dest, bool allowDouble, Register temp, Label* fail); -template -void -MacroAssembler::loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output) -{ - switch (type) { - case JSVAL_TYPE_INT32: { - // Handle loading an int32 into a double reg. - if (output.type() == MIRType::Double) { - convertInt32ToDouble(address, output.typedReg().fpu()); - break; - } - MOZ_FALLTHROUGH; - } - - case JSVAL_TYPE_BOOLEAN: - case JSVAL_TYPE_STRING: { - Register outReg; - if (output.hasValue()) { - outReg = output.valueReg().scratchReg(); - } else { - MOZ_ASSERT(output.type() == MIRTypeFromValueType(type)); - outReg = output.typedReg().gpr(); - } - - switch (type) { - case JSVAL_TYPE_BOOLEAN: - load8ZeroExtend(address, outReg); - break; - case JSVAL_TYPE_INT32: - load32(address, outReg); - break; - case JSVAL_TYPE_STRING: - loadPtr(address, outReg); - break; - default: - MOZ_CRASH(); - } - - if (output.hasValue()) - tagValue(type, outReg, output.valueReg()); - break; - } - - case JSVAL_TYPE_OBJECT: - if (output.hasValue()) { - Register scratch = output.valueReg().scratchReg(); - loadPtr(address, scratch); - - Label notNull, done; - branchPtr(Assembler::NotEqual, scratch, ImmWord(0), ¬Null); - - moveValue(NullValue(), output.valueReg()); - jump(&done); - - bind(¬Null); - tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg()); - - bind(&done); - } else { - // Reading null can't be possible here, as otherwise the result - // would be a value (either because null has been read before or - // because there is a barrier). - Register reg = output.typedReg().gpr(); - loadPtr(address, reg); -#ifdef DEBUG - Label ok; - branchTestPtr(Assembler::NonZero, reg, reg, &ok); - assumeUnreachable("Null not possible"); - bind(&ok); -#endif - } - break; - - case JSVAL_TYPE_DOUBLE: - // Note: doubles in unboxed objects are not accessed through other - // views and do not need canonicalization. - if (output.hasValue()) - loadValue(address, output.valueReg()); - else - loadDouble(address, output.typedReg().fpu()); - break; - - default: - MOZ_CRASH(); - } -} - -template void -MacroAssembler::loadUnboxedProperty(Address address, JSValueType type, - TypedOrValueRegister output); - -template void -MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type, - TypedOrValueRegister output); - -static void -StoreUnboxedFailure(MacroAssembler& masm, Label* failure) -{ - // Storing a value to an unboxed property is a fallible operation and - // the caller must provide a failure label if a particular unboxed store - // might fail. Sometimes, however, a store that cannot succeed (such as - // storing a string to an int32 property) will be marked as infallible. - // This can only happen if the code involved is unreachable. - if (failure) - masm.jump(failure); - else - masm.assumeUnreachable("Incompatible write to unboxed property"); -} - -template -void -MacroAssembler::storeUnboxedProperty(T address, JSValueType type, - const ConstantOrRegister& value, Label* failure) -{ - switch (type) { - case JSVAL_TYPE_BOOLEAN: - if (value.constant()) { - if (value.value().isBoolean()) - store8(Imm32(value.value().toBoolean()), address); - else - StoreUnboxedFailure(*this, failure); - } else if (value.reg().hasTyped()) { - if (value.reg().type() == MIRType::Boolean) - store8(value.reg().typedReg().gpr(), address); - else - StoreUnboxedFailure(*this, failure); - } else { - if (failure) - branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure); - storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 1); - } - break; - - case JSVAL_TYPE_INT32: - if (value.constant()) { - if (value.value().isInt32()) - store32(Imm32(value.value().toInt32()), address); - else - StoreUnboxedFailure(*this, failure); - } else if (value.reg().hasTyped()) { - if (value.reg().type() == MIRType::Int32) - store32(value.reg().typedReg().gpr(), address); - else - StoreUnboxedFailure(*this, failure); - } else { - if (failure) - branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure); - storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 4); - } - break; - - case JSVAL_TYPE_DOUBLE: - if (value.constant()) { - if (value.value().isNumber()) { - loadConstantDouble(value.value().toNumber(), ScratchDoubleReg); - storeDouble(ScratchDoubleReg, address); - } else { - StoreUnboxedFailure(*this, failure); - } - } else if (value.reg().hasTyped()) { - if (value.reg().type() == MIRType::Int32) { - convertInt32ToDouble(value.reg().typedReg().gpr(), ScratchDoubleReg); - storeDouble(ScratchDoubleReg, address); - } else if (value.reg().type() == MIRType::Double) { - storeDouble(value.reg().typedReg().fpu(), address); - } else { - StoreUnboxedFailure(*this, failure); - } - } else { - ValueOperand reg = value.reg().valueReg(); - Label notInt32, end; - branchTestInt32(Assembler::NotEqual, reg, ¬Int32); - int32ValueToDouble(reg, ScratchDoubleReg); - storeDouble(ScratchDoubleReg, address); - jump(&end); - bind(¬Int32); - if (failure) - branchTestDouble(Assembler::NotEqual, reg, failure); - storeValue(reg, address); - bind(&end); - } - break; - - case JSVAL_TYPE_OBJECT: - if (value.constant()) { - if (value.value().isObjectOrNull()) - storePtr(ImmGCPtr(value.value().toObjectOrNull()), address); - else - StoreUnboxedFailure(*this, failure); - } else if (value.reg().hasTyped()) { - MOZ_ASSERT(value.reg().type() != MIRType::Null); - if (value.reg().type() == MIRType::Object) - storePtr(value.reg().typedReg().gpr(), address); - else - StoreUnboxedFailure(*this, failure); - } else { - if (failure) { - Label ok; - branchTestNull(Assembler::Equal, value.reg().valueReg(), &ok); - branchTestObject(Assembler::NotEqual, value.reg().valueReg(), failure); - bind(&ok); - } - storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t)); - } - break; - - case JSVAL_TYPE_STRING: - if (value.constant()) { - if (value.value().isString()) - storePtr(ImmGCPtr(value.value().toString()), address); - else - StoreUnboxedFailure(*this, failure); - } else if (value.reg().hasTyped()) { - if (value.reg().type() == MIRType::String) - storePtr(value.reg().typedReg().gpr(), address); - else - StoreUnboxedFailure(*this, failure); - } else { - if (failure) - branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure); - storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t)); - } - break; - - default: - MOZ_CRASH(); - } -} - -template void -MacroAssembler::storeUnboxedProperty(Address address, JSValueType type, - const ConstantOrRegister& value, Label* failure); - -template void -MacroAssembler::storeUnboxedProperty(BaseIndex address, JSValueType type, - const ConstantOrRegister& value, Label* failure); - // Inlined version of gc::CheckAllocatorState that checks the bare essentials // and bails for anything that cannot be handled with our jit allocators. void @@ -1252,10 +1015,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj, nbytes = (nbytes < sizeof(uintptr_t)) ? 0 : nbytes - sizeof(uintptr_t); offset += sizeof(uintptr_t); } - } else if (templateObj->is()) { - storePtr(ImmWord(0), Address(obj, UnboxedPlainObject::offsetOfExpando())); - if (initContents) - initUnboxedObjectContents(obj, &templateObj->as()); } else { MOZ_CRASH("Unknown object"); } @@ -1276,29 +1035,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj, #endif } -void -MacroAssembler::initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject) -{ - const UnboxedLayout& layout = templateObject->layoutDontCheckGeneration(); - - // Initialize reference fields of the object, per UnboxedPlainObject::create. - if (const int32_t* list = layout.traceList()) { - while (*list != -1) { - storePtr(ImmGCPtr(GetJitContext()->runtime->names().empty), - Address(object, UnboxedPlainObject::offsetOfData() + *list)); - list++; - } - list++; - while (*list != -1) { - storePtr(ImmWord(0), - Address(object, UnboxedPlainObject::offsetOfData() + *list)); - list++; - } - // Unboxed objects don't have Values to initialize. - MOZ_ASSERT(*(list + 1) == -1); - } -} - void MacroAssembler::compareStrings(JSOp op, Register left, Register right, Register result, Label* fail) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 6ee989463..d5cc95839 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -36,7 +36,6 @@ #include "vm/ProxyObject.h" #include "vm/Shape.h" #include "vm/TypedArrayObject.h" -#include "vm/UnboxedObject.h" using mozilla::FloatingPoint; @@ -1626,17 +1625,6 @@ class MacroAssembler : public MacroAssemblerSpecific void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address& dest, unsigned numElems = 0); - // Load a property from an UnboxedPlainObject. - template - void loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output); - - // Store a property to an UnboxedPlainObject, without triggering barriers. - // If failure is null, the value definitely has a type suitable for storing - // in the property. - template - void storeUnboxedProperty(T address, JSValueType type, - const ConstantOrRegister& value, Label* failure); - Register extractString(const Address& address, Register scratch) { return extractObject(address, scratch); } @@ -1713,8 +1701,6 @@ class MacroAssembler : public MacroAssemblerSpecific LiveRegisterSet liveRegs, Label* fail, TypedArrayObject* templateObj, TypedArrayLength lengthKind); - void initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject); - void newGCString(Register result, Register temp, Label* fail); void newGCFatInlineString(Register result, Register temp, Label* fail); -- cgit v1.2.3 From fd96dac1d27da739cf168395623a962b2f0f1b98 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 23 Jun 2019 19:41:44 +0000 Subject: Fix unified deprot --- js/src/jit/CodeGenerator.cpp | 1 + js/src/jit/VMFunctions.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index e0b8a7f28..71a8890f3 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -25,6 +25,7 @@ #include "builtin/Eval.h" #include "builtin/TypedObject.h" #include "gc/Nursery.h" +#include "gc/StoreBuffer-inl.h" #include "irregexp/NativeRegExpMacroAssembler.h" #include "jit/AtomicOperations.h" #include "jit/BaselineCompiler.h" diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 297357b1e..402d910b9 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -28,7 +28,7 @@ #include "vm/NativeObject-inl.h" #include "vm/StringObject-inl.h" #include "vm/TypeInference-inl.h" -#include "vm/UnboxedObject-inl.h" +#include "gc/StoreBuffer-inl.h" using namespace js; using namespace js::jit; -- cgit v1.2.3 From ac97104c52c573e25392312d3bb7b3a297f67c44 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 23 Jun 2019 21:30:34 +0000 Subject: Remove Unboxed Object code from jit, Part 3. --- js/src/jit/BaselineIC.cpp | 40 +++---------------------------------- js/src/jit/BaselineIC.h | 10 ++-------- js/src/jit/IonCaches.cpp | 5 ----- js/src/jit/MCallOptimize.cpp | 1 - js/src/jit/OptimizationTracking.cpp | 4 ---- js/src/jit/Recover.cpp | 35 +++++--------------------------- 6 files changed, 10 insertions(+), 85 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index ba855dac9..56049a2a0 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -42,8 +42,8 @@ #include "jit/shared/Lowering-shared-inl.h" #include "vm/EnvironmentObject-inl.h" #include "vm/Interpreter-inl.h" +#include "vm/NativeObject-inl.h" #include "vm/StringObject-inl.h" -#include "vm/UnboxedObject-inl.h" using mozilla::DebugOnly; @@ -732,11 +732,6 @@ LastPropertyForSetProp(JSObject* obj) if (obj->isNative()) return obj->as().lastProperty(); - if (obj->is()) { - UnboxedExpandoObject* expando = obj->as().maybeExpando(); - return expando ? expando->lastProperty() : nullptr; - } - return nullptr; } @@ -2666,18 +2661,6 @@ BaselineScript::noteArrayWriteHole(uint32_t pcOffset) // SetElem_DenseOrUnboxedArray // -template -void -EmitUnboxedPreBarrierForBaseline(MacroAssembler &masm, T address, JSValueType type) -{ - if (type == JSVAL_TYPE_OBJECT) - EmitPreBarrier(masm, address, MIRType::Object); - else if (type == JSVAL_TYPE_STRING) - EmitPreBarrier(masm, address, MIRType::String); - else - MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type)); -} - bool ICSetElem_DenseOrUnboxedArray::Compiler::generateStubCode(MacroAssembler& masm) { @@ -4124,18 +4107,7 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC return true; if (!obj->isNative()) { - if (obj->is()) { - UnboxedExpandoObject* expando = obj->as().maybeExpando(); - if (expando) { - shape = expando->lookup(cx, name); - if (!shape) - return true; - } else { - return true; - } - } else { - return true; - } + return true; } size_t chainDepth; @@ -4368,12 +4340,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ return false; RootedReceiverGuard oldGuard(cx, ReceiverGuard(obj)); - if (obj->is()) { - MOZ_ASSERT(!oldShape); - if (UnboxedExpandoObject* expando = obj->as().maybeExpando()) - oldShape = expando->lastProperty(); - } - bool attached = false; // There are some reasons we can fail to attach a stub that are temporary. // We want to avoid calling noteUnoptimizableAccess() if the reason we @@ -5538,7 +5504,7 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb if (!thisObject) return false; - if (thisObject->is() || thisObject->is()) + if (thisObject->is()) templateObject = thisObject; } diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 901fca9cc..98f0e1c59 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -22,7 +22,6 @@ #include "jit/SharedICRegisters.h" #include "js/GCVector.h" #include "vm/ArrayObject.h" -#include "vm/UnboxedObject.h" namespace js { namespace jit { @@ -1823,8 +1822,7 @@ class ICSetProp_Native : public ICUpdatedStub virtual int32_t getKey() const { return static_cast(engine_) | (static_cast(kind) << 1) | - (static_cast(isFixedSlot_) << 17) | - (static_cast(obj_->is()) << 18); + (static_cast(isFixedSlot_) << 17); } MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm); @@ -1929,7 +1927,6 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler return static_cast(engine_) | (static_cast(kind) << 1) | (static_cast(isFixedSlot_) << 17) | - (static_cast(obj_->is()) << 18) | (static_cast(protoChainDepth_) << 19); } @@ -1954,10 +1951,7 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler newGroup = nullptr; RootedShape newShape(cx); - if (obj_->isNative()) - newShape = obj_->as().lastProperty(); - else - newShape = obj_->as().maybeExpando()->lastProperty(); + newShape = obj_->as().lastProperty(); return newStub>( space, getStubCode(), oldGroup_, shapes, newShape, newGroup, offset_); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 1ef25cbd5..2cd9fa4be 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3384,11 +3384,6 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex return false; oldShape = obj->maybeShape(); - if (obj->is()) { - MOZ_ASSERT(!oldShape); - if (UnboxedExpandoObject* expando = obj->as().maybeExpando()) - oldShape = expando->lastProperty(); - } } RootedId id(cx); diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index fed5aefe5..359f04639 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -30,7 +30,6 @@ #include "jit/shared/Lowering-shared-inl.h" #include "vm/NativeObject-inl.h" #include "vm/StringObject-inl.h" -#include "vm/UnboxedObject-inl.h" using mozilla::ArrayLength; using mozilla::AssertedCast; diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp index b42634d43..7d72795a0 100644 --- a/js/src/jit/OptimizationTracking.cpp +++ b/js/src/jit/OptimizationTracking.cpp @@ -15,11 +15,9 @@ #include "jit/JitcodeMap.h" #include "jit/JitSpewer.h" #include "js/TrackedOptimizationInfo.h" -#include "vm/UnboxedObject.h" #include "vm/ObjectGroup-inl.h" #include "vm/TypeInference-inl.h" -#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; @@ -846,8 +844,6 @@ MaybeConstructorFromType(TypeSet::Type ty) return nullptr; ObjectGroup* obj = ty.group(); TypeNewScript* newScript = obj->newScript(); - if (!newScript && obj->maybeUnboxedLayout()) - newScript = obj->unboxedLayout().newScript(); return newScript ? newScript->function() : nullptr; } diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 8fe6ee3fb..3edc6de8b 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -1540,37 +1540,12 @@ RObjectState::recover(JSContext* cx, SnapshotIterator& iter) const RootedObject object(cx, &iter.read().toObject()); RootedValue val(cx); - if (object->is()) { - const UnboxedLayout& layout = object->as().layout(); - - RootedId id(cx); - RootedValue receiver(cx, ObjectValue(*object)); - const UnboxedLayout::PropertyVector& properties = layout.properties(); - for (size_t i = 0; i < properties.length(); i++) { - val = iter.read(); - - // This is the default placeholder value of MObjectState, when no - // properties are defined yet. - if (val.isUndefined()) - continue; - - id = NameToId(properties[i].name); - ObjectOpResult result; - - // SetProperty can only fail due to OOM. - if (!SetProperty(cx, object, id, val, receiver, result)) - return false; - if (!result) - return result.reportError(cx, object, id); - } - } else { - RootedNativeObject nativeObject(cx, &object->as()); - MOZ_ASSERT(nativeObject->slotSpan() == numSlots()); + RootedNativeObject nativeObject(cx, &object->as()); + MOZ_ASSERT(nativeObject->slotSpan() == numSlots()); - for (size_t i = 0; i < numSlots(); i++) { - val = iter.read(); - nativeObject->setSlot(i, val); - } + for (size_t i = 0; i < numSlots(); i++) { + val = iter.read(); + nativeObject->setSlot(i, val); } val.setObject(*object); -- cgit v1.2.3 From e2ab8d5f332cd26a072430fe1d1a4518cad15d1b Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 25 Jun 2019 11:12:26 +0000 Subject: Remove Unboxed Object code from jit, Part 4. --- js/src/jit/BaselineIC.cpp | 115 +++------------------------ js/src/jit/CodeGenerator.cpp | 15 +--- js/src/jit/IonBuilder.cpp | 183 ------------------------------------------- js/src/jit/IonBuilder.h | 13 --- js/src/jit/IonCaches.cpp | 69 +--------------- js/src/jit/Recover.cpp | 1 - js/src/jit/SharedIC.cpp | 30 +------ 7 files changed, 20 insertions(+), 406 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 56049a2a0..d95d08edc 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -1148,56 +1148,6 @@ TryAttachNativeOrUnboxedGetValueElemStub(JSContext* cx, HandleScript script, jsb ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub(); - if (obj->is() && holder == obj) { - const UnboxedLayout::Property* property = obj->as().layout().lookup(id); - - // Once unboxed objects support symbol-keys, we need to change the following accordingly - MOZ_ASSERT_IF(!keyVal.isString(), !property); - - if (property) { - if (!cx->runtime()->jitSupportsFloatingPoint) - return true; - - RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName()); - ICGetElemNativeCompiler compiler(cx, ICStub::GetElem_UnboxedPropertyName, - monitorStub, obj, holder, - name, - ICGetElemNativeStub::UnboxedProperty, - needsAtomize, property->offset + - UnboxedPlainObject::offsetOfData(), - property->type); - ICStub* newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub) - return false; - - stub->addNewStub(newStub); - *attached = true; - return true; - } - - Shape* shape = obj->as().maybeExpando()->lookup(cx, id); - if (!shape->hasDefaultGetter() || !shape->hasSlot()) - return true; - - bool isFixedSlot; - uint32_t offset; - GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset); - - ICGetElemNativeStub::AccessType acctype = - isFixedSlot ? ICGetElemNativeStub::FixedSlot - : ICGetElemNativeStub::DynamicSlot; - ICGetElemNativeCompiler compiler(cx, getGetElemStubKind(ICStub::GetElem_NativeSlotName), - monitorStub, obj, holder, key, - acctype, needsAtomize, offset); - ICStub* newStub = compiler.getStub(compiler.getStubSpace(script)); - if (!newStub) - return false; - - stub->addNewStub(newStub); - *attached = true; - return true; - } - if (!holder->isNative()) return true; @@ -1445,7 +1395,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_ } // Check for NativeObject[id] and UnboxedPlainObject[id] shape-optimizable accesses. - if (obj->isNative() || obj->is()) { + if (obj->isNative()) { RootedScript rootedScript(cx, script); if (rhs.isString()) { if (!TryAttachNativeOrUnboxedGetValueElemStub(cx, rootedScript, pc, stub, @@ -1857,14 +1807,6 @@ ICGetElemNativeCompiler::generateStubCode(MacroAssembler& masm) Register holderReg; if (obj_ == holder_) { holderReg = objReg; - - if (obj_->is() && acctype_ != ICGetElemNativeStub::UnboxedProperty) { - // The property will be loaded off the unboxed expando. - masm.push(R1.scratchReg()); - popR1 = true; - holderReg = R1.scratchReg(); - masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); - } } else { // Shape guard holder. if (regs.empty()) { @@ -4494,20 +4436,7 @@ GuardGroupAndShapeMaybeUnboxedExpando(MacroAssembler& masm, JSObject* obj, // Guard against shape or expando shape. masm.loadPtr(Address(ICStubReg, offsetOfShape), scratch); - if (obj->is()) { - Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando()); - masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure); - Label done; - masm.push(object); - masm.loadPtr(expandoAddress, object); - masm.branchTestObjShape(Assembler::Equal, object, scratch, &done); - masm.pop(object); - masm.jump(failure); - masm.bind(&done); - masm.pop(object); - } else { - masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); - } + masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); } bool @@ -4546,13 +4475,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler& masm) regs.takeUnchecked(objReg); Register holderReg; - if (obj_->is()) { - // We are loading off the expando object, so use that for the holder. - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); - if (!isFixedSlot_) - masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg); - } else if (isFixedSlot_) { + if (isFixedSlot_) { holderReg = objReg; } else { holderReg = regs.takeAny(); @@ -4689,31 +4612,17 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm) regs.add(R0); regs.takeUnchecked(objReg); - if (obj_->is()) { - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg); - - // Write the expando object's new shape. - Address shapeAddr(holderReg, ShapedObject::offsetOfShape()); - EmitPreBarrier(masm, shapeAddr, MIRType::Shape); - masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); - masm.storePtr(scratch, shapeAddr); + // Write the object's new shape. + Address shapeAddr(objReg, ShapedObject::offsetOfShape()); + EmitPreBarrier(masm, shapeAddr, MIRType::Shape); + masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); + masm.storePtr(scratch, shapeAddr); - if (!isFixedSlot_) - masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg); + if (isFixedSlot_) { + holderReg = objReg; } else { - // Write the object's new shape. - Address shapeAddr(objReg, ShapedObject::offsetOfShape()); - EmitPreBarrier(masm, shapeAddr, MIRType::Shape); - masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch); - masm.storePtr(scratch, shapeAddr); - - if (isFixedSlot_) { - holderReg = objReg; - } else { - holderReg = regs.takeAny(); - masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg); - } + holderReg = regs.takeAny(); + masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg); } // Perform the store. No write barrier required since this is a new diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 71a8890f3..a276ab9af 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -8383,11 +8383,6 @@ CodeGenerator::visitStoreUnboxedPointer(LStoreUnboxedPointer* lir) } } -typedef bool (*ConvertUnboxedObjectToNativeFn)(JSContext*, JSObject*); -static const VMFunction ConvertUnboxedPlainObjectToNativeInfo = - FunctionInfo(UnboxedPlainObject::convertToNative, - "UnboxedPlainObject::convertToNative"); - typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue); static const VMFunction ArrayPopDenseInfo = FunctionInfo(jit::ArrayPopDense, "ArrayPopDense"); @@ -8680,11 +8675,11 @@ CodeGenerator::visitIteratorStartO(LIteratorStartO* lir) masm.loadPtr(Address(niTemp, offsetof(NativeIterator, guard_array)), temp2); // Compare object with the first receiver guard. The last iterator can only - // match for native objects and unboxed objects. + // match for native objects. { Address groupAddr(temp2, offsetof(ReceiverGuard, group)); Address shapeAddr(temp2, offsetof(ReceiverGuard, shape)); - Label guardDone, shapeMismatch, noExpando; + Label guardDone, shapeMismatch; masm.loadObjShape(obj, temp1); masm.branchPtr(Assembler::NotEqual, shapeAddr, temp1, &shapeMismatch); @@ -8696,12 +8691,6 @@ CodeGenerator::visitIteratorStartO(LIteratorStartO* lir) masm.bind(&shapeMismatch); masm.loadObjGroup(obj, temp1); masm.branchPtr(Assembler::NotEqual, groupAddr, temp1, ool->entry()); - masm.loadPtr(Address(obj, UnboxedPlainObject::offsetOfExpando()), temp1); - masm.branchTestPtr(Assembler::Zero, temp1, temp1, &noExpando); - branchIfNotEmptyObjectElements(temp1, ool->entry()); - masm.loadObjShape(temp1, temp1); - masm.bind(&noExpando); - masm.branchPtr(Assembler::NotEqual, shapeAddr, temp1, ool->entry()); masm.bind(&guardDone); } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index fc864a197..a54a58add 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -10925,63 +10925,6 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_ return slot; } -uint32_t -IonBuilder::getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValueType* punboxedType) -{ - if (!types || types->unknownObject() || !types->objectOrSentinel()) { - trackOptimizationOutcome(TrackedOutcome::NoTypeInfo); - return UINT32_MAX; - } - - uint32_t offset = UINT32_MAX; - - for (size_t i = 0; i < types->getObjectCount(); i++) { - TypeSet::ObjectKey* key = types->getObject(i); - if (!key) - continue; - - if (key->unknownProperties()) { - trackOptimizationOutcome(TrackedOutcome::UnknownProperties); - return UINT32_MAX; - } - - if (key->isSingleton()) { - trackOptimizationOutcome(TrackedOutcome::Singleton); - return UINT32_MAX; - } - - UnboxedLayout* layout = key->group()->maybeUnboxedLayout(); - if (!layout) { - trackOptimizationOutcome(TrackedOutcome::NotUnboxed); - return UINT32_MAX; - } - - const UnboxedLayout::Property* property = layout->lookup(name); - if (!property) { - trackOptimizationOutcome(TrackedOutcome::StructNoField); - return UINT32_MAX; - } - - if (layout->nativeGroup()) { - trackOptimizationOutcome(TrackedOutcome::UnboxedConvertedToNative); - return UINT32_MAX; - } - - if (offset == UINT32_MAX) { - offset = property->offset; - *punboxedType = property->type; - } else if (offset != property->offset) { - trackOptimizationOutcome(TrackedOutcome::InconsistentFieldOffset); - return UINT32_MAX; - } else if (*punboxedType != property->type) { - trackOptimizationOutcome(TrackedOutcome::InconsistentFieldType); - return UINT32_MAX; - } - } - - return offset; -} - bool IonBuilder::jsop_runonce() { @@ -11948,72 +11891,6 @@ IonBuilder::getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyN return true; } -MInstruction* -IonBuilder::loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, - BarrierKind barrier, TemporaryTypeSet* types) -{ - // loadUnboxedValue is designed to load any value as if it were contained in - // an array. Thus a property offset is converted to an index, when the - // object is reinterpreted as an array of properties of the same size. - size_t index = offset / UnboxedTypeSize(unboxedType); - MInstruction* indexConstant = MConstant::New(alloc(), Int32Value(index)); - current->add(indexConstant); - - return loadUnboxedValue(obj, UnboxedPlainObject::offsetOfData(), - indexConstant, unboxedType, barrier, types); -} - -MInstruction* -IonBuilder::loadUnboxedValue(MDefinition* elements, size_t elementsOffset, - MDefinition* index, JSValueType unboxedType, - BarrierKind barrier, TemporaryTypeSet* types) -{ - MInstruction* load; - switch (unboxedType) { - case JSVAL_TYPE_BOOLEAN: - load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Uint8, - DoesNotRequireMemoryBarrier, elementsOffset); - load->setResultType(MIRType::Boolean); - break; - - case JSVAL_TYPE_INT32: - load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Int32, - DoesNotRequireMemoryBarrier, elementsOffset); - load->setResultType(MIRType::Int32); - break; - - case JSVAL_TYPE_DOUBLE: - load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Float64, - DoesNotRequireMemoryBarrier, elementsOffset, - /* canonicalizeDoubles = */ false); - load->setResultType(MIRType::Double); - break; - - case JSVAL_TYPE_STRING: - load = MLoadUnboxedString::New(alloc(), elements, index, elementsOffset); - break; - - case JSVAL_TYPE_OBJECT: { - MLoadUnboxedObjectOrNull::NullBehavior nullBehavior; - if (types->hasType(TypeSet::NullType())) - nullBehavior = MLoadUnboxedObjectOrNull::HandleNull; - else if (barrier != BarrierKind::NoBarrier) - nullBehavior = MLoadUnboxedObjectOrNull::BailOnNull; - else - nullBehavior = MLoadUnboxedObjectOrNull::NullNotPossible; - load = MLoadUnboxedObjectOrNull::New(alloc(), elements, index, nullBehavior, - elementsOffset); - break; - } - - default: - MOZ_CRASH(); - } - - current->add(load); - return load; -} - MDefinition* IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape, const BaselineInspector::ReceiverVector& receivers, @@ -12835,66 +12712,6 @@ IonBuilder::setPropTryDefiniteSlot(bool* emitted, MDefinition* obj, return true; } -MInstruction* -IonBuilder::storeUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, - MDefinition* value) -{ - size_t scaledOffsetConstant = offset / UnboxedTypeSize(unboxedType); - MInstruction* scaledOffset = MConstant::New(alloc(), Int32Value(scaledOffsetConstant)); - current->add(scaledOffset); - - return storeUnboxedValue(obj, obj, UnboxedPlainObject::offsetOfData(), - scaledOffset, unboxedType, value); -} - -MInstruction* -IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t elementsOffset, - MDefinition* scaledOffset, JSValueType unboxedType, - MDefinition* value, bool preBarrier /* = true */) -{ - MInstruction* store; - switch (unboxedType) { - case JSVAL_TYPE_BOOLEAN: - store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Uint8, - MStoreUnboxedScalar::DontTruncateInput, - DoesNotRequireMemoryBarrier, elementsOffset); - break; - - case JSVAL_TYPE_INT32: - store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Int32, - MStoreUnboxedScalar::DontTruncateInput, - DoesNotRequireMemoryBarrier, elementsOffset); - break; - - case JSVAL_TYPE_DOUBLE: - store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Float64, - MStoreUnboxedScalar::DontTruncateInput, - DoesNotRequireMemoryBarrier, elementsOffset); - break; - - case JSVAL_TYPE_STRING: - store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value, - elementsOffset, preBarrier); - break; - - case JSVAL_TYPE_OBJECT: - MOZ_ASSERT(value->type() == MIRType::Object || - value->type() == MIRType::Null || - value->type() == MIRType::Value); - MOZ_ASSERT(!value->mightBeType(MIRType::Undefined), - "MToObjectOrNull slow path is invalid for unboxed objects"); - store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value, obj, - elementsOffset, preBarrier); - break; - - default: - MOZ_CRASH(); - } - - current->add(store); - return store; -} - bool IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name, MDefinition* value, diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 1b97c4743..dd40b4bd6 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -1048,19 +1048,6 @@ class IonBuilder ResultWithOOM testNotDefinedProperty(MDefinition* obj, jsid id); uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed); - uint32_t getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, - JSValueType* punboxedType); - MInstruction* loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, - BarrierKind barrier, TemporaryTypeSet* types); - MInstruction* loadUnboxedValue(MDefinition* elements, size_t elementsOffset, - MDefinition* scaledOffset, JSValueType unboxedType, - BarrierKind barrier, TemporaryTypeSet* types); - MInstruction* storeUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType, - MDefinition* value); - MInstruction* storeUnboxedValue(MDefinition* obj, - MDefinition* elements, int32_t elementsOffset, - MDefinition* scaledOffset, JSValueType unboxedType, - MDefinition* value, bool preBarrier = true); MOZ_MUST_USE bool checkPreliminaryGroups(MDefinition *obj); MOZ_MUST_USE bool freezePropTypeSets(TemporaryTypeSet* types, JSObject* foundProto, PropertyName* name); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 2cd9fa4be..9901bdd07 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -31,7 +31,6 @@ #include "jit/shared/Lowering-shared-inl.h" #include "vm/Interpreter-inl.h" #include "vm/Shape-inl.h" -#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; @@ -620,26 +619,7 @@ TestMatchingReceiver(MacroAssembler& masm, IonCache::StubAttacher& attacher, Register object, JSObject* obj, Label* failure, bool alwaysCheckGroup = false) { - if (obj->is()) { - MOZ_ASSERT(failure); - - masm.branchTestObjGroup(Assembler::NotEqual, object, obj->group(), failure); - Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando()); - if (UnboxedExpandoObject* expando = obj->as().maybeExpando()) { - masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure); - Label success; - masm.push(object); - masm.loadPtr(expandoAddress, object); - masm.branchTestObjShape(Assembler::Equal, object, expando->lastProperty(), - &success); - masm.pop(object); - masm.jump(failure); - masm.bind(&success); - masm.pop(object); - } else { - masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure); - } - } else if (obj->is()) { + if (obj->is()) { attacher.branchNextStubOrLabel(masm, Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), ImmGCPtr(obj->group()), failure); @@ -756,7 +736,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm, // jump directly. Otherwise, jump to the end of the stub, so there's a // common point to patch. bool multipleFailureJumps = (obj != holder) - || obj->is() || (checkTDZ && output.hasValue()) || (failures != nullptr && failures->used()); @@ -775,7 +754,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm, Register scratchReg = Register::FromCode(0); // Quell compiler warning. if (obj != holder || - obj->is() || !holder->as().isFixedSlot(shape->slot())) { if (output.hasValue()) { @@ -836,10 +814,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm, holderReg = InvalidReg; } - } else if (obj->is()) { - holder = obj->as().maybeExpando(); - holderReg = scratchReg; - masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), holderReg); } else { holderReg = object; } @@ -2220,12 +2194,6 @@ GenerateSetSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att NativeObject::slotsSizeMustNotOverflow(); - if (obj->is()) { - obj = obj->as().maybeExpando(); - masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), tempReg); - object = tempReg; - } - if (obj->as().isFixedSlot(shape->slot())) { Address addr(object, NativeObject::getFixedSlotOffset(shape->slot())); @@ -2863,23 +2831,13 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att masm.branchTestObjGroup(Assembler::NotEqual, object, oldGroup, failures); if (obj->maybeShape()) { masm.branchTestObjShape(Assembler::NotEqual, object, oldShape, failures); - } else { - MOZ_ASSERT(obj->is()); - - Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando()); - masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failures); - - masm.loadPtr(expandoAddress, tempReg); - masm.branchTestObjShape(Assembler::NotEqual, tempReg, oldShape, failures); } Shape* newShape = obj->maybeShape(); - if (!newShape) - newShape = obj->as().maybeExpando()->lastProperty(); // Guard that the incoming value is in the type set for the property // if a type barrier is required. - if (checkTypeset) + if (newShape && checkTypeset) CheckTypeSetForWrite(masm, obj, newShape->propid(), tempReg, value, failures); // Guard shapes along prototype chain. @@ -2900,9 +2858,7 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att } // Call a stub to (re)allocate dynamic slots, if necessary. - uint32_t newNumDynamicSlots = obj->is() - ? obj->as().maybeExpando()->numDynamicSlots() - : obj->as().numDynamicSlots(); + uint32_t newNumDynamicSlots = obj->as().numDynamicSlots(); if (NativeObject::dynamicSlotsCount(oldShape) != newNumDynamicSlots) { AllocatableRegisterSet regs(RegisterSet::Volatile()); LiveRegisterSet save(regs.asLiveSet()); @@ -2913,12 +2869,6 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att Register temp1 = regs.takeAnyGeneral(); Register temp2 = regs.takeAnyGeneral(); - if (obj->is()) { - // Pass the expando object to the stub. - masm.Push(object); - masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), object); - } - masm.setupUnalignedABICall(temp1); masm.loadJSContext(temp1); masm.passABIArg(temp1); @@ -2935,27 +2885,16 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att masm.jump(&allocDone); masm.bind(&allocFailed); - if (obj->is()) - masm.Pop(object); masm.PopRegsInMask(save); masm.jump(failures); masm.bind(&allocDone); masm.setFramePushed(framePushedAfterCall); - if (obj->is()) - masm.Pop(object); masm.PopRegsInMask(save); } bool popObject = false; - if (obj->is()) { - masm.push(object); - popObject = true; - obj = obj->as().maybeExpando(); - masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), object); - } - // Write the object or expando object's new shape. Address shapeAddr(object, ShapedObject::offsetOfShape()); if (cx->zone()->needsIncrementalBarrier()) @@ -2963,8 +2902,6 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att masm.storePtr(ImmGCPtr(newShape), shapeAddr); if (oldGroup != obj->group()) { - MOZ_ASSERT(!obj->is()); - // Changing object's group from a partially to fully initialized group, // per the acquired properties analysis. Only change the group if the // old group still has a newScript. diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index 3edc6de8b..793b631df 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -30,7 +30,6 @@ #include "vm/Interpreter-inl.h" #include "vm/NativeObject-inl.h" -#include "vm/UnboxedObject-inl.h" using namespace js; using namespace js::jit; diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp index 313957462..05a95824f 100644 --- a/js/src/jit/SharedIC.cpp +++ b/js/src/jit/SharedIC.cpp @@ -2244,8 +2244,7 @@ IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy) if (!isDOMProxy && !obj->isNative()) { if (obj == holder) return false; - if (!obj->is() && - !obj->is()) + if (!obj->is()) { return false; } @@ -2573,9 +2572,6 @@ CheckHasNoSuchProperty(JSContext* cx, JSObject* obj, PropertyName* name, } else if (curObj != obj) { // Non-native objects are only handled as the original receiver. return false; - } else if (curObj->is()) { - if (curObj->as().containsUnboxedOrExpandoProperty(cx, NameToId(name))) - return false; } else if (curObj->is()) { if (curObj->as().typeDescr().hasProperty(cx->names(), NameToId(name))) return false; @@ -2840,34 +2836,15 @@ GuardReceiverObject(MacroAssembler& masm, ReceiverGuard guard, { Address groupAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfGroup()); Address shapeAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfShape()); - Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando()); if (guard.group) { masm.loadPtr(groupAddress, scratch); masm.branchTestObjGroup(Assembler::NotEqual, object, scratch, failure); - - if (guard.group->clasp() == &UnboxedPlainObject::class_ && !guard.shape) { - // Guard the unboxed object has no expando object. - masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure); - } } if (guard.shape) { masm.loadPtr(shapeAddress, scratch); - if (guard.group && guard.group->clasp() == &UnboxedPlainObject::class_) { - // Guard the unboxed object has a matching expando object. - masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure); - Label done; - masm.push(object); - masm.loadPtr(expandoAddress, object); - masm.branchTestObjShape(Assembler::Equal, object, scratch, &done); - masm.pop(object); - masm.jump(failure); - masm.bind(&done); - masm.pop(object); - } else { - masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); - } + masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure); } } @@ -4251,8 +4228,7 @@ DoNewObject(JSContext* cx, void* payload, ICNewObject_Fallback* stub, MutableHan return false; if (!stub->invalid() && - (templateObject->is() || - !templateObject->as().hasDynamicSlots())) + !templateObject->as().hasDynamicSlots()) { JitCode* code = GenerateNewObjectWithTemplateCode(cx, templateObject); if (!code) -- cgit v1.2.3 From 1cf7e63d993b0f41aecc3af7e0cd759c8b067df4 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 25 Jun 2019 20:13:11 +0000 Subject: Remove Unboxed Objects Option Code --- js/src/jit/JitOptions.cpp | 3 --- js/src/jit/JitOptions.h | 3 --- 2 files changed, 6 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp index b9a7c7b27..3f9d9db88 100644 --- a/js/src/jit/JitOptions.cpp +++ b/js/src/jit/JitOptions.cpp @@ -221,9 +221,6 @@ DefaultJitOptions::DefaultJitOptions() Warn(forcedRegisterAllocatorEnv, env); } - // Toggles whether unboxed plain objects can be created by the VM. - SET_DEFAULT(disableUnboxedObjects, true); - // Test whether Atomics are allowed in asm.js code. SET_DEFAULT(asmJSAtomicsEnable, false); diff --git a/js/src/jit/JitOptions.h b/js/src/jit/JitOptions.h index 076980b4e..719ee14d9 100644 --- a/js/src/jit/JitOptions.h +++ b/js/src/jit/JitOptions.h @@ -91,9 +91,6 @@ struct DefaultJitOptions mozilla::Maybe forcedDefaultIonSmallFunctionWarmUpThreshold; mozilla::Maybe forcedRegisterAllocator; - // The options below affect the rest of the VM, and not just the JIT. - bool disableUnboxedObjects; - DefaultJitOptions(); bool isSmallFunction(JSScript* script) const; void setEagerCompilation(); -- cgit v1.2.3 From 636901a4f56c0039fc922debbc48920b19ec0a71 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Tue, 25 Jun 2019 20:24:34 +0000 Subject: Remove UnboxedObjects ObjectGroup addendum --- js/src/jit/MacroAssembler.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index bc04e85cf..a739b9325 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -126,20 +126,14 @@ MacroAssembler::guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Regi { // Type set guards might miss when an object's group changes. In this case // either its old group's properties will become unknown, or it will change - // to a native object with an original unboxed group. Jump to label if this - // might have happened for the input object. + // to a native object. Jump to label if this might have happened for the + // input object. if (types->unknownObject()) { jump(label); return; } - loadPtr(Address(obj, JSObject::offsetOfGroup()), scratch); - load32(Address(scratch, ObjectGroup::offsetOfFlags()), scratch); - and32(Imm32(OBJECT_FLAG_ADDENDUM_MASK), scratch); - branch32(Assembler::Equal, - scratch, Imm32(ObjectGroup::addendumOriginalUnboxedGroupValue()), label); - for (size_t i = 0; i < types->getObjectCount(); i++) { if (JSObject* singleton = types->getSingletonNoBarrier(i)) { movePtr(ImmGCPtr(singleton), scratch); -- cgit v1.2.3 From 3264f3b73802f016777d090d0372749356f3a291 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 26 Jun 2019 09:19:13 +0000 Subject: Remove now-unused parameter (prev. used for unboxed objects). --- js/src/jit/CodeGenerator.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index a276ab9af..fcb711237 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3028,7 +3028,7 @@ CodeGenerator::visitStoreSlotV(LStoreSlotV* lir) static void GuardReceiver(MacroAssembler& masm, const ReceiverGuard& guard, - Register obj, Register scratch, Label* miss, bool checkNullExpando) + Register obj, Register scratch, Label* miss) { if (guard.group) { masm.branchTestObjGroup(Assembler::NotEqual, obj, guard.group, miss); @@ -3050,13 +3050,11 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction* ins, Register obj, Regis Label next; masm.comment("GuardReceiver"); - GuardReceiver(masm, receiver, obj, scratch, &next, /* checkNullExpando = */ false); + GuardReceiver(masm, receiver, obj, scratch, &next); if (receiver.shape) { masm.comment("loadTypedOrValue"); - // If this is an unboxed expando access, GuardReceiver loaded the - // expando object into scratch. - Register target = receiver.group ? scratch : obj; + Register target = obj; Shape* shape = mir->shape(i); if (shape->slot() < shape->numFixedSlots()) { @@ -3122,12 +3120,10 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction* ins, Register obj, Regis ReceiverGuard receiver = mir->receiver(i); Label next; - GuardReceiver(masm, receiver, obj, scratch, &next, /* checkNullExpando = */ false); + GuardReceiver(masm, receiver, obj, scratch, &next); if (receiver.shape) { - // If this is an unboxed expando access, GuardReceiver loaded the - // expando object into scratch. - Register target = receiver.group ? scratch : obj; + Register target = obj; Shape* shape = mir->shape(i); if (shape->slot() < shape->numFixedSlots()) { @@ -3293,7 +3289,7 @@ CodeGenerator::visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir) const ReceiverGuard& receiver = mir->receiver(i); Label next; - GuardReceiver(masm, receiver, obj, temp, &next, /* checkNullExpando = */ true); + GuardReceiver(masm, receiver, obj, temp, &next); if (i == mir->numReceivers() - 1) { bailoutFrom(&next, lir->snapshot()); -- cgit v1.2.3 From 06bf5d769f33d72441825fa39e00baf9eaaac179 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Wed, 26 Jun 2019 11:44:03 +0000 Subject: Clean up MObjectState --- js/src/jit/MIR.cpp | 9 +++------ js/src/jit/MIR.h | 23 +++-------------------- js/src/jit/ScalarReplacement.cpp | 33 --------------------------------- 3 files changed, 6 insertions(+), 59 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 190b40bb2..fa9cc3019 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -4817,15 +4817,14 @@ MCreateThisWithTemplate::canRecoverOnBailout() const MObjectState::MObjectState(MObjectState* state) : numSlots_(state->numSlots_), - numFixedSlots_(state->numFixedSlots_), - operandIndex_(state->operandIndex_) + numFixedSlots_(state->numFixedSlots_) { // This instruction is only used as a summary for bailout paths. setResultType(MIRType::Object); setRecoveredOnBailout(); } -MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandIndex) +MObjectState::MObjectState(JSObject* templateObject) { // This instruction is only used as a summary for bailout paths. setResultType(MIRType::Object); @@ -4836,8 +4835,6 @@ MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandInd NativeObject* nativeObject = &templateObject->as(); numSlots_ = nativeObject->slotSpan(); numFixedSlots_ = nativeObject->numFixedSlots(); - - operandIndex_ = operandIndex; } JSObject* @@ -4897,7 +4894,7 @@ MObjectState::New(TempAllocator& alloc, MDefinition* obj) JSObject* templateObject = templateObjectOf(obj); MOZ_ASSERT(templateObject, "Unexpected object creation."); - MObjectState* res = new(alloc) MObjectState(templateObject, nullptr); + MObjectState* res = new(alloc) MObjectState(templateObject); if (!res || !res->init(alloc, obj)) return nullptr; return res; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 6526e0931..0992768bf 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -375,7 +375,7 @@ class AliasSet { Element = 1 << 1, // A Value member of obj->elements or // a typed object. UnboxedElement = 1 << 2, // An unboxed scalar or reference member of - // typed object or unboxed object. + // typed object. DynamicSlot = 1 << 3, // A Value member of obj->slots. FixedSlot = 1 << 4, // A Value member of obj->fixedSlots(). DOMProperty = 1 << 5, // A DOM property @@ -3758,14 +3758,9 @@ class MObjectState { private: uint32_t numSlots_; - uint32_t numFixedSlots_; // valid if isUnboxed() == false. - OperandIndexMap* operandIndex_; // valid if isUnboxed() == true. + uint32_t numFixedSlots_; - bool isUnboxed() const { - return operandIndex_ != nullptr; - } - - MObjectState(JSObject *templateObject, OperandIndexMap* operandIndex); + MObjectState(JSObject *templateObject); explicit MObjectState(MObjectState* state); MOZ_MUST_USE bool init(TempAllocator& alloc, MDefinition* obj); @@ -3826,18 +3821,6 @@ class MObjectState setSlot(slot + numFixedSlots(), def); } - // Interface reserved for unboxed objects. - bool hasOffset(uint32_t offset) const { - MOZ_ASSERT(isUnboxed()); - return offset < operandIndex_->map.length() && operandIndex_->map[offset] != 0; - } - MDefinition* getOffset(uint32_t offset) const { - return getOperand(operandIndex_->map[offset]); - } - void setOffset(uint32_t offset, MDefinition* def) { - replaceOperand(operandIndex_->map[offset], def); - } - MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override; bool canRecoverOnBailout() const override { return true; diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index be9ceee2e..97ba52349 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -285,10 +285,6 @@ class ObjectMemoryView : public MDefinitionVisitorDefaultNoop void visitGuardShape(MGuardShape* ins); void visitFunctionEnvironment(MFunctionEnvironment* ins); void visitLambda(MLambda* ins); - - private: - void storeOffset(MInstruction* ins, size_t offset, MDefinition* value); - void loadOffset(MInstruction* ins, size_t offset); }; const char* ObjectMemoryView::phaseName = "Scalar Replacement of Object"; @@ -630,35 +626,6 @@ ObjectMemoryView::visitLambda(MLambda* ins) ins->setIncompleteObject(); } -void -ObjectMemoryView::storeOffset(MInstruction* ins, size_t offset, MDefinition* value) -{ - // Clone the state and update the slot value. - MOZ_ASSERT(state_->hasOffset(offset)); - state_ = BlockState::Copy(alloc_, state_); - if (!state_) { - oom_ = true; - return; - } - - state_->setOffset(offset, value); - ins->block()->insertBefore(ins, state_); - - // Remove original instruction. - ins->block()->discard(ins); -} - -void -ObjectMemoryView::loadOffset(MInstruction* ins, size_t offset) -{ - // Replace load by the slot value. - MOZ_ASSERT(state_->hasOffset(offset)); - ins->replaceAllUsesWith(state_->getOffset(offset)); - - // Remove original instruction. - ins->block()->discard(ins); -} - static bool IndexOf(MDefinition* ins, int32_t* res) { -- cgit v1.2.3 From 01e1fcf522219bf1b2d7d2dcc6209db3d270a182 Mon Sep 17 00:00:00 2001 From: g4jc Date: Fri, 28 Jun 2019 21:35:05 -0400 Subject: Issue #1142 - Remove uneeded assertion (#1145) Since unboxed objects were removed, isUnboxed is undefined. This causes a build failure when debuging is enabled. This patch fixes the issue by removing the uneeeded assertion. --- js/src/jit/MIR.h | 1 - 1 file changed, 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 0992768bf..9076339f1 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -3785,7 +3785,6 @@ class MObjectState MOZ_MUST_USE bool initFromTemplateObject(TempAllocator& alloc, MDefinition* undefinedVal); size_t numFixedSlots() const { - MOZ_ASSERT(!isUnboxed()); return numFixedSlots_; } size_t numSlots() const { -- cgit v1.2.3 From 35d29c05c59057fc84be41ec94f2e3bc31ddef44 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Fri, 28 Jun 2019 23:02:15 -0400 Subject: Issue #1142 - Cleanup unused debug code for unboxed objects Also fixes an assertion during compile if debug is enabled since unboxed objects have been removed. --- js/src/jit/BaselineIC.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index d95d08edc..2f20ffa4f 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -289,7 +289,7 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H case ICStub::SetProp_Native: case ICStub::SetProp_NativeAdd: case ICStub::SetProp_Unboxed: { - MOZ_ASSERT(obj->isNative() || obj->is()); + MOZ_ASSERT(obj->isNative()); jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(script); if (*pc == JSOP_SETALIASEDVAR || *pc == JSOP_INITALIASEDLEXICAL) id = NameToId(EnvironmentCoordinateName(cx->caches.envCoordinateNameCache, script, pc)); -- cgit v1.2.3 From 739a81958035410ddd9b230354a56c909cc5c816 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 18:54:17 -0400 Subject: 1320408 - Part 2: Change JSFunction::getOrCreateScript to static method. --- js/src/jit/IonAnalysis.cpp | 4 ++-- js/src/jit/IonAnalysis.h | 2 +- js/src/jit/IonBuilder.cpp | 3 ++- js/src/jit/VMFunctions.cpp | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 41c71c9c3..90fa1864a 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -4132,7 +4132,7 @@ CmpInstructions(const void* a, const void* b) } bool -jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun, +jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, ObjectGroup* group, HandlePlainObject baseobj, Vector* initializerList) { @@ -4142,7 +4142,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun, // which will definitely be added to the created object before it has a // chance to escape and be accessed elsewhere. - RootedScript script(cx, fun->getOrCreateScript(cx)); + RootedScript script(cx, JSFunction::getOrCreateScript(cx, fun)); if (!script) return false; diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h index 1ce8edc80..efd31415b 100644 --- a/js/src/jit/IonAnalysis.h +++ b/js/src/jit/IonAnalysis.h @@ -196,7 +196,7 @@ MCompare* ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum); MOZ_MUST_USE bool -AnalyzeNewScriptDefiniteProperties(JSContext* cx, JSFunction* fun, +AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, ObjectGroup* group, HandlePlainObject baseobj, Vector* initializerList); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index a54a58add..e98a4056e 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -466,7 +466,8 @@ IonBuilder::canInlineTarget(JSFunction* target, CallInfo& callInfo) // Allow constructing lazy scripts when performing the definite properties // analysis, as baseline has not been used to warm the caller up yet. if (target->isInterpreted() && info().analysisMode() == Analysis_DefiniteProperties) { - RootedScript script(analysisContext, target->getOrCreateScript(analysisContext)); + RootedFunction fun(analysisContext, target); + RootedScript script(analysisContext, JSFunction::getOrCreateScript(analysisContext, fun)); if (!script) return InliningDecision_Error; diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 402d910b9..5bcd36ba0 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -555,7 +555,7 @@ CreateThis(JSContext* cx, HandleObject callee, HandleObject newTarget, MutableHa if (callee->is()) { RootedFunction fun(cx, &callee->as()); if (fun->isInterpreted() && fun->isConstructor()) { - JSScript* script = fun->getOrCreateScript(cx); + JSScript* script = JSFunction::getOrCreateScript(cx, fun); if (!script || !script->ensureHasTypes(cx)) return false; if (fun->isBoundFunction() || script->isDerivedClassConstructor()) { -- cgit v1.2.3 From af6768fb1f2e44b0bfe4136c79d8031028d073b1 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 19:20:00 -0400 Subject: 1320408 - Part 4: Change JSObject::getGroup to static method. --- js/src/jit/BaselineIC.cpp | 23 ++++++++++++++--------- js/src/jit/BaselineIC.h | 2 +- js/src/jit/IonCaches.cpp | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 2f20ffa4f..506cbf1d2 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -2253,14 +2253,20 @@ DenseOrUnboxedArraySetElemStubExists(JSContext* cx, ICStub::Kind kind, for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) { if (kind == ICStub::SetElem_DenseOrUnboxedArray && iter->isSetElem_DenseOrUnboxedArray()) { ICSetElem_DenseOrUnboxedArray* nstub = iter->toSetElem_DenseOrUnboxedArray(); - if (obj->maybeShape() == nstub->shape() && obj->getGroup(cx) == nstub->group()) + if (obj->maybeShape() == nstub->shape() && + JSObject::getGroup(cx, obj) == nstub->group()) + { return true; + } } if (kind == ICStub::SetElem_DenseOrUnboxedArrayAdd && iter->isSetElem_DenseOrUnboxedArrayAdd()) { ICSetElem_DenseOrUnboxedArrayAdd* nstub = iter->toSetElem_DenseOrUnboxedArrayAdd(); - if (obj->getGroup(cx) == nstub->group() && SetElemAddHasSameShapes(nstub, obj)) + if (JSObject::getGroup(cx, obj) == nstub->group() && + SetElemAddHasSameShapes(nstub, obj)) + { return true; + } } } return false; @@ -2446,7 +2452,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_ &addingCase, &protoDepth)) { RootedShape shape(cx, obj->maybeShape()); - RootedObjectGroup group(cx, obj->getGroup(cx)); + RootedObjectGroup group(cx, JSObject::getGroup(cx, obj)); if (!group) return false; @@ -4277,7 +4283,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_ if (!obj) return false; RootedShape oldShape(cx, obj->maybeShape()); - RootedObjectGroup oldGroup(cx, obj->getGroup(cx)); + RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj)); if (!oldGroup) return false; RootedReceiverGuard oldGuard(cx, ReceiverGuard(obj)); @@ -5175,14 +5181,13 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& if (native == js::array_slice) { if (args.thisv().isObject()) { - JSObject* obj = &args.thisv().toObject(); + RootedObject obj(cx, &args.thisv().toObject()); if (!obj->isSingleton()) { if (obj->group()->maybePreliminaryObjects()) { *skipAttach = true; return true; } - res.set(NewFullyAllocatedArrayTryReuseGroup(cx, &args.thisv().toObject(), 0, - TenuredObject)); + res.set(NewFullyAllocatedArrayTryReuseGroup(cx, obj, 0, TenuredObject)); return !!res; } } @@ -7961,7 +7966,7 @@ ICUpdatedStub* ICSetElemDenseOrUnboxedArrayAddCompiler::getStubSpecific(ICStubSpace* space, Handle shapes) { - RootedObjectGroup group(cx, obj_->getGroup(cx)); + RootedObjectGroup group(cx, JSObject::getGroup(cx, obj_)); if (!group) return nullptr; Rooted stubCode(cx, getStubCode()); @@ -8098,7 +8103,7 @@ ICSetProp_Native::ICSetProp_Native(JitCode* stubCode, ObjectGroup* group, Shape* ICSetProp_Native* ICSetProp_Native::Compiler::getStub(ICStubSpace* space) { - RootedObjectGroup group(cx, obj_->getGroup(cx)); + RootedObjectGroup group(cx, JSObject::getGroup(cx, obj_)); if (!group) return nullptr; diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 98f0e1c59..9941cc93d 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -1940,7 +1940,7 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler template ICUpdatedStub* getStubSpecific(ICStubSpace* space, Handle shapes) { - RootedObjectGroup newGroup(cx, obj_->getGroup(cx)); + RootedObjectGroup newGroup(cx, JSObject::getGroup(cx, obj_)); if (!newGroup) return nullptr; diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 9901bdd07..48e0792bb 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3316,7 +3316,7 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex RootedObjectGroup oldGroup(cx); RootedShape oldShape(cx); if (cache.canAttachStub()) { - oldGroup = obj->getGroup(cx); + oldGroup = JSObject::getGroup(cx, obj); if (!oldGroup) return false; -- cgit v1.2.3 From 93335c3120968fac165a95978ef0dbdffe7900b4 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 21:10:15 -0400 Subject: 1320408 - Part 12: Change JSScript::sourceData to static method. --- js/src/jit/BaselineJIT.cpp | 2 +- js/src/jit/Ion.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index d0e297c2d..5c21926b5 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -273,7 +273,7 @@ jit::BaselineCompile(JSContext* cx, JSScript* script, bool forceDebugInstrumenta MOZ_ASSERT(script->canBaselineCompile()); MOZ_ASSERT(IsBaselineEnabled(cx)); - script->ensureNonLazyCanonicalFunction(cx); + script->ensureNonLazyCanonicalFunction(); LifoAlloc alloc(TempAllocator::PreferredLifoChunkSize); TempAllocator* temp = alloc.new_(&alloc); diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index c61b414e0..b8a2d2fba 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -2153,7 +2153,7 @@ IonCompile(JSContext* cx, JSScript* script, // Make sure the script's canonical function isn't lazy. We can't de-lazify // it in a helper thread. - script->ensureNonLazyCanonicalFunction(cx); + script->ensureNonLazyCanonicalFunction(); TrackPropertiesForSingletonScopes(cx, script, baselineFrame); -- cgit v1.2.3 From 3a5176f4b25a2b90cefe14eb2c2de57113dc21ac Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 23:28:04 -0400 Subject: 1320408 - Part 14: Change some GlobalObject methods to static method. --- js/src/jit/CodeGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index fcb711237..573993d5e 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -1053,7 +1053,7 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re Address pairsVectorAddress(masm.getStackPointer(), pairsVectorStartOffset); - RegExpStatics* res = cx->global()->getRegExpStatics(cx); + RegExpStatics* res = GlobalObject::getRegExpStatics(cx, cx->global()); if (!res) return false; #ifdef JS_USE_LINK_REGISTER -- cgit v1.2.3 From caf39feeeb457ffb143110826a0220211c00afb6 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 23:29:58 -0400 Subject: 1320408 - Part 15: Change NativeObject::addDataProperty to static method. --- js/src/jit/IonAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 90fa1864a..5fc624fb1 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -4055,7 +4055,7 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, // Add the property to the object, being careful not to update type information. DebugOnly slotSpan = baseobj->slotSpan(); MOZ_ASSERT(!baseobj->containsPure(id)); - if (!baseobj->addDataProperty(cx, id, baseobj->slotSpan(), JSPROP_ENUMERATE)) + if (!NativeObject::addDataProperty(cx, baseobj, id, baseobj->slotSpan(), JSPROP_ENUMERATE)) return false; MOZ_ASSERT(baseobj->slotSpan() != slotSpan); MOZ_ASSERT(!baseobj->inDictionaryMode()); -- cgit v1.2.3 From 449ea84dcc7dffb2f042fc414eb7238ae842d596 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 14 Jul 2019 19:04:34 -0400 Subject: 1344477 - Part 1: Add JSOP_CALL_IGNORES_RV for function call that ignores return value. --- js/src/jit/BaselineCompiler.cpp | 6 ++++++ js/src/jit/BaselineCompiler.h | 1 + js/src/jit/BaselineIC.cpp | 24 +++++++++++++++++---- js/src/jit/BaselineIC.h | 10 ++++++--- js/src/jit/CodeGenerator.cpp | 26 ++++++++++++++++------ js/src/jit/CodeGenerator.h | 4 ++-- js/src/jit/IonBuilder.cpp | 48 +++++++++++++++++++++++++---------------- js/src/jit/IonBuilder.h | 17 ++++++++++++--- js/src/jit/MIR.cpp | 4 ++-- js/src/jit/MIR.h | 21 ++++++++++++------ js/src/jit/VMFunctions.cpp | 8 +++---- js/src/jit/VMFunctions.h | 4 ++-- js/src/jit/shared/LIR-shared.h | 3 +++ 13 files changed, 125 insertions(+), 51 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 6b64bfb44..b2f9d3b23 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -3291,6 +3291,12 @@ BaselineCompiler::emit_JSOP_CALL() return emitCall(); } +bool +BaselineCompiler::emit_JSOP_CALL_IGNORES_RV() +{ + return emitCall(); +} + bool BaselineCompiler::emit_JSOP_CALLITER() { diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 910a52980..95e0c77ad 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -159,6 +159,7 @@ namespace jit { _(JSOP_INITALIASEDLEXICAL) \ _(JSOP_UNINITIALIZED) \ _(JSOP_CALL) \ + _(JSOP_CALL_IGNORES_RV) \ _(JSOP_CALLITER) \ _(JSOP_FUNCALL) \ _(JSOP_FUNAPPLY) \ diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 506cbf1d2..8a7c68e59 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -10,6 +10,8 @@ #include "mozilla/SizePrintfMacros.h" #include "mozilla/TemplateLib.h" +#include "jsfriendapi.h" +#include "jsfun.h" #include "jslibmath.h" #include "jstypes.h" @@ -5494,11 +5496,17 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb MOZ_ASSERT_IF(templateObject, !templateObject->group()->maybePreliminaryObjects()); } + bool ignoresReturnValue = false; + if (op == JSOP_CALL_IGNORES_RV && fun->isNative()) { + const JSJitInfo* jitInfo = fun->jitInfo(); + ignoresReturnValue = jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative; + } + JitSpew(JitSpew_BaselineIC, " Generating Call_Native stub (fun=%p, cons=%s, spread=%s)", fun.get(), constructing ? "yes" : "no", isSpread ? "yes" : "no"); ICCall_Native::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(), - fun, templateObject, constructing, isSpread, - script->pcToOffset(pc)); + fun, templateObject, constructing, ignoresReturnValue, + isSpread, script->pcToOffset(pc)); ICStub* newStub = compiler.getStub(compiler.getStubSpace(script)); if (!newStub) return false; @@ -5601,12 +5609,14 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint MOZ_ASSERT(argc == GET_ARGC(pc)); bool constructing = (op == JSOP_NEW); + bool ignoresReturnValue = (op == JSOP_CALL_IGNORES_RV); // Ensure vp array is rooted - we may GC in here. size_t numValues = argc + 2 + constructing; AutoArrayRooter vpRoot(cx, numValues, vp); - CallArgs callArgs = CallArgsFromSp(argc + constructing, vp + numValues, constructing); + CallArgs callArgs = CallArgsFromSp(argc + constructing, vp + numValues, constructing, + ignoresReturnValue); RootedValue callee(cx, vp[0]); // Handle funapply with JSOP_ARGUMENTS @@ -5636,6 +5646,7 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint return false; } else { MOZ_ASSERT(op == JSOP_CALL || + op == JSOP_CALL_IGNORES_RV || op == JSOP_CALLITER || op == JSOP_FUNCALL || op == JSOP_FUNAPPLY || @@ -6686,7 +6697,12 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm) // stub and use that instead of the original one. masm.callWithABI(Address(ICStubReg, ICCall_Native::offsetOfNative())); #else - masm.callWithABI(Address(callee, JSFunction::offsetOfNativeOrScript())); + if (ignoresReturnValue_) { + masm.loadPtr(Address(callee, JSFunction::offsetOfJitInfo()), callee); + masm.callWithABI(Address(callee, JSJitInfo::offsetOfIgnoresReturnValueNative())); + } else { + masm.callWithABI(Address(callee, JSFunction::offsetOfNativeOrScript())); + } #endif // Test for failure. diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index 9941cc93d..e1ad12559 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -2277,6 +2277,7 @@ class ICSetProp_CallNative : public ICSetPropCallSetter // Call // JSOP_CALL +// JSOP_CALL_IGNORES_RV // JSOP_FUNAPPLY // JSOP_FUNCALL // JSOP_NEW @@ -2547,6 +2548,7 @@ class ICCall_Native : public ICMonitoredStub protected: ICStub* firstMonitorStub_; bool isConstructing_; + bool ignoresReturnValue_; bool isSpread_; RootedFunction callee_; RootedObject templateObject_; @@ -2556,17 +2558,19 @@ class ICCall_Native : public ICMonitoredStub virtual int32_t getKey() const { return static_cast(engine_) | (static_cast(kind) << 1) | - (static_cast(isConstructing_) << 17) | - (static_cast(isSpread_) << 18); + (static_cast(isSpread_) << 17) | + (static_cast(isConstructing_) << 18) | + (static_cast(ignoresReturnValue_) << 19); } public: Compiler(JSContext* cx, ICStub* firstMonitorStub, HandleFunction callee, HandleObject templateObject, - bool isConstructing, bool isSpread, uint32_t pcOffset) + bool isConstructing, bool ignoresReturnValue, bool isSpread, uint32_t pcOffset) : ICCallStubCompiler(cx, ICStub::Call_Native), firstMonitorStub_(firstMonitorStub), isConstructing_(isConstructing), + ignoresReturnValue_(ignoresReturnValue), isSpread_(isSpread), callee_(cx, callee), templateObject_(cx, templateObject), diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 573993d5e..114fc96b3 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -3688,7 +3688,13 @@ CodeGenerator::visitCallNative(LCallNative* call) masm.passABIArg(argContextReg); masm.passABIArg(argUintNReg); masm.passABIArg(argVpReg); - masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, target->native())); + JSNative native = target->native(); + if (call->ignoresReturnValue()) { + const JSJitInfo* jitInfo = target->jitInfo(); + if (jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative) + native = jitInfo->ignoresReturnValueMethod; + } + masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, native)); emitTracelogStopEvent(TraceLogger_Call); @@ -3845,13 +3851,15 @@ CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue* lir) callVM(GetIntrinsicValueInfo, lir); } -typedef bool (*InvokeFunctionFn)(JSContext*, HandleObject, bool, uint32_t, Value*, MutableHandleValue); +typedef bool (*InvokeFunctionFn)(JSContext*, HandleObject, bool, bool, uint32_t, Value*, + MutableHandleValue); static const VMFunction InvokeFunctionInfo = FunctionInfo(InvokeFunction, "InvokeFunction"); void CodeGenerator::emitCallInvokeFunction(LInstruction* call, Register calleereg, - bool constructing, uint32_t argc, uint32_t unusedStack) + bool constructing, bool ignoresReturnValue, + uint32_t argc, uint32_t unusedStack) { // Nestle %esp up to the argument vector. // Each path must account for framePushed_ separately, for callVM to be valid. @@ -3859,6 +3867,7 @@ CodeGenerator::emitCallInvokeFunction(LInstruction* call, Register calleereg, pushArg(masm.getStackPointer()); // argv. pushArg(Imm32(argc)); // argc. + pushArg(Imm32(ignoresReturnValue)); pushArg(Imm32(constructing)); // constructing. pushArg(calleereg); // JSFunction*. @@ -3945,8 +3954,8 @@ CodeGenerator::visitCallGeneric(LCallGeneric* call) // Handle uncompiled or native functions. masm.bind(&invoke); - emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->numActualArgs(), - unusedStack); + emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->ignoresReturnValue(), + call->numActualArgs(), unusedStack); masm.bind(&end); @@ -4001,7 +4010,8 @@ CodeGenerator::visitCallKnown(LCallKnown* call) masm.checkStackAlignment(); if (target->isClassConstructor() && !call->isConstructing()) { - emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->numActualArgs(), unusedStack); + emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->ignoresReturnValue(), + call->numActualArgs(), unusedStack); return; } @@ -4045,7 +4055,8 @@ CodeGenerator::visitCallKnown(LCallKnown* call) if (call->isConstructing() && target->nargs() > call->numActualArgs()) emitCallInvokeFunctionShuffleNewTarget(call, calleereg, target->nargs(), unusedStack); else - emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->numActualArgs(), unusedStack); + emitCallInvokeFunction(call, calleereg, call->isConstructing(), call->ignoresReturnValue(), + call->numActualArgs(), unusedStack); masm.bind(&end); @@ -4072,6 +4083,7 @@ CodeGenerator::emitCallInvokeFunction(T* apply, Register extraStackSize) pushArg(objreg); // argv. pushArg(ToRegister(apply->getArgc())); // argc. + pushArg(Imm32(false)); // ignoresReturnValue. pushArg(Imm32(false)); // isConstrucing. pushArg(ToRegister(apply->getFunction())); // JSFunction*. diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index b5f170d84..1c9a7e89b 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -165,8 +165,8 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitOutOfLineCallPostWriteElementBarrier(OutOfLineCallPostWriteElementBarrier* ool); void visitCallNative(LCallNative* call); void emitCallInvokeFunction(LInstruction* call, Register callereg, - bool isConstructing, uint32_t argc, - uint32_t unusedStack); + bool isConstructing, bool ignoresReturnValue, + uint32_t argc, uint32_t unusedStack); void visitCallGeneric(LCallGeneric* call); void emitCallInvokeFunctionShuffleNewTarget(LCallKnown *call, Register calleeReg, diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index e98a4056e..2d053de5a 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1939,6 +1939,7 @@ IonBuilder::inspectOpcode(JSOp op) return jsop_funapply(GET_ARGC(pc)); case JSOP_CALL: + case JSOP_CALL_IGNORES_RV: case JSOP_CALLITER: case JSOP_NEW: case JSOP_SUPERCALL: @@ -1946,7 +1947,8 @@ IonBuilder::inspectOpcode(JSOp op) if (!outermostBuilder()->iterators_.append(current->peek(-1))) return false; } - return jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL); + return jsop_call(GET_ARGC(pc), (JSOp)*pc == JSOP_NEW || (JSOp)*pc == JSOP_SUPERCALL, + (JSOp)*pc == JSOP_CALL_IGNORES_RV); case JSOP_EVAL: case JSOP_STRICTEVAL: @@ -5874,7 +5876,7 @@ IonBuilder::inlineGenericFallback(JSFunction* target, CallInfo& callInfo, MBasic return false; // Create a new CallInfo to track modified state within this block. - CallInfo fallbackInfo(alloc(), callInfo.constructing()); + CallInfo fallbackInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue()); if (!fallbackInfo.init(callInfo)) return false; fallbackInfo.popFormals(fallbackBlock); @@ -5913,7 +5915,7 @@ IonBuilder::inlineObjectGroupFallback(CallInfo& callInfo, MBasicBlock* dispatchB MOZ_ASSERT(cache->idempotent()); // Create a new CallInfo to track modified state within the fallback path. - CallInfo fallbackInfo(alloc(), callInfo.constructing()); + CallInfo fallbackInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue()); if (!fallbackInfo.init(callInfo)) return false; @@ -6089,7 +6091,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const ObjectVector& targets, BoolVec inlineBlock->rewriteSlot(funIndex, funcDef); // Create a new CallInfo to track modified state within the inline block. - CallInfo inlineInfo(alloc(), callInfo.constructing()); + CallInfo inlineInfo(alloc(), callInfo.constructing(), callInfo.ignoresReturnValue()); if (!inlineInfo.init(callInfo)) return false; inlineInfo.popFormals(inlineBlock); @@ -6538,7 +6540,8 @@ IonBuilder::jsop_funcall(uint32_t argc) TemporaryTypeSet* calleeTypes = current->peek(calleeDepth)->resultTypeSet(); JSFunction* native = getSingleCallTarget(calleeTypes); if (!native || !native->isNative() || native->native() != &fun_call) { - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, argc)) return false; return makeCall(native, callInfo); @@ -6563,7 +6566,8 @@ IonBuilder::jsop_funcall(uint32_t argc) argc -= 1; } - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, argc)) return false; @@ -6600,7 +6604,8 @@ IonBuilder::jsop_funapply(uint32_t argc) TemporaryTypeSet* calleeTypes = current->peek(calleeDepth)->resultTypeSet(); JSFunction* native = getSingleCallTarget(calleeTypes); if (argc != 2 || info().analysisMode() == Analysis_ArgumentsUsage) { - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, argc)) return false; return makeCall(native, callInfo); @@ -6629,7 +6634,8 @@ IonBuilder::jsop_funapply(uint32_t argc) return jsop_funapplyarray(argc); } - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, argc)) return false; return makeCall(native, callInfo); @@ -6738,7 +6744,8 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc) // can inline the apply() target and don't care about the actual arguments // that were passed in. - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); // Vp MDefinition* vp = current->pop(); @@ -6784,7 +6791,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc) } bool -IonBuilder::jsop_call(uint32_t argc, bool constructing) +IonBuilder::jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue) { startTrackingOptimizations(); @@ -6810,7 +6817,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing) if (calleeTypes && !getPolyCallTargets(calleeTypes, constructing, targets, 4)) return false; - CallInfo callInfo(alloc(), constructing); + CallInfo callInfo(alloc(), constructing, ignoresReturnValue); if (!callInfo.init(current, argc)) return false; @@ -6946,7 +6953,8 @@ IonBuilder::makeCallHelper(JSFunction* target, CallInfo& callInfo) } MCall* call = MCall::New(alloc(), target, targetArgs + 1 + callInfo.constructing(), - callInfo.argc(), callInfo.constructing(), isDOMCall); + callInfo.argc(), callInfo.constructing(), + callInfo.ignoresReturnValue(), isDOMCall); if (!call) return nullptr; @@ -7047,7 +7055,7 @@ IonBuilder::jsop_eval(uint32_t argc) // Emit a normal call if the eval has never executed. This keeps us from // disabling compilation for the script when testing with --ion-eager. if (calleeTypes && calleeTypes->empty()) - return jsop_call(argc, /* constructing = */ false); + return jsop_call(argc, /* constructing = */ false, false); JSFunction* singleton = getSingleCallTarget(calleeTypes); if (!singleton) @@ -7063,7 +7071,8 @@ IonBuilder::jsop_eval(uint32_t argc) if (info().funMaybeLazy()->isArrow()) return abort("Direct eval from arrow function"); - CallInfo callInfo(alloc(), /* constructing = */ false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, argc)) return false; callInfo.setImplicitlyUsedUnchecked(); @@ -7102,7 +7111,8 @@ IonBuilder::jsop_eval(uint32_t argc) current->push(dynamicName); current->push(constant(UndefinedValue())); // thisv - CallInfo evalCallInfo(alloc(), /* constructing = */ false); + CallInfo evalCallInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!evalCallInfo.init(current, /* argc = */ 0)) return false; @@ -7119,7 +7129,7 @@ IonBuilder::jsop_eval(uint32_t argc) return resumeAfter(ins) && pushTypeBarrier(ins, types, BarrierKind::TypeSet); } - return jsop_call(argc, /* constructing = */ false); + return jsop_call(argc, /* constructing = */ false, false); } bool @@ -12001,7 +12011,8 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName current->push(obj); - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, 0)) return false; @@ -12496,7 +12507,8 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj, // Call the setter. Note that we have to push the original value, not // the setter's return value. - CallInfo callInfo(alloc(), false); + CallInfo callInfo(alloc(), /* constructing = */ false, + /* ignoresReturnValue = */ BytecodeIsPopped(pc)); if (!callInfo.init(current, 1)) return false; diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index dd40b4bd6..9e40b3959 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -699,6 +699,7 @@ class IonBuilder MOZ_MUST_USE bool jsop_funapplyarguments(uint32_t argc); MOZ_MUST_USE bool jsop_funapplyarray(uint32_t argc); MOZ_MUST_USE bool jsop_call(uint32_t argc, bool constructing); + MOZ_MUST_USE bool jsop_call(uint32_t argc, bool constructing, bool ignoresReturnValue); MOZ_MUST_USE bool jsop_eval(uint32_t argc); MOZ_MUST_USE bool jsop_ifeq(JSOp op); MOZ_MUST_USE bool jsop_try(); @@ -1352,16 +1353,21 @@ class CallInfo MDefinition* newTargetArg_; MDefinitionVector args_; - bool constructing_; - bool setter_; + bool constructing_:1; + + // True if the caller does not use the return value. + bool ignoresReturnValue_:1; + + bool setter_:1; public: - CallInfo(TempAllocator& alloc, bool constructing) + CallInfo(TempAllocator& alloc, bool constructing, bool ignoresReturnValue) : fun_(nullptr), thisArg_(nullptr), newTargetArg_(nullptr), args_(alloc), constructing_(constructing), + ignoresReturnValue_(ignoresReturnValue), setter_(false) { } @@ -1370,6 +1376,7 @@ class CallInfo fun_ = callInfo.fun(); thisArg_ = callInfo.thisArg(); + ignoresReturnValue_ = callInfo.ignoresReturnValue(); if (constructing()) newTargetArg_ = callInfo.getNewTarget(); @@ -1466,6 +1473,10 @@ class CallInfo return constructing_; } + bool ignoresReturnValue() const { + return ignoresReturnValue_; + } + void setNewTarget(MDefinition* newTarget) { MOZ_ASSERT(constructing()); newTargetArg_ = newTarget; diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index fa9cc3019..10671cfda 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -1970,7 +1970,7 @@ WrappedFunction::WrappedFunction(JSFunction* fun) MCall* MCall::New(TempAllocator& alloc, JSFunction* target, size_t maxArgc, size_t numActualArgs, - bool construct, bool isDOMCall) + bool construct, bool ignoresReturnValue, bool isDOMCall) { WrappedFunction* wrappedTarget = target ? new(alloc) WrappedFunction(target) : nullptr; MOZ_ASSERT(maxArgc >= numActualArgs); @@ -1979,7 +1979,7 @@ MCall::New(TempAllocator& alloc, JSFunction* target, size_t maxArgc, size_t numA MOZ_ASSERT(!construct); ins = new(alloc) MCallDOMNative(wrappedTarget, numActualArgs); } else { - ins = new(alloc) MCall(wrappedTarget, numActualArgs, construct); + ins = new(alloc) MCall(wrappedTarget, numActualArgs, construct, ignoresReturnValue); } if (!ins->init(alloc, maxArgc + NumNonArgumentOperands)) return nullptr; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 9076339f1..ac55b1150 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -4043,14 +4043,18 @@ class MCall uint32_t numActualArgs_; // True if the call is for JSOP_NEW. - bool construct_; + bool construct_:1; - bool needsArgCheck_; + // True if the caller does not use the return value. + bool ignoresReturnValue_:1; - MCall(WrappedFunction* target, uint32_t numActualArgs, bool construct) + bool needsArgCheck_:1; + + MCall(WrappedFunction* target, uint32_t numActualArgs, bool construct, bool ignoresReturnValue) : target_(target), numActualArgs_(numActualArgs), construct_(construct), + ignoresReturnValue_(ignoresReturnValue), needsArgCheck_(true) { setResultType(MIRType::Value); @@ -4059,7 +4063,7 @@ class MCall public: INSTRUCTION_HEADER(Call) static MCall* New(TempAllocator& alloc, JSFunction* target, size_t maxArgc, size_t numActualArgs, - bool construct, bool isDOMCall); + bool construct, bool ignoresReturnValue, bool isDOMCall); void initFunction(MDefinition* func) { initOperand(FunctionOperandIndex, func); @@ -4104,6 +4108,10 @@ class MCall return construct_; } + bool ignoresReturnValue() const { + return ignoresReturnValue_; + } + // The number of stack arguments is the max between the number of formal // arguments and the number of actual arguments. The number of stack // argument includes the |undefined| padding added in case of underflow. @@ -4147,7 +4155,7 @@ class MCallDOMNative : public MCall // virtual things from MCall. protected: MCallDOMNative(WrappedFunction* target, uint32_t numActualArgs) - : MCall(target, numActualArgs, false) + : MCall(target, numActualArgs, false, false) { MOZ_ASSERT(getJitInfo()->type() != JSJitInfo::InlinableNative); @@ -4162,7 +4170,8 @@ class MCallDOMNative : public MCall } friend MCall* MCall::New(TempAllocator& alloc, JSFunction* target, size_t maxArgc, - size_t numActualArgs, bool construct, bool isDOMCall); + size_t numActualArgs, bool construct, bool ignoresReturnValue, + bool isDOMCall); const JSJitInfo* getJitInfo() const; public: diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 5bcd36ba0..e58c3f570 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -54,8 +54,8 @@ VMFunction::addToFunctions() } bool -InvokeFunction(JSContext* cx, HandleObject obj, bool constructing, uint32_t argc, Value* argv, - MutableHandleValue rval) +InvokeFunction(JSContext* cx, HandleObject obj, bool constructing, bool ignoresReturnValue, + uint32_t argc, Value* argv, MutableHandleValue rval) { TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); TraceLogStartEvent(logger, TraceLogger_Call); @@ -104,7 +104,7 @@ InvokeFunction(JSContext* cx, HandleObject obj, bool constructing, uint32_t argc return InternalConstructWithProvidedThis(cx, fval, thisv, cargs, newTarget, rval); } - InvokeArgs args(cx); + InvokeArgsMaybeIgnoresReturnValue args(cx, ignoresReturnValue); if (!args.init(cx, argc)) return false; @@ -120,7 +120,7 @@ InvokeFunctionShuffleNewTarget(JSContext* cx, HandleObject obj, uint32_t numActu { MOZ_ASSERT(numFormalArgs > numActualArgs); argv[1 + numActualArgs] = argv[1 + numFormalArgs]; - return InvokeFunction(cx, obj, true, numActualArgs, argv, rval); + return InvokeFunction(cx, obj, true, false, numActualArgs, argv, rval); } bool diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 9a2edd0f3..bd65df134 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -584,8 +584,8 @@ class AutoDetectInvalidation }; MOZ_MUST_USE bool -InvokeFunction(JSContext* cx, HandleObject obj0, bool constructing, uint32_t argc, Value* argv, - MutableHandleValue rval); +InvokeFunction(JSContext* cx, HandleObject obj0, bool constructing, bool ignoresReturnValue, + uint32_t argc, Value* argv, MutableHandleValue rval); MOZ_MUST_USE bool InvokeFunctionShuffleNewTarget(JSContext* cx, HandleObject obj, uint32_t numActualArgs, uint32_t numFormalArgs, Value* argv, MutableHandleValue rval); diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index ffa4d8367..2b242d2e4 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -1898,6 +1898,9 @@ class LJSCallInstructionHelper : public LCallInstructionHelperisConstructing(); } + bool ignoresReturnValue() const { + return mir()->ignoresReturnValue(); + } }; // Generates a polymorphic callsite, wherein the function being called is -- cgit v1.2.3 From 85aeff765ea921ea2c947fa9d68756eb989b6287 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 14 Jul 2019 19:04:52 -0400 Subject: 1344477 - Part 2: Optimize Array.prototype.splice with JSOP_NORVCALL. --- js/src/jit/CodeGenerator.cpp | 13 ------------ js/src/jit/CodeGenerator.h | 1 - js/src/jit/InlinableNatives.h | 1 - js/src/jit/IonBuilder.h | 1 - js/src/jit/Lowering.cpp | 10 --------- js/src/jit/Lowering.h | 1 - js/src/jit/MCallOptimize.cpp | 42 ------------------------------------- js/src/jit/MIR.h | 21 ------------------- js/src/jit/MOpcodes.h | 1 - js/src/jit/VMFunctions.cpp | 12 ----------- js/src/jit/VMFunctions.h | 3 --- js/src/jit/shared/LIR-shared.h | 28 ------------------------- js/src/jit/shared/LOpcodes-shared.h | 1 - 13 files changed, 135 deletions(-) (limited to 'js/src/jit') 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(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 @@ -656,16 +656,6 @@ LIRGenerator::visitAssertRecoveredOnBailout(MAssertRecoveredOnBailout* assertion MOZ_CRASH("AssertRecoveredOnBailout nodes are always recovered on bailouts."); } -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) { 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: @@ -653,46 +651,6 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) return InliningStatus_Inlined; } -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) { 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, 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 @@ -303,18 +303,6 @@ StringsEqual(JSContext* cx, HandleString lhs, HandleString rhs, bool* res) template bool StringsEqual(JSContext* cx, HandleString lhs, HandleString rhs, bool* res); template bool StringsEqual(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) { 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 @@ -738,9 +738,6 @@ InitBaselineFrameForOsr(BaselineFrame* frame, InterpreterFrame* interpFrame, 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 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 -{ - 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 { 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) \ -- cgit v1.2.3 From 28c5b8c0589d7548382d205de8df03b42b32ccc7 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 14 Jul 2019 21:41:35 -0400 Subject: 1344334 - Make DoTypeUpdateFallback infallible. --- js/src/jit/BaselineIC.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index 8a7c68e59..a001357f8 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -323,7 +323,14 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H MOZ_CRASH("Invalid stub"); } - return stub->addUpdateStubForValue(cx, script /* = outerScript */, obj, id, value); + if (!stub->addUpdateStubForValue(cx, script /* = outerScript */, obj, id, value)) { + // The calling JIT code assumes this function is infallible (for + // instance we may reallocate dynamic slots before calling this), + // so ignore OOMs if we failed to attach a stub. + cx->recoverFromOutOfMemory(); + } + + return true; } typedef bool (*DoTypeUpdateFallbackFn)(JSContext*, BaselineFrame*, ICUpdatedStub*, HandleValue, -- cgit v1.2.3 From 7e6342a01158d689cb8cbfcb7ffb34f4aa2817c9 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Sat, 20 Jul 2019 15:43:01 +0200 Subject: Define JumpImmediateRange on ARM64. There are comments in the code suggesting that we've made plans at some point to handle very far jumps via patching + indirect jumps, but all of those comments are TODO/FIXME. Absent such a strategy, the furthest jump is 2^27-1 bytes, and we need to define JumpImmediateRange to reflect that. --- js/src/jit/arm64/Architecture-arm64.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/arm64/Architecture-arm64.h b/js/src/jit/arm64/Architecture-arm64.h index e74340f13..bee212db7 100644 --- a/js/src/jit/arm64/Architecture-arm64.h +++ b/js/src/jit/arm64/Architecture-arm64.h @@ -299,10 +299,12 @@ static const uint32_t ION_FRAME_SLACK_SIZE = 24; static const uint32_t ShadowStackSpace = 0; -// TODO: -// This constant needs to be updated to account for whatever near/far branching -// strategy is used by ARM64. -static const uint32_t JumpImmediateRange = UINT32_MAX; +// When our only strategy for far jumps is to encode the offset directly, and +// not insert any jump islands during assembly for even further jumps, then the +// architecture restricts us to -2^27 .. 2^27-4, to fit into a signed 28-bit +// value. We further reduce this range to allow the far-jump inserting code to +// have some breathing room. +static const uint32_t JumpImmediateRange = ((1 << 27) - (20 * 1024 * 1024)); static const uint32_t ABIStackAlignment = 16; static const uint32_t CodeAlignment = 16; -- cgit v1.2.3 From 8cd6a5a3361c155114c5dc9fedbee18e3e2720a7 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Mon, 22 Jul 2019 10:22:35 +0200 Subject: Remove unused checking function for unboxed types. Tag #1030 --- js/src/jit/MIR.cpp | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 10671cfda..0cf31adb3 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2630,40 +2630,6 @@ jit::EqualTypes(MIRType type1, TemporaryTypeSet* typeset1, return typeset1->equals(typeset2); } -// Tests whether input/inputTypes can always be stored to an unboxed -// object/array property with the given unboxed type. -bool -jit::CanStoreUnboxedType(TempAllocator& alloc, - JSValueType unboxedType, MIRType input, TypeSet* inputTypes) -{ - TemporaryTypeSet types; - - switch (unboxedType) { - case JSVAL_TYPE_BOOLEAN: - case JSVAL_TYPE_INT32: - case JSVAL_TYPE_DOUBLE: - case JSVAL_TYPE_STRING: - types.addType(TypeSet::PrimitiveType(unboxedType), alloc.lifoAlloc()); - break; - - case JSVAL_TYPE_OBJECT: - types.addType(TypeSet::AnyObjectType(), alloc.lifoAlloc()); - types.addType(TypeSet::NullType(), alloc.lifoAlloc()); - break; - - default: - MOZ_CRASH("Bad unboxed type"); - } - - return TypeSetIncludes(&types, input, inputTypes); -} - -static bool -CanStoreUnboxedType(TempAllocator& alloc, JSValueType unboxedType, MDefinition* value) -{ - return CanStoreUnboxedType(alloc, unboxedType, value->type(), value->resultTypeSet()); -} - bool MPhi::specializeType(TempAllocator& alloc) { -- cgit v1.2.3 From 2b223cce089bb8cbfb1a463fdd42e09eee63c7b2 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 5 Sep 2019 13:03:09 +0200 Subject: Use the correct group for JIT constraints. This fixes a rare crash/CTD in JS. This adds information about the constraints to a new RAII class so we can finish all constraints at the end. Based on changes in BZ 1568397 --- js/src/jit/IonAnalysis.cpp | 32 +++++++++++++++++++++++--------- js/src/jit/IonAnalysis.h | 7 +++++-- 2 files changed, 28 insertions(+), 11 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp index 5fc624fb1..ace6cd81e 100644 --- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -4005,7 +4005,7 @@ jit::ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const Lin } static bool -AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, +AnalyzePoppedThis(JSContext* cx, DPAConstraintInfo& constraintInfo, ObjectGroup* group, MDefinition* thisValue, MInstruction* ins, bool definitelyExecuted, HandlePlainObject baseobj, Vector* initializerList, @@ -4046,7 +4046,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, return true; RootedId id(cx, NameToId(setprop->name())); - if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) { + bool added = false; + if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo, + group, id, &added)) { + return false; + } + if (!added) { // The prototype chain already contains a getter/setter for this // property, or type information is too imprecise. return true; @@ -4106,7 +4111,12 @@ AnalyzePoppedThis(JSContext* cx, ObjectGroup* group, if (!baseobj->lookup(cx, id) && !accessedProperties->append(get->name())) return false; - if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, group, id)) { + bool added = false; + if (!AddClearDefiniteGetterSetterForPrototypeChain(cx, constraintInfo, + group, id, &added)) { + return false; + } + if (!added) { // The |this| value can escape if any property reads it does go // through a getter. return true; @@ -4132,8 +4142,11 @@ CmpInstructions(const void* a, const void* b) } bool -jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, - ObjectGroup* group, HandlePlainObject baseobj, +jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, + DPAConstraintInfo& constraintInfo, + HandleFunction fun, + ObjectGroup* group, + HandlePlainObject baseobj, Vector* initializerList) { MOZ_ASSERT(cx->zone()->types.activeAnalysis); @@ -4293,7 +4306,7 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, bool handled = false; size_t slotSpan = baseobj->slotSpan(); - if (!AnalyzePoppedThis(cx, group, thisValue, ins, definitelyExecuted, + if (!AnalyzePoppedThis(cx, constraintInfo, group, thisValue, ins, definitelyExecuted, baseobj, initializerList, &accessedProperties, &handled)) { return false; @@ -4312,7 +4325,6 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, // contingent on the correct frames being inlined. Add constraints to // invalidate the definite properties if additional functions could be // called at the inline frame sites. - Vector exitBlocks(cx); for (MBasicBlockIterator block(graph.begin()); block != graph.end(); block++) { // Inlining decisions made after the last new property was added to // the object don't need to be frozen. @@ -4320,9 +4332,11 @@ jit::AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, break; if (MResumePoint* rp = block->callerResumePoint()) { if (block->numPredecessors() == 1 && block->getPredecessor(0) == rp->block()) { - JSScript* script = rp->block()->info().script(); - if (!AddClearDefiniteFunctionUsesInScript(cx, group, script, block->info().script())) + JSScript* caller = rp->block()->info().script(); + JSScript* callee = block->info().script(); + if (!constraintInfo.addInliningConstraint(caller, callee)) { return false; + } } } } diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h index efd31415b..49bc0b591 100644 --- a/js/src/jit/IonAnalysis.h +++ b/js/src/jit/IonAnalysis.h @@ -196,8 +196,11 @@ MCompare* ConvertLinearInequality(TempAllocator& alloc, MBasicBlock* block, const LinearSum& sum); MOZ_MUST_USE bool -AnalyzeNewScriptDefiniteProperties(JSContext* cx, HandleFunction fun, - ObjectGroup* group, HandlePlainObject baseobj, +AnalyzeNewScriptDefiniteProperties(JSContext* cx, + DPAConstraintInfo& constraintInfo, + HandleFunction fun, + ObjectGroup* group, + HandlePlainObject baseobj, Vector* initializerList); MOZ_MUST_USE bool -- cgit v1.2.3 From a68a09618787980ff58b248c484b4017e3d2e663 Mon Sep 17 00:00:00 2001 From: Dmitry Grigoryev Date: Fri, 4 Oct 2019 22:58:16 +0200 Subject: Replace calls to undefined functions isMarkable() and toMarkablePointer() --- js/src/jit/arm/MacroAssembler-arm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index a4161ab00..3421001f7 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -3462,8 +3462,8 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest) ScratchRegisterScope scratch(asMasm()); SecondScratchRegisterScope scratch2(asMasm()); - if (val.isMarkable()) - ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch); + if (val.isGCThing()) + ma_mov(ImmGCPtr(val.toGCThing()), scratch); else ma_mov(Imm32(val.toNunboxPayload()), scratch); ma_str(scratch, ToPayload(dest), scratch2); -- cgit v1.2.3 From e8c5582bec49058508b2de9f2f292f3a25e5278e Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 24 Oct 2019 12:13:26 +0200 Subject: Fix type barrier in IonBuilder::jsop_getimport. --- js/src/jit/IonBuilder.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 2d053de5a..0c69729a4 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -8895,10 +8895,8 @@ IonBuilder::jsop_getimport(PropertyName* name) if (!emitted) { // This can happen if we don't have type information. - TypeSet::ObjectKey* staticKey = TypeSet::ObjectKey::get(targetEnv); TemporaryTypeSet* types = bytecodeTypes(pc); - BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), staticKey, - name, types, /* updateObserved = */ true); + BarrierKind barrier = BarrierKind::TypeSet; if (!loadStaticSlot(targetEnv, barrier, types, shape->slot())) return false; -- cgit v1.2.3 From 44a077980abb92dcea9ed374fd9719eaaf2f1458 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 27 Oct 2019 02:51:11 +0200 Subject: Issue #1257 - Part 2: Remove watch/unwatch and JS watchpoint class. --- js/src/jit/BaselineIC.cpp | 6 ------ js/src/jit/IonCaches.cpp | 5 +---- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'js/src/jit') diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index a001357f8..9530f65fa 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -4053,9 +4053,6 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC { MOZ_ASSERT(!*attached); - if (obj->watched()) - return true; - RootedShape shape(cx); RootedObject holder(cx); if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape)) @@ -4151,9 +4148,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc, MOZ_ASSERT(!*attached); MOZ_ASSERT(!*isTemporarilyUnoptimizable); - if (obj->watched()) - return true; - RootedShape shape(cx); RootedObject holder(cx); if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape)) diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 48e0792bb..fb4291188 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3232,7 +3232,7 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* MOZ_ASSERT(!*emitted); MOZ_ASSERT(!*tryNativeAddSlot); - if (!canAttachStub() || obj->watched()) + if (!canAttachStub()) return true; // Fail cache emission if the object is frozen @@ -3897,9 +3897,6 @@ IsDenseElementSetInlineable(JSObject* obj, const Value& idval, const ConstantOrR if (!obj->is()) return false; - if (obj->watched()) - return false; - if (!idval.isInt32()) return false; -- cgit v1.2.3