1/*
2 * Copyright (C) 2011 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#include "config.h"
27#include "DFGAssemblyHelpers.h"
28
29#if ENABLE(DFG_JIT)
30
31namespace JSC { namespace DFG {
32
33ExecutableBase* AssemblyHelpers::executableFor(const CodeOrigin& codeOrigin)
34{
35    if (!codeOrigin.inlineCallFrame)
36        return m_codeBlock->ownerExecutable();
37
38    return codeOrigin.inlineCallFrame->executable.get();
39}
40
41Vector<BytecodeAndMachineOffset>& AssemblyHelpers::decodedCodeMapFor(CodeBlock* codeBlock)
42{
43    ASSERT(codeBlock == codeBlock->baselineVersion());
44    ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
45    ASSERT(codeBlock->jitCodeMap());
46
47    HashMap<CodeBlock*, Vector<BytecodeAndMachineOffset> >::AddResult result = m_decodedCodeMaps.add(codeBlock, Vector<BytecodeAndMachineOffset>());
48
49    if (result.isNewEntry)
50        codeBlock->jitCodeMap()->decode(result.iterator->value);
51
52    return result.iterator->value;
53}
54
55#if ENABLE(SAMPLING_FLAGS)
56void AssemblyHelpers::setSamplingFlag(int32_t flag)
57{
58    ASSERT(flag >= 1);
59    ASSERT(flag <= 32);
60    or32(TrustedImm32(1u << (flag - 1)), AbsoluteAddress(SamplingFlags::addressOfFlags()));
61}
62
63void AssemblyHelpers::clearSamplingFlag(int32_t flag)
64{
65    ASSERT(flag >= 1);
66    ASSERT(flag <= 32);
67    and32(TrustedImm32(~(1u << (flag - 1))), AbsoluteAddress(SamplingFlags::addressOfFlags()));
68}
69#endif
70
71#if DFG_ENABLE(JIT_ASSERT)
72#if USE(JSVALUE64)
73void AssemblyHelpers::jitAssertIsInt32(GPRReg gpr)
74{
75#if CPU(X86_64)
76    Jump checkInt32 = branch64(BelowOrEqual, gpr, TrustedImm64(static_cast<uintptr_t>(0xFFFFFFFFu)));
77    breakpoint();
78    checkInt32.link(this);
79#else
80    UNUSED_PARAM(gpr);
81#endif
82}
83
84void AssemblyHelpers::jitAssertIsJSInt32(GPRReg gpr)
85{
86    Jump checkJSInt32 = branch64(AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
87    breakpoint();
88    checkJSInt32.link(this);
89}
90
91void AssemblyHelpers::jitAssertIsJSNumber(GPRReg gpr)
92{
93    Jump checkJSNumber = branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagTypeNumberRegister);
94    breakpoint();
95    checkJSNumber.link(this);
96}
97
98void AssemblyHelpers::jitAssertIsJSDouble(GPRReg gpr)
99{
100    Jump checkJSInt32 = branch64(AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
101    Jump checkJSNumber = branchTest64(MacroAssembler::NonZero, gpr, GPRInfo::tagTypeNumberRegister);
102    checkJSInt32.link(this);
103    breakpoint();
104    checkJSNumber.link(this);
105}
106
107void AssemblyHelpers::jitAssertIsCell(GPRReg gpr)
108{
109    Jump checkCell = branchTest64(MacroAssembler::Zero, gpr, GPRInfo::tagMaskRegister);
110    breakpoint();
111    checkCell.link(this);
112}
113#elif USE(JSVALUE32_64)
114void AssemblyHelpers::jitAssertIsInt32(GPRReg gpr)
115{
116    UNUSED_PARAM(gpr);
117}
118
119void AssemblyHelpers::jitAssertIsJSInt32(GPRReg gpr)
120{
121    Jump checkJSInt32 = branch32(Equal, gpr, TrustedImm32(JSValue::Int32Tag));
122    breakpoint();
123    checkJSInt32.link(this);
124}
125
126void AssemblyHelpers::jitAssertIsJSNumber(GPRReg gpr)
127{
128    Jump checkJSInt32 = branch32(Equal, gpr, TrustedImm32(JSValue::Int32Tag));
129    Jump checkJSDouble = branch32(Below, gpr, TrustedImm32(JSValue::LowestTag));
130    breakpoint();
131    checkJSInt32.link(this);
132    checkJSDouble.link(this);
133}
134
135void AssemblyHelpers::jitAssertIsJSDouble(GPRReg gpr)
136{
137    Jump checkJSDouble = branch32(Below, gpr, TrustedImm32(JSValue::LowestTag));
138    breakpoint();
139    checkJSDouble.link(this);
140}
141
142void AssemblyHelpers::jitAssertIsCell(GPRReg gpr)
143{
144    Jump checkCell = branch32(Equal, gpr, TrustedImm32(JSValue::CellTag));
145    breakpoint();
146    checkCell.link(this);
147}
148#endif // USE(JSVALUE32_64)
149
150void AssemblyHelpers::jitAssertHasValidCallFrame()
151{
152    Jump checkCFR = branchTestPtr(Zero, GPRInfo::callFrameRegister, TrustedImm32(7));
153    breakpoint();
154    checkCFR.link(this);
155}
156#endif // DFG_ENABLE(JIT_ASSERT)
157
158} } // namespace JSC::DFG
159
160#endif // ENABLE(DFG_JIT)
161
162