blob: 71fe6605ebe17c5a139f345be9ea28c02efd8b2b [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 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
31#include "ast.h"
32#include "code-stubs.h"
33#include "runtime.h"
34
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:
38// CodeGenerator::MakeCode
39// CodeGenerator::SetFunctionInfo
40// CodeGenerator::AddDeferred
41// CodeGenerator::masm
42//
43// These methods are either used privately by the shared code or implemented as
44// shared code:
45// CodeGenerator::CodeGenerator
46// CodeGenerator::~CodeGenerator
47// CodeGenerator::ProcessDeferred
48// CodeGenerator::GenCode
49// CodeGenerator::BuildBoilerplate
50// CodeGenerator::ComputeCallInitialize
ager@chromium.org3bf7b912008-11-17 09:09:45 +000051// CodeGenerator::ComputeCallInitializeInLoop
ager@chromium.org7c537e22008-10-16 08:43:32 +000052// CodeGenerator::ProcessDeclarations
53// CodeGenerator::DeclareGlobals
54// CodeGenerator::CheckForInlineRuntimeCall
55// CodeGenerator::GenerateFastCaseSwitchStatement
56// CodeGenerator::GenerateFastCaseSwitchCases
57// CodeGenerator::TryGenerateFastCaseSwitchStatement
58// CodeGenerator::GenerateFastCaseSwitchJumpTable
59// CodeGenerator::FastCaseSwitchMinCaseCount
60// CodeGenerator::FastCaseSwitchMaxOverheadFactor
61
ager@chromium.orga74f0da2008-12-03 16:05:52 +000062#ifdef ARM
ager@chromium.org7c537e22008-10-16 08:43:32 +000063#include "codegen-arm.h"
64#else
65#include "codegen-ia32.h"
66#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000067
68namespace v8 { namespace internal {
69
70
71// Use lazy compilation; defaults to true.
72// NOTE: Do not remove non-lazy compilation until we can properly
73// install extensions with lazy compilation enabled. At the
74// moment, this doesn't work for the extensions in Google3,
75// and we can only run the tests with --nolazy.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076
77
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078// Deferred code objects are small pieces of code that are compiled
79// out of line. They are used to defer the compilation of uncommon
80// paths thereby avoiding expensive jumps around uncommon code parts.
81class DeferredCode: public ZoneObject {
82 public:
83 explicit DeferredCode(CodeGenerator* generator);
84 virtual ~DeferredCode() { }
85
86 virtual void Generate() = 0;
87
88 MacroAssembler* masm() const { return masm_; }
89 CodeGenerator* generator() const { return generator_; }
90
91 Label* enter() { return &enter_; }
92 Label* exit() { return &exit_; }
93
ager@chromium.org236ad962008-09-25 09:45:57 +000094 int statement_position() const { return statement_position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095 int position() const { return position_; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096
97#ifdef DEBUG
98 void set_comment(const char* comment) { comment_ = comment; }
99 const char* comment() const { return comment_; }
100#else
101 inline void set_comment(const char* comment) { }
102 const char* comment() const { return ""; }
103#endif
104
105 protected:
106 // The masm_ field is manipulated when compiling stubs with the
107 // BEGIN_STUB and END_STUB macros. For that reason, it cannot be
108 // constant.
109 MacroAssembler* masm_;
110
111 private:
112 CodeGenerator* const generator_;
113 Label enter_;
114 Label exit_;
ager@chromium.org236ad962008-09-25 09:45:57 +0000115 int statement_position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000116 int position_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117#ifdef DEBUG
118 const char* comment_;
119#endif
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000120 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121};
122
123
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000124// RuntimeStub models code stubs calling entry points in the Runtime class.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000125class RuntimeStub : public CodeStub {
126 public:
mads.s.ager31e71382008-08-13 09:32:07 +0000127 explicit RuntimeStub(Runtime::FunctionId id, int num_arguments)
128 : id_(id), num_arguments_(num_arguments) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000129
130 void Generate(MacroAssembler* masm);
131
mads.s.ager31e71382008-08-13 09:32:07 +0000132 // Disassembler support. It is useful to be able to print the name
133 // of the runtime function called through this stub.
134 static const char* GetNameFromMinorKey(int minor_key) {
135 return Runtime::FunctionForId(IdField::decode(minor_key))->stub_name;
136 }
137
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000138 private:
139 Runtime::FunctionId id_;
mads.s.ager31e71382008-08-13 09:32:07 +0000140 int num_arguments_;
141
142 class ArgumentField: public BitField<int, 0, 16> {};
143 class IdField: public BitField<Runtime::FunctionId, 16, kMinorBits - 16> {};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000144
145 Major MajorKey() { return Runtime; }
mads.s.ager31e71382008-08-13 09:32:07 +0000146 int MinorKey() {
147 return IdField::encode(id_) | ArgumentField::encode(num_arguments_);
148 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000149
150 const char* GetName();
151
152#ifdef DEBUG
153 void Print() {
154 PrintF("RuntimeStub (id %s)\n", Runtime::FunctionForId(id_)->name);
155 }
156#endif
157};
158
159
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000160class StackCheckStub : public CodeStub {
161 public:
162 StackCheckStub() { }
163
164 void Generate(MacroAssembler* masm);
165
166 private:
167
168 const char* GetName() { return "StackCheckStub"; }
169
170 Major MajorKey() { return StackCheck; }
171 int MinorKey() { return 0; }
172};
173
174
175class UnarySubStub : public CodeStub {
176 public:
177 UnarySubStub() { }
178
179 private:
180 Major MajorKey() { return UnarySub; }
181 int MinorKey() { return 0; }
182 void Generate(MacroAssembler* masm);
183
184 const char* GetName() { return "UnarySubStub"; }
185};
186
187
188class CEntryStub : public CodeStub {
189 public:
190 CEntryStub() { }
191
192 void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
193
194 protected:
195 void GenerateBody(MacroAssembler* masm, bool is_debug_break);
196 void GenerateCore(MacroAssembler* masm,
197 Label* throw_normal_exception,
198 Label* throw_out_of_memory_exception,
ager@chromium.org236ad962008-09-25 09:45:57 +0000199 StackFrame::Type frame_type,
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000200 bool do_gc,
201 bool always_allocate_scope);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202 void GenerateThrowTOS(MacroAssembler* masm);
203 void GenerateThrowOutOfMemory(MacroAssembler* masm);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204
205 private:
206 Major MajorKey() { return CEntry; }
207 int MinorKey() { return 0; }
208
209 const char* GetName() { return "CEntryStub"; }
210};
211
212
213class CEntryDebugBreakStub : public CEntryStub {
214 public:
215 CEntryDebugBreakStub() { }
216
217 void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
218
219 private:
220 int MinorKey() { return 1; }
221
222 const char* GetName() { return "CEntryDebugBreakStub"; }
223};
224
225
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000226class JSEntryStub : public CodeStub {
227 public:
228 JSEntryStub() { }
229
230 void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
231
232 protected:
233 void GenerateBody(MacroAssembler* masm, bool is_construct);
234
235 private:
236 Major MajorKey() { return JSEntry; }
237 int MinorKey() { return 0; }
238
239 const char* GetName() { return "JSEntryStub"; }
240};
241
242
243class JSConstructEntryStub : public JSEntryStub {
244 public:
245 JSConstructEntryStub() { }
246
247 void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
248
249 private:
250 int MinorKey() { return 1; }
251
252 const char* GetName() { return "JSConstructEntryStub"; }
253};
254
255
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000256class ArgumentsAccessStub: public CodeStub {
257 public:
258 enum Type {
259 READ_LENGTH,
260 READ_ELEMENT,
261 NEW_OBJECT
262 };
263
264 explicit ArgumentsAccessStub(Type type) : type_(type) { }
265
266 private:
267 Type type_;
268
269 Major MajorKey() { return ArgumentsAccess; }
270 int MinorKey() { return type_; }
ager@chromium.org7c537e22008-10-16 08:43:32 +0000271
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000272 void Generate(MacroAssembler* masm);
ager@chromium.org7c537e22008-10-16 08:43:32 +0000273 void GenerateReadLength(MacroAssembler* masm);
274 void GenerateReadElement(MacroAssembler* masm);
275 void GenerateNewObject(MacroAssembler* masm);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000276
277 const char* GetName() { return "ArgumentsAccessStub"; }
278
279#ifdef DEBUG
280 void Print() {
281 PrintF("ArgumentsAccessStub (type %d)\n", type_);
282 }
283#endif
284};
285
286
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000287} // namespace internal
288} // namespace v8
289
290#endif // V8_CODEGEN_H_