blob: aa3199972349bc5de33f22640e898ae511247362 [file] [log] [blame]
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001// Copyright 2010 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +00002// 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// ProcessDeclarations
62// DeclareGlobals
Steve Blocka7e24c12009-10-30 11:49:00 +000063// CheckForInlineRuntimeCall
Steve Block3ce2e202009-11-05 08:53:23 +000064// AnalyzeCondition
Steve Blocka7e24c12009-10-30 11:49:00 +000065// CodeForFunctionPosition
66// CodeForReturnPosition
67// CodeForStatementPosition
Steve Blockd0582a62009-12-15 09:54:21 +000068// CodeForDoWhileConditionPosition
Steve Blocka7e24c12009-10-30 11:49:00 +000069// CodeForSourcePosition
70
Ben Murdochb0fe1622011-05-05 13:52:32 +010071enum InitState { CONST_INIT, NOT_CONST_INIT };
72enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
73
Ben Murdochbb769b22010-08-11 14:56:33 +010074#if V8_TARGET_ARCH_IA32
75#include "ia32/codegen-ia32.h"
76#elif V8_TARGET_ARCH_X64
77#include "x64/codegen-x64.h"
78#elif V8_TARGET_ARCH_ARM
79#include "arm/codegen-arm.h"
80#elif V8_TARGET_ARCH_MIPS
81#include "mips/codegen-mips.h"
82#else
83#error Unsupported target architecture.
84#endif
85
86#include "register-allocator.h"
87
88namespace v8 {
89namespace internal {
90
Steve Blocka7e24c12009-10-30 11:49:00 +000091// Code generation can be nested. Code generation scopes form a stack
92// of active code generators.
93class CodeGeneratorScope BASE_EMBEDDED {
94 public:
Steve Block44f0eee2011-05-26 01:26:41 +010095 explicit CodeGeneratorScope(Isolate* isolate, CodeGenerator* cgen)
96 : isolate_(isolate) {
97 previous_ = isolate->current_code_generator();
98 isolate->set_current_code_generator(cgen);
Steve Blocka7e24c12009-10-30 11:49:00 +000099 }
100
101 ~CodeGeneratorScope() {
Steve Block44f0eee2011-05-26 01:26:41 +0100102 isolate_->set_current_code_generator(previous_);
Steve Blocka7e24c12009-10-30 11:49:00 +0000103 }
104
Steve Block44f0eee2011-05-26 01:26:41 +0100105 static CodeGenerator* Current(Isolate* isolate) {
106 ASSERT(isolate->current_code_generator() != NULL);
107 return isolate->current_code_generator();
Steve Blocka7e24c12009-10-30 11:49:00 +0000108 }
109
110 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000111 CodeGenerator* previous_;
Steve Block44f0eee2011-05-26 01:26:41 +0100112 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000113};
114
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100115#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
116
117// State of used registers in a virtual frame.
118class FrameRegisterState {
119 public:
120 // Captures the current state of the given frame.
121 explicit FrameRegisterState(VirtualFrame* frame);
122
123 // Saves the state in the stack.
124 void Save(MacroAssembler* masm) const;
125
126 // Restores the state from the stack.
127 void Restore(MacroAssembler* masm) const;
128
129 private:
130 // Constants indicating special actions. They should not be multiples
131 // of kPointerSize so they will not collide with valid offsets from
132 // the frame pointer.
133 static const int kIgnore = -1;
134 static const int kPush = 1;
135
136 // This flag is ored with a valid offset from the frame pointer, so
137 // it should fit in the low zero bits of a valid offset.
138 static const int kSyncedFlag = 2;
139
140 int registers_[RegisterAllocator::kNumRegisters];
141};
142
143#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
144
145
146class FrameRegisterState {
147 public:
148 inline FrameRegisterState(VirtualFrame frame) : frame_(frame) { }
149
150 inline const VirtualFrame* frame() const { return &frame_; }
151
152 private:
153 VirtualFrame frame_;
154};
155
156#else
157
158#error Unsupported target architecture.
159
160#endif
161
162
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100163// RuntimeCallHelper implementation that saves/restores state of a
164// virtual frame.
165class VirtualFrameRuntimeCallHelper : public RuntimeCallHelper {
166 public:
167 // Does not take ownership of |frame_state|.
168 explicit VirtualFrameRuntimeCallHelper(const FrameRegisterState* frame_state)
169 : frame_state_(frame_state) {}
170
171 virtual void BeforeCall(MacroAssembler* masm) const;
172
173 virtual void AfterCall(MacroAssembler* masm) const;
174
175 private:
176 const FrameRegisterState* frame_state_;
177};
178
179
Steve Blocka7e24c12009-10-30 11:49:00 +0000180// Deferred code objects are small pieces of code that are compiled
181// out of line. They are used to defer the compilation of uncommon
182// paths thereby avoiding expensive jumps around uncommon code parts.
183class DeferredCode: public ZoneObject {
184 public:
185 DeferredCode();
186 virtual ~DeferredCode() { }
187
188 virtual void Generate() = 0;
189
190 MacroAssembler* masm() { return masm_; }
191
192 int statement_position() const { return statement_position_; }
193 int position() const { return position_; }
194
195 Label* entry_label() { return &entry_label_; }
196 Label* exit_label() { return &exit_label_; }
197
198#ifdef DEBUG
199 void set_comment(const char* comment) { comment_ = comment; }
200 const char* comment() const { return comment_; }
201#else
202 void set_comment(const char* comment) { }
203 const char* comment() const { return ""; }
204#endif
205
206 inline void Jump();
207 inline void Branch(Condition cc);
208 void BindExit() { masm_->bind(&exit_label_); }
209
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100210 const FrameRegisterState* frame_state() const { return &frame_state_; }
211
Steve Blocka7e24c12009-10-30 11:49:00 +0000212 void SaveRegisters();
213 void RestoreRegisters();
Iain Merrick75681382010-08-19 15:07:18 +0100214 void Exit();
215
216 // If this returns true then all registers will be saved for the duration
217 // of the Generate() call. Otherwise the registers are not saved and the
218 // Generate() call must bracket runtime any runtime calls with calls to
219 // SaveRegisters() and RestoreRegisters(). In this case the Generate
220 // method must also call Exit() in order to return to the non-deferred
221 // code.
222 virtual bool AutoSaveAndRestore() { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000223
224 protected:
225 MacroAssembler* masm_;
226
227 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000228 int statement_position_;
229 int position_;
230
231 Label entry_label_;
232 Label exit_label_;
233
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100234 FrameRegisterState frame_state_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000235
236#ifdef DEBUG
237 const char* comment_;
238#endif
239 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
240};
241
Steve Blocka7e24c12009-10-30 11:49:00 +0000242
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100243} } // namespace v8::internal
Steve Blocka7e24c12009-10-30 11:49:00 +0000244
245#endif // V8_CODEGEN_H_