codegen.h revision 80d68eab642096c1a48b6474d6ec33064b0ad1f5
1// 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
31#include "code-stubs.h"
32#include "runtime.h"
33#include "type-info.h"
34
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
39//   MakeCodePrologue
40//   MakeCodeEpilogue
41//   masm
42//   frame
43//   script
44//   has_valid_frame
45//   SetFrame
46//   DeleteFrame
47//   allocator
48//   AddDeferred
49//   in_spilled_code
50//   set_in_spilled_code
51//   RecordPositions
52//
53// These methods are either used privately by the shared code or implemented as
54// shared code:
55//   CodeGenerator
56//   ~CodeGenerator
57//   ProcessDeferred
58//   Generate
59//   ComputeLazyCompile
60//   BuildFunctionInfo
61//   ComputeCallInitialize
62//   ComputeCallInitializeInLoop
63//   ProcessDeclarations
64//   DeclareGlobals
65//   FindInlineRuntimeLUT
66//   CheckForInlineRuntimeCall
67//   PatchInlineRuntimeEntry
68//   AnalyzeCondition
69//   CodeForFunctionPosition
70//   CodeForReturnPosition
71//   CodeForStatementPosition
72//   CodeForDoWhileConditionPosition
73//   CodeForSourcePosition
74
75
76#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)                                                        \
88  F(StringCharCodeAt, 2, 1)                                                  \
89  F(StringCharFromCode, 1, 1)                                                \
90  F(StringCharAt, 2, 1)                                                      \
91  F(ObjectEquals, 2, 1)                                                      \
92  F(Log, 3, 1)                                                               \
93  F(RandomHeapNumber, 0, 1)                                                  \
94  F(IsObject, 1, 1)                                                          \
95  F(IsFunction, 1, 1)                                                        \
96  F(IsUndetectableObject, 1, 1)                                              \
97  F(IsSpecObject, 1, 1)                                                      \
98  F(IsStringWrapperSafeForDefaultValueOf, 1, 1)                              \
99  F(StringAdd, 2, 1)                                                         \
100  F(SubString, 3, 1)                                                         \
101  F(StringCompare, 2, 1)                                                     \
102  F(RegExpExec, 4, 1)                                                        \
103  F(RegExpConstructResult, 3, 1)                                             \
104  F(RegExpCloneResult, 1, 1)                                                 \
105  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)                                                           \
111  F(MathSqrt, 1, 1)                                                          \
112  F(IsRegExpEquivalent, 2, 1)                                                \
113  F(HasCachedArrayIndex, 1, 1)                                               \
114  F(GetCachedArrayIndex, 1, 1)
115
116
117#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
134// 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
157
158#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
206// 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
223// 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
253  const FrameRegisterState* frame_state() const { return &frame_state_; }
254
255  void SaveRegisters();
256  void RestoreRegisters();
257  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; }
266
267 protected:
268  MacroAssembler* masm_;
269
270 private:
271  int statement_position_;
272  int position_;
273
274  Label entry_label_;
275  Label exit_label_;
276
277  FrameRegisterState frame_state_;
278
279#ifdef DEBUG
280  const char* comment_;
281#endif
282  DISALLOW_COPY_AND_ASSIGN(DeferredCode);
283};
284
285
286} }  // namespace v8::internal
287
288#endif  // V8_CODEGEN_H_
289