Source/JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=119548
[WebKit-https.git] / Source / JavaScriptCore / jit / SlowPathCall.h
1 /*
2  * Copyright (C) 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 SlowPathCall_h
27 #define SlowPathCall_h
28
29 #include "CommonSlowPaths.h"
30 #include "MacroAssemblerCodeRef.h"
31
32 #if ENABLE(JIT)
33
34 namespace JSC {
35
36 class JITSlowPathCall {
37 public:
38     JITSlowPathCall(JIT* jit, Instruction* pc, SlowPathReturnType (SLOW_PATH *stub)(ExecState* exec, Instruction* pc))
39         : m_jit(jit)
40         , m_stub(stub)
41         , m_pc(pc)
42     {
43     }
44
45     JIT::Call call()
46     {
47 #if ENABLE(OPCODE_SAMPLING)
48         if (m_jit->m_bytecodeOffset != (unsigned)-1)
49             m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, true);
50 #endif
51         m_jit->updateTopCallFrame();
52 #if CPU(X86) && USE(JSVALUE32_64)
53         m_jit->addPtr(MacroAssembler::TrustedImm32(-8), MacroAssembler::stackPointerRegister);
54         m_jit->push(JIT::TrustedImm32(JIT::TrustedImmPtr(m_pc)));
55         m_jit->push(JIT::callFrameRegister);
56 #elif CPU(X86_64) && OS(WINDOWS)
57         m_jit->addPtr(MacroAssembler::TrustedImm32(-16), MacroAssembler::stackPointerRegister);
58         m_jit->move(MacroAssembler::stackPointerRegister, JIT::firstArgumentRegister);
59         m_jit->move(JIT::callFrameRegister, JIT::secondArgumentRegister);
60         m_jit->move(JIT::TrustedImmPtr(m_pc), JIT::thirdArgumentRegister);
61 #else
62         m_jit->move(JIT::callFrameRegister, JIT::firstArgumentRegister);
63         m_jit->move(JIT::TrustedImmPtr(m_pc), JIT::secondArgumentRegister);
64 #endif
65         JIT::Call call = m_jit->call();
66         m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeOffset, m_stub.value()));
67
68 #if CPU(X86) && USE(JSVALUE32_64)
69         m_jit->addPtr(MacroAssembler::TrustedImm32(16), MacroAssembler::stackPointerRegister);
70 #elif CPU(X86_64) && OS(WINDOWS)
71         m_jit->pop(JIT::regT0); // vPC
72         m_jit->pop(JIT::regT1); // callFrame register
73 #endif
74
75 #if ENABLE(OPCODE_SAMPLING)
76         if (m_jit->m_bytecodeOffset != (unsigned)-1)
77             m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeOffset, false);
78 #endif
79         
80 #if USE(JSVALUE32_64)
81         m_jit->unmap();
82 #else
83         m_jit->killLastResultRegister();
84 #endif
85         
86 #if USE(JSVALUE32_64)
87         JIT::Jump noException = m_jit->branch32(JIT::Equal, JIT::AbsoluteAddress(reinterpret_cast<char*>(m_jit->m_codeBlock->vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), JIT::TrustedImm32(JSValue::EmptyValueTag));
88 #else
89         JIT::Jump noException = m_jit->branchTest64(JIT::Zero, JIT::AbsoluteAddress(m_jit->m_codeBlock->vm()->addressOfException()));
90 #endif
91         m_jit->reloadCallFrameFromTopCallFrame();
92         m_jit->move(JIT::TrustedImmPtr(FunctionPtr(ctiVMHandleException).value()), JIT::regT1);
93         m_jit->jump(JIT::regT1);
94         noException.link(m_jit);
95         
96         return call;
97     }
98
99 private:
100     JIT* m_jit;
101     FunctionPtr m_stub;
102     Instruction* m_pc;
103 };
104
105 } // namespace JS
106
107 #endif // ENABLE(JIT)
108
109 #endif // SlowPathCall_h