1/* 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef DFGCallArrayAllocatorSlowPathGenerator_h 27#define DFGCallArrayAllocatorSlowPathGenerator_h 28 29#if ENABLE(DFG_JIT) 30 31#include "DFGCommon.h" 32#include "DFGSlowPathGenerator.h" 33#include "DFGSpeculativeJIT.h" 34#include <wtf/Vector.h> 35 36namespace JSC { namespace DFG { 37 38class CallArrayAllocatorSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> { 39public: 40 CallArrayAllocatorSlowPathGenerator( 41 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZ function, 42 GPRReg resultGPR, GPRReg storageGPR, Structure* structure, size_t size) 43 : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) 44 , m_function(function) 45 , m_resultGPR(resultGPR) 46 , m_storageGPR(storageGPR) 47 , m_structure(structure) 48 , m_size(size) 49 { 50 ASSERT(size < static_cast<size_t>(std::numeric_limits<int32_t>::max())); 51 jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR); 52 } 53 54protected: 55 virtual void generateInternal(SpeculativeJIT* jit) override 56 { 57 linkFrom(jit); 58 for (unsigned i = 0; i < m_plans.size(); ++i) 59 jit->silentSpill(m_plans[i]); 60 jit->callOperation(m_function, m_resultGPR, m_structure, m_size); 61 GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); 62 for (unsigned i = m_plans.size(); i--;) 63 jit->silentFill(m_plans[i], canTrample); 64 jit->m_jit.loadPtr(MacroAssembler::Address(m_resultGPR, JSObject::butterflyOffset()), m_storageGPR); 65 jumpTo(jit); 66 } 67 68private: 69 P_JITOperation_EStZ m_function; 70 GPRReg m_resultGPR; 71 GPRReg m_storageGPR; 72 Structure* m_structure; 73 size_t m_size; 74 Vector<SilentRegisterSavePlan, 2> m_plans; 75}; 76 77class CallArrayAllocatorWithVariableSizeSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> { 78public: 79 CallArrayAllocatorWithVariableSizeSlowPathGenerator( 80 MacroAssembler::JumpList from, SpeculativeJIT* jit, P_JITOperation_EStZ function, 81 GPRReg resultGPR, Structure* contiguousStructure, Structure* arrayStorageStructure, GPRReg sizeGPR) 82 : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit) 83 , m_function(function) 84 , m_resultGPR(resultGPR) 85 , m_contiguousStructure(contiguousStructure) 86 , m_arrayStorageStructure(arrayStorageStructure) 87 , m_sizeGPR(sizeGPR) 88 { 89 jit->silentSpillAllRegistersImpl(false, m_plans, resultGPR); 90 } 91 92protected: 93 virtual void generateInternal(SpeculativeJIT* jit) override 94 { 95 linkFrom(jit); 96 for (unsigned i = 0; i < m_plans.size(); ++i) 97 jit->silentSpill(m_plans[i]); 98 GPRReg scratchGPR = AssemblyHelpers::selectScratchGPR(m_sizeGPR); 99 MacroAssembler::Jump bigLength = jit->m_jit.branch32(MacroAssembler::AboveOrEqual, m_sizeGPR, MacroAssembler::TrustedImm32(MIN_SPARSE_ARRAY_INDEX)); 100 jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_contiguousStructure), scratchGPR); 101 MacroAssembler::Jump done = jit->m_jit.jump(); 102 bigLength.link(&jit->m_jit); 103 jit->m_jit.move(MacroAssembler::TrustedImmPtr(m_arrayStorageStructure), scratchGPR); 104 done.link(&jit->m_jit); 105 jit->callOperation(m_function, m_resultGPR, scratchGPR, m_sizeGPR); 106 GPRReg canTrample = SpeculativeJIT::pickCanTrample(m_resultGPR); 107 for (unsigned i = m_plans.size(); i--;) 108 jit->silentFill(m_plans[i], canTrample); 109 jumpTo(jit); 110 } 111 112private: 113 P_JITOperation_EStZ m_function; 114 GPRReg m_resultGPR; 115 Structure* m_contiguousStructure; 116 Structure* m_arrayStorageStructure; 117 GPRReg m_sizeGPR; 118 Vector<SilentRegisterSavePlan, 2> m_plans; 119}; 120 121} } // namespace JSC::DFG 122 123#endif // ENABLE(DFG_JIT) 124 125#endif // DFGCallArrayAllocatorSlowPathGenerator_h 126 127