blob: 8f923dd34b294775b0950cab5d05d9d60bfc7d4d [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// ComputeCallInitialize
62// ComputeCallInitializeInLoop
63// ProcessDeclarations
64// DeclareGlobals
65// CheckForInlineRuntimeCall
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +000066// AnalyzeCondition
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000067// CodeForFunctionPosition
68// CodeForReturnPosition
69// CodeForStatementPosition
ager@chromium.orgc4c92722009-11-18 14:12:51 +000070// CodeForDoWhileConditionPosition
kasperl@chromium.org8ccb0be2009-04-07 07:21:39 +000071// CodeForSourcePosition
ager@chromium.org7c537e22008-10-16 08:43:32 +000072
lrn@chromium.orgc4e51ac2010-08-09 09:47:21 +000073#if V8_TARGET_ARCH_IA32
74#include "ia32/codegen-ia32.h"
75#elif V8_TARGET_ARCH_X64
76#include "x64/codegen-x64.h"
77#elif V8_TARGET_ARCH_ARM
78#include "arm/codegen-arm.h"
79#elif V8_TARGET_ARCH_MIPS
80#include "mips/codegen-mips.h"
81#else
82#error Unsupported target architecture.
83#endif
84
85#include "register-allocator.h"
86
87namespace v8 {
88namespace internal {
89
kasperl@chromium.orgb3284ad2009-05-18 06:12:45 +000090// Code generation can be nested. Code generation scopes form a stack
91// of active code generators.
92class CodeGeneratorScope BASE_EMBEDDED {
93 public:
94 explicit CodeGeneratorScope(CodeGenerator* cgen) {
95 previous_ = top_;
96 top_ = cgen;
97 }
98
99 ~CodeGeneratorScope() {
100 top_ = previous_;
101 }
102
103 static CodeGenerator* Current() {
104 ASSERT(top_ != NULL);
105 return top_;
106 }
107
108 private:
109 static CodeGenerator* top_;
110 CodeGenerator* previous_;
111};
112
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000113
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000114#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
115
116// State of used registers in a virtual frame.
117class FrameRegisterState {
118 public:
119 // Captures the current state of the given frame.
120 explicit FrameRegisterState(VirtualFrame* frame);
121
122 // Saves the state in the stack.
123 void Save(MacroAssembler* masm) const;
124
125 // Restores the state from the stack.
126 void Restore(MacroAssembler* masm) const;
127
128 private:
129 // Constants indicating special actions. They should not be multiples
130 // of kPointerSize so they will not collide with valid offsets from
131 // the frame pointer.
132 static const int kIgnore = -1;
133 static const int kPush = 1;
134
135 // This flag is ored with a valid offset from the frame pointer, so
136 // it should fit in the low zero bits of a valid offset.
137 static const int kSyncedFlag = 2;
138
139 int registers_[RegisterAllocator::kNumRegisters];
140};
141
142#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS
143
144
145class FrameRegisterState {
146 public:
147 inline FrameRegisterState(VirtualFrame frame) : frame_(frame) { }
148
149 inline const VirtualFrame* frame() const { return &frame_; }
150
151 private:
152 VirtualFrame frame_;
153};
154
155#else
156
157#error Unsupported target architecture.
158
159#endif
160
161
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000162// RuntimeCallHelper implementation that saves/restores state of a
163// virtual frame.
164class VirtualFrameRuntimeCallHelper : public RuntimeCallHelper {
165 public:
166 // Does not take ownership of |frame_state|.
167 explicit VirtualFrameRuntimeCallHelper(const FrameRegisterState* frame_state)
168 : frame_state_(frame_state) {}
169
170 virtual void BeforeCall(MacroAssembler* masm) const;
171
172 virtual void AfterCall(MacroAssembler* masm) const;
173
174 private:
175 const FrameRegisterState* frame_state_;
176};
177
178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179// Deferred code objects are small pieces of code that are compiled
180// out of line. They are used to defer the compilation of uncommon
181// paths thereby avoiding expensive jumps around uncommon code parts.
182class DeferredCode: public ZoneObject {
183 public:
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000184 DeferredCode();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000185 virtual ~DeferredCode() { }
186
187 virtual void Generate() = 0;
188
ager@chromium.orge2902be2009-06-08 12:21:35 +0000189 MacroAssembler* masm() { return masm_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190
ager@chromium.org236ad962008-09-25 09:45:57 +0000191 int statement_position() const { return statement_position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192 int position() const { return position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193
ager@chromium.orge2902be2009-06-08 12:21:35 +0000194 Label* entry_label() { return &entry_label_; }
195 Label* exit_label() { return &exit_label_; }
196
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000197#ifdef DEBUG
198 void set_comment(const char* comment) { comment_ = comment; }
199 const char* comment() const { return comment_; }
200#else
sgjesse@chromium.org755c5b12009-05-29 11:04:38 +0000201 void set_comment(const char* comment) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202 const char* comment() const { return ""; }
203#endif
204
ager@chromium.orge2902be2009-06-08 12:21:35 +0000205 inline void Jump();
206 inline void Branch(Condition cc);
207 void BindExit() { masm_->bind(&exit_label_); }
208
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000209 const FrameRegisterState* frame_state() const { return &frame_state_; }
210
ager@chromium.orge2902be2009-06-08 12:21:35 +0000211 void SaveRegisters();
212 void RestoreRegisters();
vegorov@chromium.org26c16f82010-08-11 13:41:03 +0000213 void Exit();
214
215 // If this returns true then all registers will be saved for the duration
216 // of the Generate() call. Otherwise the registers are not saved and the
217 // Generate() call must bracket runtime any runtime calls with calls to
218 // SaveRegisters() and RestoreRegisters(). In this case the Generate
219 // method must also call Exit() in order to return to the non-deferred
220 // code.
221 virtual bool AutoSaveAndRestore() { return true; }
ager@chromium.orge2902be2009-06-08 12:21:35 +0000222
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223 protected:
ager@chromium.orge2902be2009-06-08 12:21:35 +0000224 MacroAssembler* masm_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225
226 private:
ager@chromium.org236ad962008-09-25 09:45:57 +0000227 int statement_position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000228 int position_;
ager@chromium.orge2902be2009-06-08 12:21:35 +0000229
230 Label entry_label_;
231 Label exit_label_;
232
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000233 FrameRegisterState frame_state_;
ager@chromium.orge2902be2009-06-08 12:21:35 +0000234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235#ifdef DEBUG
236 const char* comment_;
237#endif
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000238 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000239};
240
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000241
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000242} } // namespace v8::internal
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243
244#endif // V8_CODEGEN_H_