2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
32 #include "FTLDWARFRegister.h"
33 #include "FTLStackMaps.h"
35 #include <wtf/HashMap.h>
37 namespace JSC
{ namespace FTL
{
54 Location(WTF::HashTableDeletedValueType
)
60 static Location
forRegister(DWARFRegister dwarfReg
, int32_t addend
)
63 result
.m_kind
= Register
;
64 result
.u
.variable
.dwarfRegNum
= dwarfReg
.dwarfRegNum();
65 result
.u
.variable
.offset
= addend
;
69 static Location
forIndirect(DWARFRegister dwarfReg
, int32_t offset
)
72 result
.m_kind
= Indirect
;
73 result
.u
.variable
.dwarfRegNum
= dwarfReg
.dwarfRegNum();
74 result
.u
.variable
.offset
= offset
;
78 static Location
forConstant(int64_t constant
)
81 result
.m_kind
= Constant
;
82 result
.u
.constant
= constant
;
86 // You can pass a null StackMaps if you are confident that the location doesn't
87 // involve a wide constant.
88 static Location
forStackmaps(const StackMaps
*, const StackMaps::Location
&);
90 Kind
kind() const { return m_kind
; }
92 bool hasDwarfRegNum() const { return kind() == Register
|| kind() == Indirect
; }
93 int16_t dwarfRegNum() const
95 ASSERT(hasDwarfRegNum());
96 return u
.variable
.dwarfRegNum
;
99 bool hasDwarfReg() const { return hasDwarfRegNum(); }
100 DWARFRegister
dwarfReg() const { return DWARFRegister(dwarfRegNum()); }
102 bool hasOffset() const { return kind() == Indirect
; }
103 int32_t offset() const
106 return u
.variable
.offset
;
109 bool hasAddend() const { return kind() == Register
; }
110 int32_t addend() const
113 return u
.variable
.offset
;
116 bool hasConstant() const { return kind() == Constant
; }
117 int64_t constant() const
119 ASSERT(hasConstant());
123 bool operator!() const { return kind() == Unprocessed
&& !u
.variable
.offset
; }
125 bool isHashTableDeletedValue() const { return kind() == Unprocessed
&& u
.variable
.offset
; }
127 bool operator==(const Location
& other
) const
129 return m_kind
== other
.m_kind
130 && u
.constant
== other
.u
.constant
;
133 unsigned hash() const
135 unsigned result
= m_kind
;
139 result
^= u
.variable
.offset
;
143 result
^= u
.variable
.dwarfRegNum
;
147 result
^= u
.variable
.dwarfRegNum
;
148 result
^= u
.variable
.offset
;
152 result
^= WTF::IntHash
<int64_t>::hash(u
.constant
);
156 return WTF::IntHash
<unsigned>::hash(result
);
159 void dump(PrintStream
&) const;
162 bool involvesGPR() const;
164 GPRReg
directGPR() const; // Get the GPR and assert that there is no addend.
169 // Assuming that all registers are saved to the savedRegisters buffer according
170 // to FTLSaveRestore convention, this loads the value into the given register.
171 // The code that this generates isn't exactly super fast. This assumes that FP
172 // and SP contain the same values that they would have contained in the original
173 // frame, or that you've done one or more canonically formed calls (i.e. can
174 // restore the FP by following the call frame linked list numFramesToPop times,
175 // and SP can be recovered by popping FP numFramesToPop-1 times and adding 16).
176 void restoreInto(MacroAssembler
&, char* savedRegisters
, GPRReg result
, unsigned numFramesToPop
= 0) const;
189 struct LocationHash
{
190 static unsigned hash(const Location
& key
) { return key
.hash(); }
191 static bool equal(const Location
& a
, const Location
& b
) { return a
== b
; }
192 static const bool safeToCompareToEmptyOrDeleted
= true;
195 } } // namespace JSC::FTL
199 void printInternal(PrintStream
&, JSC::FTL::Location::Kind
);
201 template<typename T
> struct DefaultHash
;
202 template<> struct DefaultHash
<JSC::FTL::Location
> {
203 typedef JSC::FTL::LocationHash Hash
;
206 template<typename T
> struct HashTraits
;
207 template<> struct HashTraits
<JSC::FTL::Location
> : SimpleClassHashTraits
<JSC::FTL::Location
> { };
211 #endif // ENABLE(FTL_JIT)
213 #endif // FTLLocation_h