blob: 23b36f07a8f19e11f5449a198de989312df969f1 [file] [log] [blame]
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +00001// Copyright 2010 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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_
ager@chromium.org7c537e22008-10-16 08:43:32 +000029#define V8_CODEGEN_H_
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000030
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031#include "code-stubs.h"
32#include "runtime.h"
sgjesse@chromium.orgdf7a2842010-03-25 14:34:15 +000033#include "type-info.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
ager@chromium.org7c537e22008-10-16 08:43:32 +000035// 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:
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000038// MakeCode
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000039// MakeCodePrologue
40// MakeCodeEpilogue
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000041// masm
42// frame
ager@chromium.orgc4c92722009-11-18 14:12:51 +000043// script
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000044// has_valid_frame
45// SetFrame
46// DeleteFrame
47// allocator
48// AddDeferred
49// in_spilled_code
50// set_in_spilled_code
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000051// RecordPositions
ager@chromium.org7c537e22008-10-16 08:43:32 +000052//
53// These methods are either used privately by the shared code or implemented as
54// shared code:
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000055// CodeGenerator
56// ~CodeGenerator
57// ProcessDeferred
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +000058// Generate
ager@chromium.org3811b432009-10-28 14:53:37 +000059// ComputeLazyCompile
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +000060// BuildFunctionInfo
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000061// ProcessDeclarations
62// DeclareGlobals
63// CheckForInlineRuntimeCall
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000064// AnalyzeCondition
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000065// CodeForFunctionPosition
66// CodeForReturnPosition
67// CodeForStatementPosition
ager@chromium.orgc4c92722009-11-18 14:12:51 +000068// CodeForDoWhileConditionPosition
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000069// CodeForSourcePosition
ager@chromium.org7c537e22008-10-16 08:43:32 +000070
kasperl@chromium.orga5551262010-12-07 12:49:48 +000071enum InitState { CONST_INIT, NOT_CONST_INIT };
72enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
73
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +000074#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
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +000091// Code generation can be nested. Code generation scopes form a stack
92// of active code generators.
93class CodeGeneratorScope BASE_EMBEDDED {
94 public:
95 explicit CodeGeneratorScope(CodeGenerator* cgen) {
96 previous_ = top_;
97 top_ = cgen;
98 }
99
100 ~CodeGeneratorScope() {
101 top_ = previous_;
102 }
103
104 static CodeGenerator* Current() {
105 ASSERT(top_ != NULL);
106 return top_;
107 }
108
109 private:
110 static CodeGenerator* top_;
111 CodeGenerator* previous_;
112};
113
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000114
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000115#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
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000163// 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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +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:
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000185 DeferredCode();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000186 virtual ~DeferredCode() { }
187
188 virtual void Generate() = 0;
189
ager@chromium.orge2902be2009-06-08 12:21:35 +0000190 MacroAssembler* masm() { return masm_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000191
ager@chromium.org236ad962008-09-25 09:45:57 +0000192 int statement_position() const { return statement_position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193 int position() const { return position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194
ager@chromium.orge2902be2009-06-08 12:21:35 +0000195 Label* entry_label() { return &entry_label_; }
196 Label* exit_label() { return &exit_label_; }
197
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198#ifdef DEBUG
199 void set_comment(const char* comment) { comment_ = comment; }
200 const char* comment() const { return comment_; }
201#else
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000202 void set_comment(const char* comment) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000203 const char* comment() const { return ""; }
204#endif
205
ager@chromium.orge2902be2009-06-08 12:21:35 +0000206 inline void Jump();
207 inline void Branch(Condition cc);
208 void BindExit() { masm_->bind(&exit_label_); }
209
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000210 const FrameRegisterState* frame_state() const { return &frame_state_; }
211
ager@chromium.orge2902be2009-06-08 12:21:35 +0000212 void SaveRegisters();
213 void RestoreRegisters();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000214 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; }
ager@chromium.orge2902be2009-06-08 12:21:35 +0000223
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224 protected:
ager@chromium.orge2902be2009-06-08 12:21:35 +0000225 MacroAssembler* masm_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000226
227 private:
ager@chromium.org236ad962008-09-25 09:45:57 +0000228 int statement_position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229 int position_;
ager@chromium.orge2902be2009-06-08 12:21:35 +0000230
231 Label entry_label_;
232 Label exit_label_;
233
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000234 FrameRegisterState frame_state_;
ager@chromium.orge2902be2009-06-08 12:21:35 +0000235
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236#ifdef DEBUG
237 const char* comment_;
238#endif
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000239 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240};
241
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000243} } // namespace v8::internal
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000244
245#endif // V8_CODEGEN_H_