blob: 3373d1c08ef53cc88eec78c6b161b13fd393b6f2 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_CODEGEN_H_
29#define V8_CODEGEN_H_
30
Steve Blocka7e24c12009-10-30 11:49:00 +000031#include "code-stubs.h"
32#include "runtime.h"
Steve Block6ded16b2010-05-10 14:33:55 +010033#include "type-info.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034
35// Include the declaration of the architecture defined class CodeGenerator.
36// The contract to the shared code is that the the CodeGenerator is a subclass
37// of Visitor and that the following methods are available publicly:
38// MakeCode
Steve Block3ce2e202009-11-05 08:53:23 +000039// MakeCodePrologue
40// MakeCodeEpilogue
Steve Blocka7e24c12009-10-30 11:49:00 +000041// masm
42// frame
Steve Blockd0582a62009-12-15 09:54:21 +000043// script
Steve Blocka7e24c12009-10-30 11:49:00 +000044// has_valid_frame
45// SetFrame
46// DeleteFrame
47// allocator
48// AddDeferred
49// in_spilled_code
50// set_in_spilled_code
Steve Block3ce2e202009-11-05 08:53:23 +000051// RecordPositions
Steve Blocka7e24c12009-10-30 11:49:00 +000052//
53// These methods are either used privately by the shared code or implemented as
54// shared code:
55// CodeGenerator
56// ~CodeGenerator
57// ProcessDeferred
Leon Clarke4515c472010-02-03 11:58:03 +000058// Generate
Steve Block3ce2e202009-11-05 08:53:23 +000059// ComputeLazyCompile
Steve Block6ded16b2010-05-10 14:33:55 +010060// BuildFunctionInfo
Steve Blocka7e24c12009-10-30 11:49:00 +000061// ComputeCallInitialize
62// ComputeCallInitializeInLoop
63// ProcessDeclarations
64// DeclareGlobals
65// FindInlineRuntimeLUT
66// CheckForInlineRuntimeCall
67// PatchInlineRuntimeEntry
Steve Block3ce2e202009-11-05 08:53:23 +000068// AnalyzeCondition
Steve Blocka7e24c12009-10-30 11:49:00 +000069// CodeForFunctionPosition
70// CodeForReturnPosition
71// CodeForStatementPosition
Steve Blockd0582a62009-12-15 09:54:21 +000072// CodeForDoWhileConditionPosition
Steve Blocka7e24c12009-10-30 11:49:00 +000073// CodeForSourcePosition
74
75
Steve Block6ded16b2010-05-10 14:33:55 +010076#define INLINE_RUNTIME_FUNCTION_LIST(F) \
77 F(IsSmi, 1, 1) \
78 F(IsNonNegativeSmi, 1, 1) \
79 F(IsArray, 1, 1) \
80 F(IsRegExp, 1, 1) \
81 F(CallFunction, -1 /* receiver + n args + function */, 1) \
82 F(IsConstructCall, 0, 1) \
83 F(ArgumentsLength, 0, 1) \
84 F(Arguments, 1, 1) \
85 F(ClassOf, 1, 1) \
86 F(ValueOf, 1, 1) \
87 F(SetValueOf, 2, 1) \
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +010088 F(StringCharCodeAt, 2, 1) \
89 F(StringCharFromCode, 1, 1) \
90 F(StringCharAt, 2, 1) \
Steve Block6ded16b2010-05-10 14:33:55 +010091 F(ObjectEquals, 2, 1) \
92 F(Log, 3, 1) \
Leon Clarkef7060e22010-06-03 12:02:55 +010093 F(RandomHeapNumber, 0, 1) \
Steve Block6ded16b2010-05-10 14:33:55 +010094 F(IsObject, 1, 1) \
95 F(IsFunction, 1, 1) \
96 F(IsUndetectableObject, 1, 1) \
Iain Merrick75681382010-08-19 15:07:18 +010097 F(IsSpecObject, 1, 1) \
98 F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \
Steve Block6ded16b2010-05-10 14:33:55 +010099 F(StringAdd, 2, 1) \
100 F(SubString, 3, 1) \
101 F(StringCompare, 2, 1) \
102 F(RegExpExec, 4, 1) \
103 F(RegExpConstructResult, 3, 1) \
Steve Block791712a2010-08-27 10:21:07 +0100104 F(RegExpCloneResult, 1, 1) \
Steve Block6ded16b2010-05-10 14:33:55 +0100105 F(GetFromCache, 2, 1) \
106 F(NumberToString, 1, 1) \
107 F(SwapElements, 3, 1) \
108 F(MathPow, 2, 1) \
109 F(MathSin, 1, 1) \
110 F(MathCos, 1, 1) \
Ben Murdochbb769b22010-08-11 14:56:33 +0100111 F(MathSqrt, 1, 1) \
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100112 F(IsRegExpEquivalent, 2, 1) \
113 F(HasCachedArrayIndex, 1, 1) \
114 F(GetCachedArrayIndex, 1, 1)
Steve Block6ded16b2010-05-10 14:33:55 +0100115
116
Ben Murdochbb769b22010-08-11 14:56:33 +0100117#if V8_TARGET_ARCH_IA32
118#include "ia32/codegen-ia32.h"
119#elif V8_TARGET_ARCH_X64
120#include "x64/codegen-x64.h"
121#elif V8_TARGET_ARCH_ARM
122#include "arm/codegen-arm.h"
123#elif V8_TARGET_ARCH_MIPS
124#include "mips/codegen-mips.h"
125#else
126#error Unsupported target architecture.
127#endif
128
129#include "register-allocator.h"
130
131namespace v8 {
132namespace internal {
133
Steve Blocka7e24c12009-10-30 11:49:00 +0000134// Code generation can be nested. Code generation scopes form a stack
135// of active code generators.
136class CodeGeneratorScope BASE_EMBEDDED {
137 public:
138 explicit CodeGeneratorScope(CodeGenerator* cgen) {
139 previous_ = top_;
140 top_ = cgen;
141 }
142
143 ~CodeGeneratorScope() {
144 top_ = previous_;
145 }
146
147 static CodeGenerator* Current() {
148 ASSERT(top_ != NULL);
149 return top_;
150 }
151
152 private:
153 static CodeGenerator* top_;
154 CodeGenerator* previous_;
155};
156
Iain Merrick75681382010-08-19 15:07:18 +0100157
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100158#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
159
160// State of used registers in a virtual frame.
161class FrameRegisterState {
162 public:
163 // Captures the current state of the given frame.
164 explicit FrameRegisterState(VirtualFrame* frame);
165
166 // Saves the state in the stack.
167 void Save(MacroAssembler* masm) const;
168
169 // Restores the state from the stack.
170 void Restore(MacroAssembler* masm) const;
171
172 private:
173 // Constants indicating special actions. They should not be multiples
174 // of kPointerSize so they will not collide with valid offsets from
175 // the frame pointer.
176 static const int kIgnore = -1;
177 static const int kPush = 1;
178
179 // This flag is ored with a valid offset from the frame pointer, so
180 // it should fit in the low zero bits of a valid offset.
181 static const int kSyncedFlag = 2;
182
183 int registers_[RegisterAllocator::kNumRegisters];
184};
185
186#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
187
188
189class FrameRegisterState {
190 public:
191 inline FrameRegisterState(VirtualFrame frame) : frame_(frame) { }
192
193 inline const VirtualFrame* frame() const { return &frame_; }
194
195 private:
196 VirtualFrame frame_;
197};
198
199#else
200
201#error Unsupported target architecture.
202
203#endif
204
205
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100206// RuntimeCallHelper implementation that saves/restores state of a
207// virtual frame.
208class VirtualFrameRuntimeCallHelper : public RuntimeCallHelper {
209 public:
210 // Does not take ownership of |frame_state|.
211 explicit VirtualFrameRuntimeCallHelper(const FrameRegisterState* frame_state)
212 : frame_state_(frame_state) {}
213
214 virtual void BeforeCall(MacroAssembler* masm) const;
215
216 virtual void AfterCall(MacroAssembler* masm) const;
217
218 private:
219 const FrameRegisterState* frame_state_;
220};
221
222
Steve Blocka7e24c12009-10-30 11:49:00 +0000223// Deferred code objects are small pieces of code that are compiled
224// out of line. They are used to defer the compilation of uncommon
225// paths thereby avoiding expensive jumps around uncommon code parts.
226class DeferredCode: public ZoneObject {
227 public:
228 DeferredCode();
229 virtual ~DeferredCode() { }
230
231 virtual void Generate() = 0;
232
233 MacroAssembler* masm() { return masm_; }
234
235 int statement_position() const { return statement_position_; }
236 int position() const { return position_; }
237
238 Label* entry_label() { return &entry_label_; }
239 Label* exit_label() { return &exit_label_; }
240
241#ifdef DEBUG
242 void set_comment(const char* comment) { comment_ = comment; }
243 const char* comment() const { return comment_; }
244#else
245 void set_comment(const char* comment) { }
246 const char* comment() const { return ""; }
247#endif
248
249 inline void Jump();
250 inline void Branch(Condition cc);
251 void BindExit() { masm_->bind(&exit_label_); }
252
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100253 const FrameRegisterState* frame_state() const { return &frame_state_; }
254
Steve Blocka7e24c12009-10-30 11:49:00 +0000255 void SaveRegisters();
256 void RestoreRegisters();
Iain Merrick75681382010-08-19 15:07:18 +0100257 void Exit();
258
259 // If this returns true then all registers will be saved for the duration
260 // of the Generate() call. Otherwise the registers are not saved and the
261 // Generate() call must bracket runtime any runtime calls with calls to
262 // SaveRegisters() and RestoreRegisters(). In this case the Generate
263 // method must also call Exit() in order to return to the non-deferred
264 // code.
265 virtual bool AutoSaveAndRestore() { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000266
267 protected:
268 MacroAssembler* masm_;
269
270 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000271 int statement_position_;
272 int position_;
273
274 Label entry_label_;
275 Label exit_label_;
276
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100277 FrameRegisterState frame_state_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000278
279#ifdef DEBUG
280 const char* comment_;
281#endif
282 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
283};
284
Steve Blocka7e24c12009-10-30 11:49:00 +0000285
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100286} } // namespace v8::internal
Steve Blocka7e24c12009-10-30 11:49:00 +0000287
288#endif // V8_CODEGEN_H_