ffd0d071508d73516858bb73bc17bd1028ae4ae3
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLOSRExit.cpp
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 #include "config.h"
27 #include "FTLOSRExit.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "CodeBlock.h"
32 #include "DFGBasicBlock.h"
33 #include "DFGNode.h"
34 #include "FTLExitArgument.h"
35 #include "FTLExitArgumentList.h"
36 #include "FTLJITCode.h"
37 #include "Operations.h"
38
39 namespace JSC { namespace FTL {
40
41 using namespace DFG;
42
43 OSRExit::OSRExit(
44     ExitKind exitKind, ValueFormat profileValueFormat,
45     MethodOfGettingAValueProfile valueProfile, CodeOrigin codeOrigin,
46     CodeOrigin originForProfile, int lastSetOperand, unsigned numberOfArguments,
47     unsigned numberOfLocals)
48     : OSRExitBase(exitKind, codeOrigin, originForProfile)
49     , m_profileValueFormat(profileValueFormat)
50     , m_valueProfile(valueProfile)
51     , m_patchableCodeOffset(0)
52     , m_lastSetOperand(lastSetOperand)
53     , m_values(numberOfArguments, numberOfLocals)
54 {
55 }
56
57 CodeLocationJump OSRExit::codeLocationForRepatch(CodeBlock* ftlCodeBlock) const
58 {
59     return CodeLocationJump(
60         reinterpret_cast<char*>(
61             ftlCodeBlock->jitCode()->ftl()->exitThunks().dataLocation()) +
62         m_patchableCodeOffset);
63 }
64
65 void OSRExit::convertToForward(
66     BasicBlock* block, Node* currentNode, unsigned nodeIndex,
67     const FormattedValue &value, ExitArgumentList& arguments)
68 {
69     Node* node;
70     Node* lastMovHint;
71     if (!doSearchForForwardConversion(block, currentNode, nodeIndex, !!value, node, lastMovHint))
72         return;
73
74     ASSERT(node->codeOrigin != currentNode->codeOrigin);
75     
76     m_codeOrigin = node->codeOrigin;
77     
78     if (!value)
79         return;
80     
81     VirtualRegister overriddenOperand = lastMovHint->local();
82     m_lastSetOperand = overriddenOperand;
83     
84     // Is the value for this operand being passed as an argument to the exit, or is
85     // it something else? If it's an argument already, then replace that argument;
86     // otherwise add another argument.
87     if (m_values[overriddenOperand.offset()].isArgument()) {
88         ExitArgument exitArgument = m_values[overriddenOperand.offset()].exitArgument();
89         arguments[exitArgument.argument()] = value.value();
90         m_values[overriddenOperand.offset()] = ExitValue::exitArgument(
91             exitArgument.withFormat(value.format()));
92         return;
93     }
94     
95     unsigned argument = arguments.size();
96     arguments.append(value.value());
97     m_values[m_lastSetOperand.offset()] = ExitValue::exitArgument(
98         ExitArgument(value.format(), argument));
99 }
100
101 } } // namespace JSC::FTL
102
103 #endif // ENABLE(FTL_JIT)
104