1/* 2 * Copyright (C) 2012, 2013 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 DFGArgumentPosition_h 27#define DFGArgumentPosition_h 28 29#include "DFGDoubleFormatState.h" 30#include "DFGVariableAccessData.h" 31#include "DFGVariableAccessDataDump.h" 32#include "SpeculatedType.h" 33 34namespace JSC { namespace DFG { 35 36class ArgumentPosition { 37public: 38 ArgumentPosition() 39 : m_prediction(SpecNone) 40 , m_doubleFormatState(EmptyDoubleFormatState) 41 , m_isProfitableToUnbox(false) 42 , m_shouldNeverUnbox(false) 43 { 44 } 45 46 void addVariable(VariableAccessData* variable) 47 { 48 m_variables.append(variable); 49 } 50 51 bool mergeShouldNeverUnbox(bool shouldNeverUnbox) 52 { 53 return checkAndSet(m_shouldNeverUnbox, m_shouldNeverUnbox | shouldNeverUnbox); 54 } 55 56 bool mergeArgumentPredictionAwareness() 57 { 58 bool changed = false; 59 for (unsigned i = 0; i < m_variables.size(); ++i) { 60 VariableAccessData* variable = m_variables[i]->find(); 61 changed |= mergeSpeculation(m_prediction, variable->argumentAwarePrediction()); 62 changed |= mergeDoubleFormatState(m_doubleFormatState, variable->doubleFormatState()); 63 changed |= mergeShouldNeverUnbox(variable->shouldNeverUnbox()); 64 } 65 if (!changed) 66 return false; 67 changed = false; 68 for (unsigned i = 0; i < m_variables.size(); ++i) { 69 VariableAccessData* variable = m_variables[i]->find(); 70 changed |= variable->mergeArgumentAwarePrediction(m_prediction); 71 changed |= variable->mergeDoubleFormatState(m_doubleFormatState); 72 changed |= variable->mergeShouldNeverUnbox(m_shouldNeverUnbox); 73 } 74 return changed; 75 } 76 77 bool mergeArgumentUnboxingAwareness() 78 { 79 bool changed = false; 80 for (unsigned i = 0; i < m_variables.size(); ++i) { 81 VariableAccessData* variable = m_variables[i]->find(); 82 changed |= checkAndSet(m_isProfitableToUnbox, m_isProfitableToUnbox | variable->isProfitableToUnbox()); 83 } 84 if (!changed) 85 return false; 86 changed = false; 87 for (unsigned i = 0; i < m_variables.size(); ++i) { 88 VariableAccessData* variable = m_variables[i]->find(); 89 changed |= variable->mergeIsProfitableToUnbox(m_isProfitableToUnbox); 90 } 91 return changed; 92 } 93 94 bool shouldUnboxIfPossible() const { return m_isProfitableToUnbox && !m_shouldNeverUnbox; } 95 96 SpeculatedType prediction() const { return m_prediction; } 97 DoubleFormatState doubleFormatState() const { return m_doubleFormatState; } 98 bool shouldUseDoubleFormat() const 99 { 100 return doubleFormatState() == UsingDoubleFormat && shouldUnboxIfPossible(); 101 } 102 103 void dump(PrintStream& out, Graph* graph) 104 { 105 for (unsigned i = 0; i < m_variables.size(); ++i) { 106 VariableAccessData* variable = m_variables[i]->find(); 107 int operand = variable->operand(); 108 109 if (i) 110 out.print(" "); 111 112 if (operandIsArgument(operand)) 113 out.print("arg", operandToArgument(operand), "(", VariableAccessDataDump(*graph, variable), ")"); 114 else 115 out.print("r", operand, "(", VariableAccessDataDump(*graph, variable), ")"); 116 } 117 out.print("\n"); 118 } 119 120private: 121 SpeculatedType m_prediction; 122 DoubleFormatState m_doubleFormatState; 123 bool m_isProfitableToUnbox; 124 bool m_shouldNeverUnbox; 125 126 Vector<VariableAccessData*, 2> m_variables; 127}; 128 129} } // namespace JSC::DFG 130 131#endif // DFGArgumentPosition_h 132 133