blob: 358c6fccd3239cca4021f99c40f8cbd9e0a7b6f9 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// 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
Steve Blocka7e24c12009-10-30 11:49:00 +000031#include "code-stubs.h"
32#include "runtime.h"
Steve Block6ded16b2010-05-10 14:33:55 +010033#include "type-info.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000034
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
Steve Block3ce2e202009-11-05 08:53:23 +000039// MakeCodePrologue
40// MakeCodeEpilogue
Steve Blocka7e24c12009-10-30 11:49:00 +000041// masm
42// frame
Steve Blockd0582a62009-12-15 09:54:21 +000043// script
Steve Blocka7e24c12009-10-30 11:49:00 +000044// has_valid_frame
45// SetFrame
46// DeleteFrame
47// allocator
48// AddDeferred
49// in_spilled_code
50// set_in_spilled_code
Steve Block3ce2e202009-11-05 08:53:23 +000051// RecordPositions
Steve Blocka7e24c12009-10-30 11:49:00 +000052//
53// These methods are either used privately by the shared code or implemented as
54// shared code:
55// CodeGenerator
56// ~CodeGenerator
57// ProcessDeferred
Leon Clarke4515c472010-02-03 11:58:03 +000058// Generate
Steve Block3ce2e202009-11-05 08:53:23 +000059// ComputeLazyCompile
Steve Block6ded16b2010-05-10 14:33:55 +010060// BuildFunctionInfo
Steve Blocka7e24c12009-10-30 11:49:00 +000061// ComputeCallInitialize
62// ComputeCallInitializeInLoop
63// ProcessDeclarations
64// DeclareGlobals
65// FindInlineRuntimeLUT
66// CheckForInlineRuntimeCall
67// PatchInlineRuntimeEntry
Steve Block3ce2e202009-11-05 08:53:23 +000068// AnalyzeCondition
Steve Blocka7e24c12009-10-30 11:49:00 +000069// CodeForFunctionPosition
70// CodeForReturnPosition
71// CodeForStatementPosition
Steve Blockd0582a62009-12-15 09:54:21 +000072// CodeForDoWhileConditionPosition
Steve Blocka7e24c12009-10-30 11:49:00 +000073// CodeForSourcePosition
74
75
76// Mode to overwrite BinaryExpression values.
77enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
78
79// Types of uncatchable exceptions.
80enum UncatchableExceptionType { OUT_OF_MEMORY, TERMINATION };
81
82
83#if V8_TARGET_ARCH_IA32
84#include "ia32/codegen-ia32.h"
85#elif V8_TARGET_ARCH_X64
86#include "x64/codegen-x64.h"
87#elif V8_TARGET_ARCH_ARM
88#include "arm/codegen-arm.h"
Andrei Popescu31002712010-02-23 13:46:05 +000089#elif V8_TARGET_ARCH_MIPS
90#include "mips/codegen-mips.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000091#else
92#error Unsupported target architecture.
93#endif
94
95#include "register-allocator.h"
96
97namespace v8 {
98namespace internal {
99
100
Steve Block6ded16b2010-05-10 14:33:55 +0100101#define INLINE_RUNTIME_FUNCTION_LIST(F) \
102 F(IsSmi, 1, 1) \
103 F(IsNonNegativeSmi, 1, 1) \
104 F(IsArray, 1, 1) \
105 F(IsRegExp, 1, 1) \
106 F(CallFunction, -1 /* receiver + n args + function */, 1) \
107 F(IsConstructCall, 0, 1) \
108 F(ArgumentsLength, 0, 1) \
109 F(Arguments, 1, 1) \
110 F(ClassOf, 1, 1) \
111 F(ValueOf, 1, 1) \
112 F(SetValueOf, 2, 1) \
113 F(FastCharCodeAt, 2, 1) \
114 F(CharFromCode, 1, 1) \
115 F(ObjectEquals, 2, 1) \
116 F(Log, 3, 1) \
Leon Clarkef7060e22010-06-03 12:02:55 +0100117 F(RandomHeapNumber, 0, 1) \
Steve Block6ded16b2010-05-10 14:33:55 +0100118 F(IsObject, 1, 1) \
119 F(IsFunction, 1, 1) \
120 F(IsUndetectableObject, 1, 1) \
121 F(StringAdd, 2, 1) \
122 F(SubString, 3, 1) \
123 F(StringCompare, 2, 1) \
124 F(RegExpExec, 4, 1) \
125 F(RegExpConstructResult, 3, 1) \
126 F(GetFromCache, 2, 1) \
127 F(NumberToString, 1, 1) \
128 F(SwapElements, 3, 1) \
129 F(MathPow, 2, 1) \
130 F(MathSin, 1, 1) \
131 F(MathCos, 1, 1) \
132 F(MathSqrt, 1, 1)
133
134
Andrei Popescu31002712010-02-23 13:46:05 +0000135// Support for "structured" code comments.
136#ifdef DEBUG
137
138class Comment BASE_EMBEDDED {
139 public:
140 Comment(MacroAssembler* masm, const char* msg);
141 ~Comment();
142
143 private:
144 MacroAssembler* masm_;
145 const char* msg_;
146};
147
148#else
149
150class Comment BASE_EMBEDDED {
151 public:
152 Comment(MacroAssembler*, const char*) {}
153};
154
155#endif // DEBUG
156
157
Steve Blocka7e24c12009-10-30 11:49:00 +0000158// Code generation can be nested. Code generation scopes form a stack
159// of active code generators.
160class CodeGeneratorScope BASE_EMBEDDED {
161 public:
162 explicit CodeGeneratorScope(CodeGenerator* cgen) {
163 previous_ = top_;
164 top_ = cgen;
165 }
166
167 ~CodeGeneratorScope() {
168 top_ = previous_;
169 }
170
171 static CodeGenerator* Current() {
172 ASSERT(top_ != NULL);
173 return top_;
174 }
175
176 private:
177 static CodeGenerator* top_;
178 CodeGenerator* previous_;
179};
180
181
182// Deferred code objects are small pieces of code that are compiled
183// out of line. They are used to defer the compilation of uncommon
184// paths thereby avoiding expensive jumps around uncommon code parts.
185class DeferredCode: public ZoneObject {
186 public:
187 DeferredCode();
188 virtual ~DeferredCode() { }
189
190 virtual void Generate() = 0;
191
192 MacroAssembler* masm() { return masm_; }
193
194 int statement_position() const { return statement_position_; }
195 int position() const { return position_; }
196
197 Label* entry_label() { return &entry_label_; }
198 Label* exit_label() { return &exit_label_; }
199
200#ifdef DEBUG
201 void set_comment(const char* comment) { comment_ = comment; }
202 const char* comment() const { return comment_; }
203#else
204 void set_comment(const char* comment) { }
205 const char* comment() const { return ""; }
206#endif
207
208 inline void Jump();
209 inline void Branch(Condition cc);
210 void BindExit() { masm_->bind(&exit_label_); }
211
212 void SaveRegisters();
213 void RestoreRegisters();
214
215 protected:
216 MacroAssembler* masm_;
217
218 private:
219 // Constants indicating special actions. They should not be multiples
220 // of kPointerSize so they will not collide with valid offsets from
221 // the frame pointer.
222 static const int kIgnore = -1;
223 static const int kPush = 1;
224
225 // This flag is ored with a valid offset from the frame pointer, so
226 // it should fit in the low zero bits of a valid offset.
227 static const int kSyncedFlag = 2;
228
229 int statement_position_;
230 int position_;
231
232 Label entry_label_;
233 Label exit_label_;
234
Steve Block6ded16b2010-05-10 14:33:55 +0100235 // C++ doesn't allow zero length arrays, so we make the array length 1 even
236 // if we don't need it.
237 static const int kRegistersArrayLength =
238 (RegisterAllocator::kNumRegisters == 0) ?
239 1 : RegisterAllocator::kNumRegisters;
240 int registers_[kRegistersArrayLength];
Steve Blocka7e24c12009-10-30 11:49:00 +0000241
242#ifdef DEBUG
243 const char* comment_;
244#endif
245 DISALLOW_COPY_AND_ASSIGN(DeferredCode);
246};
247
Steve Blocka7e24c12009-10-30 11:49:00 +0000248class StackCheckStub : public CodeStub {
249 public:
250 StackCheckStub() { }
251
252 void Generate(MacroAssembler* masm);
253
254 private:
255
256 const char* GetName() { return "StackCheckStub"; }
257
258 Major MajorKey() { return StackCheck; }
259 int MinorKey() { return 0; }
260};
261
262
Leon Clarkee46be812010-01-19 14:06:41 +0000263class FastNewClosureStub : public CodeStub {
264 public:
265 void Generate(MacroAssembler* masm);
266
267 private:
268 const char* GetName() { return "FastNewClosureStub"; }
269 Major MajorKey() { return FastNewClosure; }
270 int MinorKey() { return 0; }
271};
272
273
274class FastNewContextStub : public CodeStub {
275 public:
276 static const int kMaximumSlots = 64;
277
278 explicit FastNewContextStub(int slots) : slots_(slots) {
279 ASSERT(slots_ > 0 && slots <= kMaximumSlots);
280 }
281
282 void Generate(MacroAssembler* masm);
283
284 private:
285 int slots_;
286
287 const char* GetName() { return "FastNewContextStub"; }
288 Major MajorKey() { return FastNewContext; }
289 int MinorKey() { return slots_; }
290};
291
292
293class FastCloneShallowArrayStub : public CodeStub {
294 public:
295 static const int kMaximumLength = 8;
296
297 explicit FastCloneShallowArrayStub(int length) : length_(length) {
298 ASSERT(length >= 0 && length <= kMaximumLength);
299 }
300
301 void Generate(MacroAssembler* masm);
302
303 private:
304 int length_;
305
306 const char* GetName() { return "FastCloneShallowArrayStub"; }
307 Major MajorKey() { return FastCloneShallowArray; }
308 int MinorKey() { return length_; }
309};
310
311
Steve Blocka7e24c12009-10-30 11:49:00 +0000312class InstanceofStub: public CodeStub {
313 public:
314 InstanceofStub() { }
315
316 void Generate(MacroAssembler* masm);
317
318 private:
319 Major MajorKey() { return Instanceof; }
320 int MinorKey() { return 0; }
321};
322
323
Leon Clarkee46be812010-01-19 14:06:41 +0000324class GenericUnaryOpStub : public CodeStub {
Steve Blocka7e24c12009-10-30 11:49:00 +0000325 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000326 GenericUnaryOpStub(Token::Value op, bool overwrite)
327 : op_(op), overwrite_(overwrite) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000328
329 private:
Leon Clarkee46be812010-01-19 14:06:41 +0000330 Token::Value op_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000331 bool overwrite_;
Leon Clarkee46be812010-01-19 14:06:41 +0000332
333 class OverwriteField: public BitField<int, 0, 1> {};
334 class OpField: public BitField<Token::Value, 1, kMinorBits - 1> {};
335
336 Major MajorKey() { return GenericUnaryOp; }
337 int MinorKey() {
338 return OpField::encode(op_) | OverwriteField::encode(overwrite_);
339 }
340
Steve Blocka7e24c12009-10-30 11:49:00 +0000341 void Generate(MacroAssembler* masm);
342
Leon Clarkee46be812010-01-19 14:06:41 +0000343 const char* GetName();
344};
345
346
347enum NaNInformation {
348 kBothCouldBeNaN,
349 kCantBothBeNaN
Steve Blocka7e24c12009-10-30 11:49:00 +0000350};
351
352
353class CompareStub: public CodeStub {
354 public:
Leon Clarkee46be812010-01-19 14:06:41 +0000355 CompareStub(Condition cc,
356 bool strict,
Steve Block6ded16b2010-05-10 14:33:55 +0100357 NaNInformation nan_info = kBothCouldBeNaN,
358 bool include_number_compare = true) :
359 cc_(cc),
360 strict_(strict),
361 never_nan_nan_(nan_info == kCantBothBeNaN),
362 include_number_compare_(include_number_compare),
363 name_(NULL) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000364
365 void Generate(MacroAssembler* masm);
366
367 private:
368 Condition cc_;
369 bool strict_;
Leon Clarkee46be812010-01-19 14:06:41 +0000370 // Only used for 'equal' comparisons. Tells the stub that we already know
371 // that at least one side of the comparison is not NaN. This allows the
372 // stub to use object identity in the positive case. We ignore it when
373 // generating the minor key for other comparisons to avoid creating more
374 // stubs.
375 bool never_nan_nan_;
Steve Block6ded16b2010-05-10 14:33:55 +0100376 // Do generate the number comparison code in the stub. Stubs without number
377 // comparison code is used when the number comparison has been inlined, and
378 // the stub will be called if one of the operands is not a number.
379 bool include_number_compare_;
380
381 // Encoding of the minor key CCCCCCCCCCCCCCNS.
382 class StrictField: public BitField<bool, 0, 1> {};
383 class NeverNanNanField: public BitField<bool, 1, 1> {};
384 class IncludeNumberCompareField: public BitField<bool, 2, 1> {};
385 class ConditionField: public BitField<int, 3, 13> {};
Steve Blocka7e24c12009-10-30 11:49:00 +0000386
387 Major MajorKey() { return Compare; }
388
389 int MinorKey();
390
391 // Branch to the label if the given object isn't a symbol.
392 void BranchIfNonSymbol(MacroAssembler* masm,
393 Label* label,
394 Register object,
395 Register scratch);
396
Leon Clarkee46be812010-01-19 14:06:41 +0000397 // Unfortunately you have to run without snapshots to see most of these
398 // names in the profile since most compare stubs end up in the snapshot.
Steve Block6ded16b2010-05-10 14:33:55 +0100399 char* name_;
Leon Clarkee46be812010-01-19 14:06:41 +0000400 const char* GetName();
Steve Blocka7e24c12009-10-30 11:49:00 +0000401#ifdef DEBUG
402 void Print() {
Steve Block6ded16b2010-05-10 14:33:55 +0100403 PrintF("CompareStub (cc %d), (strict %s), "
404 "(never_nan_nan %s), (number_compare %s)\n",
Steve Blocka7e24c12009-10-30 11:49:00 +0000405 static_cast<int>(cc_),
Steve Block6ded16b2010-05-10 14:33:55 +0100406 strict_ ? "true" : "false",
407 never_nan_nan_ ? "true" : "false",
408 include_number_compare_ ? "included" : "not included");
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 }
410#endif
411};
412
413
414class CEntryStub : public CodeStub {
415 public:
Leon Clarke4515c472010-02-03 11:58:03 +0000416 explicit CEntryStub(int result_size,
417 ExitFrame::Mode mode = ExitFrame::MODE_NORMAL)
418 : result_size_(result_size), mode_(mode) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000419
Leon Clarke4515c472010-02-03 11:58:03 +0000420 void Generate(MacroAssembler* masm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000421
Leon Clarke4515c472010-02-03 11:58:03 +0000422 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000423 void GenerateCore(MacroAssembler* masm,
424 Label* throw_normal_exception,
425 Label* throw_termination_exception,
426 Label* throw_out_of_memory_exception,
Steve Blocka7e24c12009-10-30 11:49:00 +0000427 bool do_gc,
Steve Block6ded16b2010-05-10 14:33:55 +0100428 bool always_allocate_scope,
429 int alignment_skew = 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000430 void GenerateThrowTOS(MacroAssembler* masm);
431 void GenerateThrowUncatchable(MacroAssembler* masm,
432 UncatchableExceptionType type);
Leon Clarke4515c472010-02-03 11:58:03 +0000433
Steve Blocka7e24c12009-10-30 11:49:00 +0000434 // Number of pointers/values returned.
Leon Clarke4515c472010-02-03 11:58:03 +0000435 const int result_size_;
436 const ExitFrame::Mode mode_;
437
438 // Minor key encoding
439 class ExitFrameModeBits: public BitField<ExitFrame::Mode, 0, 1> {};
440 class IndirectResultBits: public BitField<bool, 1, 1> {};
Steve Blocka7e24c12009-10-30 11:49:00 +0000441
442 Major MajorKey() { return CEntry; }
443 // Minor key must differ if different result_size_ values means different
444 // code is generated.
445 int MinorKey();
446
447 const char* GetName() { return "CEntryStub"; }
448};
449
450
Steve Blockd0582a62009-12-15 09:54:21 +0000451class ApiGetterEntryStub : public CodeStub {
452 public:
453 ApiGetterEntryStub(Handle<AccessorInfo> info,
454 ApiFunction* fun)
455 : info_(info),
456 fun_(fun) { }
457 void Generate(MacroAssembler* masm);
458 virtual bool has_custom_cache() { return true; }
459 virtual bool GetCustomCache(Code** code_out);
460 virtual void SetCustomCache(Code* value);
461
Steve Block6ded16b2010-05-10 14:33:55 +0100462 static const int kStackSpace = 5;
Steve Blockd0582a62009-12-15 09:54:21 +0000463 static const int kArgc = 4;
464 private:
465 Handle<AccessorInfo> info() { return info_; }
466 ApiFunction* fun() { return fun_; }
467 Major MajorKey() { return NoCache; }
468 int MinorKey() { return 0; }
469 const char* GetName() { return "ApiEntryStub"; }
470 // The accessor info associated with the function.
471 Handle<AccessorInfo> info_;
472 // The function to be called.
473 ApiFunction* fun_;
474};
475
476
Steve Blocka7e24c12009-10-30 11:49:00 +0000477class JSEntryStub : public CodeStub {
478 public:
479 JSEntryStub() { }
480
481 void Generate(MacroAssembler* masm) { GenerateBody(masm, false); }
482
483 protected:
484 void GenerateBody(MacroAssembler* masm, bool is_construct);
485
486 private:
487 Major MajorKey() { return JSEntry; }
488 int MinorKey() { return 0; }
489
490 const char* GetName() { return "JSEntryStub"; }
491};
492
493
494class JSConstructEntryStub : public JSEntryStub {
495 public:
496 JSConstructEntryStub() { }
497
498 void Generate(MacroAssembler* masm) { GenerateBody(masm, true); }
499
500 private:
501 int MinorKey() { return 1; }
502
503 const char* GetName() { return "JSConstructEntryStub"; }
504};
505
506
507class ArgumentsAccessStub: public CodeStub {
508 public:
509 enum Type {
Steve Blocka7e24c12009-10-30 11:49:00 +0000510 READ_ELEMENT,
511 NEW_OBJECT
512 };
513
514 explicit ArgumentsAccessStub(Type type) : type_(type) { }
515
516 private:
517 Type type_;
518
519 Major MajorKey() { return ArgumentsAccess; }
520 int MinorKey() { return type_; }
521
522 void Generate(MacroAssembler* masm);
Steve Blocka7e24c12009-10-30 11:49:00 +0000523 void GenerateReadElement(MacroAssembler* masm);
524 void GenerateNewObject(MacroAssembler* masm);
525
526 const char* GetName() { return "ArgumentsAccessStub"; }
527
528#ifdef DEBUG
529 void Print() {
530 PrintF("ArgumentsAccessStub (type %d)\n", type_);
531 }
532#endif
533};
534
535
Leon Clarkee46be812010-01-19 14:06:41 +0000536class RegExpExecStub: public CodeStub {
537 public:
538 RegExpExecStub() { }
539
540 private:
541 Major MajorKey() { return RegExpExec; }
542 int MinorKey() { return 0; }
543
544 void Generate(MacroAssembler* masm);
545
546 const char* GetName() { return "RegExpExecStub"; }
547
548#ifdef DEBUG
549 void Print() {
550 PrintF("RegExpExecStub\n");
551 }
552#endif
553};
554
555
556class CallFunctionStub: public CodeStub {
557 public:
558 CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags)
559 : argc_(argc), in_loop_(in_loop), flags_(flags) { }
560
561 void Generate(MacroAssembler* masm);
562
563 private:
564 int argc_;
565 InLoopFlag in_loop_;
566 CallFunctionFlags flags_;
567
568#ifdef DEBUG
569 void Print() {
570 PrintF("CallFunctionStub (args %d, in_loop %d, flags %d)\n",
571 argc_,
572 static_cast<int>(in_loop_),
573 static_cast<int>(flags_));
574 }
575#endif
576
Andrei Popescu402d9372010-02-26 13:31:12 +0000577 // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
Leon Clarkee46be812010-01-19 14:06:41 +0000578 class InLoopBits: public BitField<InLoopFlag, 0, 1> {};
579 class FlagBits: public BitField<CallFunctionFlags, 1, 1> {};
Andrei Popescu402d9372010-02-26 13:31:12 +0000580 class ArgcBits: public BitField<int, 2, 32 - 2> {};
Leon Clarkee46be812010-01-19 14:06:41 +0000581
582 Major MajorKey() { return CallFunction; }
583 int MinorKey() {
Andrei Popescu402d9372010-02-26 13:31:12 +0000584 // Encode the parameters in a unique 32 bit value.
Leon Clarkee46be812010-01-19 14:06:41 +0000585 return InLoopBits::encode(in_loop_)
586 | FlagBits::encode(flags_)
587 | ArgcBits::encode(argc_);
588 }
589
590 InLoopFlag InLoop() { return in_loop_; }
591 bool ReceiverMightBeValue() {
592 return (flags_ & RECEIVER_MIGHT_BE_VALUE) != 0;
593 }
594
595 public:
596 static int ExtractArgcFromMinorKey(int minor_key) {
597 return ArgcBits::decode(minor_key);
598 }
599};
600
601
602class ToBooleanStub: public CodeStub {
603 public:
604 ToBooleanStub() { }
605
606 void Generate(MacroAssembler* masm);
607
608 private:
609 Major MajorKey() { return ToBoolean; }
610 int MinorKey() { return 0; }
611};
612
613
Steve Blocka7e24c12009-10-30 11:49:00 +0000614} // namespace internal
615} // namespace v8
616
617#endif // V8_CODEGEN_H_