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