codegen-x64.h revision 8a31eba00023874d4a1dcdc5f411cc4336776874
1// Copyright 2010 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_X64_CODEGEN_X64_H_ 29#define V8_X64_CODEGEN_X64_H_ 30 31#include "ast.h" 32#include "ic-inl.h" 33#include "jump-target-heavy.h" 34 35namespace v8 { 36namespace internal { 37 38// Forward declarations 39class CompilationInfo; 40class DeferredCode; 41class RegisterAllocator; 42class RegisterFile; 43 44enum InitState { CONST_INIT, NOT_CONST_INIT }; 45enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; 46 47 48// ------------------------------------------------------------------------- 49// Reference support 50 51// A reference is a C++ stack-allocated object that puts a 52// reference on the virtual frame. The reference may be consumed 53// by GetValue, TakeValue, SetValue, and Codegen::UnloadReference. 54// When the lifetime (scope) of a valid reference ends, it must have 55// been consumed, and be in state UNLOADED. 56class Reference BASE_EMBEDDED { 57 public: 58 // The values of the types is important, see size(). 59 enum Type { UNLOADED = -2, ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; 60 61 Reference(CodeGenerator* cgen, 62 Expression* expression, 63 bool persist_after_get = false); 64 ~Reference(); 65 66 Expression* expression() const { return expression_; } 67 Type type() const { return type_; } 68 void set_type(Type value) { 69 ASSERT_EQ(ILLEGAL, type_); 70 type_ = value; 71 } 72 73 void set_unloaded() { 74 ASSERT_NE(ILLEGAL, type_); 75 ASSERT_NE(UNLOADED, type_); 76 type_ = UNLOADED; 77 } 78 // The size the reference takes up on the stack. 79 int size() const { 80 return (type_ < SLOT) ? 0 : type_; 81 } 82 83 bool is_illegal() const { return type_ == ILLEGAL; } 84 bool is_slot() const { return type_ == SLOT; } 85 bool is_property() const { return type_ == NAMED || type_ == KEYED; } 86 bool is_unloaded() const { return type_ == UNLOADED; } 87 88 // Return the name. Only valid for named property references. 89 Handle<String> GetName(); 90 91 // Generate code to push the value of the reference on top of the 92 // expression stack. The reference is expected to be already on top of 93 // the expression stack, and it is consumed by the call unless the 94 // reference is for a compound assignment. 95 // If the reference is not consumed, it is left in place under its value. 96 void GetValue(); 97 98 // Like GetValue except that the slot is expected to be written to before 99 // being read from again. The value of the reference may be invalidated, 100 // causing subsequent attempts to read it to fail. 101 void TakeValue(); 102 103 // Generate code to store the value on top of the expression stack in the 104 // reference. The reference is expected to be immediately below the value 105 // on the expression stack. The value is stored in the location specified 106 // by the reference, and is left on top of the stack, after the reference 107 // is popped from beneath it (unloaded). 108 void SetValue(InitState init_state); 109 110 private: 111 CodeGenerator* cgen_; 112 Expression* expression_; 113 Type type_; 114 bool persist_after_get_; 115}; 116 117 118// ------------------------------------------------------------------------- 119// Control destinations. 120 121// A control destination encapsulates a pair of jump targets and a 122// flag indicating which one is the preferred fall-through. The 123// preferred fall-through must be unbound, the other may be already 124// bound (ie, a backward target). 125// 126// The true and false targets may be jumped to unconditionally or 127// control may split conditionally. Unconditional jumping and 128// splitting should be emitted in tail position (as the last thing 129// when compiling an expression) because they can cause either label 130// to be bound or the non-fall through to be jumped to leaving an 131// invalid virtual frame. 132// 133// The labels in the control destination can be extracted and 134// manipulated normally without affecting the state of the 135// destination. 136 137class ControlDestination BASE_EMBEDDED { 138 public: 139 ControlDestination(JumpTarget* true_target, 140 JumpTarget* false_target, 141 bool true_is_fall_through) 142 : true_target_(true_target), 143 false_target_(false_target), 144 true_is_fall_through_(true_is_fall_through), 145 is_used_(false) { 146 ASSERT(true_is_fall_through ? !true_target->is_bound() 147 : !false_target->is_bound()); 148 } 149 150 // Accessors for the jump targets. Directly jumping or branching to 151 // or binding the targets will not update the destination's state. 152 JumpTarget* true_target() const { return true_target_; } 153 JumpTarget* false_target() const { return false_target_; } 154 155 // True if the the destination has been jumped to unconditionally or 156 // control has been split to both targets. This predicate does not 157 // test whether the targets have been extracted and manipulated as 158 // raw jump targets. 159 bool is_used() const { return is_used_; } 160 161 // True if the destination is used and the true target (respectively 162 // false target) was the fall through. If the target is backward, 163 // "fall through" included jumping unconditionally to it. 164 bool true_was_fall_through() const { 165 return is_used_ && true_is_fall_through_; 166 } 167 168 bool false_was_fall_through() const { 169 return is_used_ && !true_is_fall_through_; 170 } 171 172 // Emit a branch to one of the true or false targets, and bind the 173 // other target. Because this binds the fall-through target, it 174 // should be emitted in tail position (as the last thing when 175 // compiling an expression). 176 void Split(Condition cc) { 177 ASSERT(!is_used_); 178 if (true_is_fall_through_) { 179 false_target_->Branch(NegateCondition(cc)); 180 true_target_->Bind(); 181 } else { 182 true_target_->Branch(cc); 183 false_target_->Bind(); 184 } 185 is_used_ = true; 186 } 187 188 // Emit an unconditional jump in tail position, to the true target 189 // (if the argument is true) or the false target. The "jump" will 190 // actually bind the jump target if it is forward, jump to it if it 191 // is backward. 192 void Goto(bool where) { 193 ASSERT(!is_used_); 194 JumpTarget* target = where ? true_target_ : false_target_; 195 if (target->is_bound()) { 196 target->Jump(); 197 } else { 198 target->Bind(); 199 } 200 is_used_ = true; 201 true_is_fall_through_ = where; 202 } 203 204 // Mark this jump target as used as if Goto had been called, but 205 // without generating a jump or binding a label (the control effect 206 // should have already happened). This is used when the left 207 // subexpression of the short-circuit boolean operators are 208 // compiled. 209 void Use(bool where) { 210 ASSERT(!is_used_); 211 ASSERT((where ? true_target_ : false_target_)->is_bound()); 212 is_used_ = true; 213 true_is_fall_through_ = where; 214 } 215 216 // Swap the true and false targets but keep the same actual label as 217 // the fall through. This is used when compiling negated 218 // expressions, where we want to swap the targets but preserve the 219 // state. 220 void Invert() { 221 JumpTarget* temp_target = true_target_; 222 true_target_ = false_target_; 223 false_target_ = temp_target; 224 225 true_is_fall_through_ = !true_is_fall_through_; 226 } 227 228 private: 229 // True and false jump targets. 230 JumpTarget* true_target_; 231 JumpTarget* false_target_; 232 233 // Before using the destination: true if the true target is the 234 // preferred fall through, false if the false target is. After 235 // using the destination: true if the true target was actually used 236 // as the fall through, false if the false target was. 237 bool true_is_fall_through_; 238 239 // True if the Split or Goto functions have been called. 240 bool is_used_; 241}; 242 243 244// ------------------------------------------------------------------------- 245// Code generation state 246 247// The state is passed down the AST by the code generator (and back up, in 248// the form of the state of the jump target pair). It is threaded through 249// the call stack. Constructing a state implicitly pushes it on the owning 250// code generator's stack of states, and destroying one implicitly pops it. 251// 252// The code generator state is only used for expressions, so statements have 253// the initial state. 254 255class CodeGenState BASE_EMBEDDED { 256 public: 257 // Create an initial code generator state. Destroying the initial state 258 // leaves the code generator with a NULL state. 259 explicit CodeGenState(CodeGenerator* owner); 260 261 // Create a code generator state based on a code generator's current 262 // state. The new state has its own control destination. 263 CodeGenState(CodeGenerator* owner, ControlDestination* destination); 264 265 // Destroy a code generator state and restore the owning code generator's 266 // previous state. 267 ~CodeGenState(); 268 269 // Accessors for the state. 270 ControlDestination* destination() const { return destination_; } 271 272 private: 273 // The owning code generator. 274 CodeGenerator* owner_; 275 276 // A control destination in case the expression has a control-flow 277 // effect. 278 ControlDestination* destination_; 279 280 // The previous state of the owning code generator, restored when 281 // this state is destroyed. 282 CodeGenState* previous_; 283}; 284 285 286// ------------------------------------------------------------------------- 287// Arguments allocation mode 288 289enum ArgumentsAllocationMode { 290 NO_ARGUMENTS_ALLOCATION, 291 EAGER_ARGUMENTS_ALLOCATION, 292 LAZY_ARGUMENTS_ALLOCATION 293}; 294 295 296// ------------------------------------------------------------------------- 297// CodeGenerator 298 299class CodeGenerator: public AstVisitor { 300 public: 301 static bool MakeCode(CompilationInfo* info); 302 303 // Printing of AST, etc. as requested by flags. 304 static void MakeCodePrologue(CompilationInfo* info); 305 306 // Allocate and install the code. 307 static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm, 308 Code::Flags flags, 309 CompilationInfo* info); 310 311#ifdef ENABLE_LOGGING_AND_PROFILING 312 static bool ShouldGenerateLog(Expression* type); 313#endif 314 315 static bool RecordPositions(MacroAssembler* masm, 316 int pos, 317 bool right_here = false); 318 319 // Accessors 320 MacroAssembler* masm() { return masm_; } 321 VirtualFrame* frame() const { return frame_; } 322 inline Handle<Script> script(); 323 324 bool has_valid_frame() const { return frame_ != NULL; } 325 326 // Set the virtual frame to be new_frame, with non-frame register 327 // reference counts given by non_frame_registers. The non-frame 328 // register reference counts of the old frame are returned in 329 // non_frame_registers. 330 void SetFrame(VirtualFrame* new_frame, RegisterFile* non_frame_registers); 331 332 void DeleteFrame(); 333 334 RegisterAllocator* allocator() const { return allocator_; } 335 336 CodeGenState* state() { return state_; } 337 void set_state(CodeGenState* state) { state_ = state; } 338 339 void AddDeferred(DeferredCode* code) { deferred_.Add(code); } 340 341 bool in_spilled_code() const { return in_spilled_code_; } 342 void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; } 343 344 private: 345 // Type of a member function that generates inline code for a native function. 346 typedef void (CodeGenerator::*InlineFunctionGenerator) 347 (ZoneList<Expression*>*); 348 349 static const InlineFunctionGenerator kInlineFunctionGenerators[]; 350 351 // Construction/Destruction 352 explicit CodeGenerator(MacroAssembler* masm); 353 354 // Accessors 355 inline bool is_eval(); 356 inline Scope* scope(); 357 358 // Generating deferred code. 359 void ProcessDeferred(); 360 361 // State 362 ControlDestination* destination() const { return state_->destination(); } 363 364 // Track loop nesting level. 365 int loop_nesting() const { return loop_nesting_; } 366 void IncrementLoopNesting() { loop_nesting_++; } 367 void DecrementLoopNesting() { loop_nesting_--; } 368 369 370 // Node visitors. 371 void VisitStatements(ZoneList<Statement*>* statements); 372 373#define DEF_VISIT(type) \ 374 void Visit##type(type* node); 375 AST_NODE_LIST(DEF_VISIT) 376#undef DEF_VISIT 377 378 // Visit a statement and then spill the virtual frame if control flow can 379 // reach the end of the statement (ie, it does not exit via break, 380 // continue, return, or throw). This function is used temporarily while 381 // the code generator is being transformed. 382 void VisitAndSpill(Statement* statement); 383 384 // Visit a list of statements and then spill the virtual frame if control 385 // flow can reach the end of the list. 386 void VisitStatementsAndSpill(ZoneList<Statement*>* statements); 387 388 // Main code generation function 389 void Generate(CompilationInfo* info); 390 391 // Generate the return sequence code. Should be called no more than 392 // once per compiled function, immediately after binding the return 393 // target (which can not be done more than once). 394 void GenerateReturnSequence(Result* return_value); 395 396 // Generate code for a fast smi loop. 397 void GenerateFastSmiLoop(ForStatement* node); 398 399 // Returns the arguments allocation mode. 400 ArgumentsAllocationMode ArgumentsMode(); 401 402 // Store the arguments object and allocate it if necessary. 403 Result StoreArgumentsObject(bool initial); 404 405 // The following are used by class Reference. 406 void LoadReference(Reference* ref); 407 void UnloadReference(Reference* ref); 408 409 Operand SlotOperand(Slot* slot, Register tmp); 410 411 Operand ContextSlotOperandCheckExtensions(Slot* slot, 412 Result tmp, 413 JumpTarget* slow); 414 415 // Expressions 416 void LoadCondition(Expression* x, 417 ControlDestination* destination, 418 bool force_control); 419 void Load(Expression* expr); 420 void LoadGlobal(); 421 void LoadGlobalReceiver(); 422 423 // Generate code to push the value of an expression on top of the frame 424 // and then spill the frame fully to memory. This function is used 425 // temporarily while the code generator is being transformed. 426 void LoadAndSpill(Expression* expression); 427 428 // Read a value from a slot and leave it on top of the expression stack. 429 void LoadFromSlot(Slot* slot, TypeofState typeof_state); 430 void LoadFromSlotCheckForArguments(Slot* slot, TypeofState state); 431 Result LoadFromGlobalSlotCheckExtensions(Slot* slot, 432 TypeofState typeof_state, 433 JumpTarget* slow); 434 435 // Support for loading from local/global variables and arguments 436 // whose location is known unless they are shadowed by 437 // eval-introduced bindings. Generates no code for unsupported slot 438 // types and therefore expects to fall through to the slow jump target. 439 void EmitDynamicLoadFromSlotFastCase(Slot* slot, 440 TypeofState typeof_state, 441 Result* result, 442 JumpTarget* slow, 443 JumpTarget* done); 444 445 // Store the value on top of the expression stack into a slot, leaving the 446 // value in place. 447 void StoreToSlot(Slot* slot, InitState init_state); 448 449 // Support for compiling assignment expressions. 450 void EmitSlotAssignment(Assignment* node); 451 void EmitNamedPropertyAssignment(Assignment* node); 452 void EmitKeyedPropertyAssignment(Assignment* node); 453 454 // Receiver is passed on the frame and not consumed. 455 Result EmitNamedLoad(Handle<String> name, bool is_contextual); 456 457 // If the store is contextual, value is passed on the frame and consumed. 458 // Otherwise, receiver and value are passed on the frame and consumed. 459 Result EmitNamedStore(Handle<String> name, bool is_contextual); 460 461 // Load a property of an object, returning it in a Result. 462 // The object and the property name are passed on the stack, and 463 // not changed. 464 Result EmitKeyedLoad(); 465 466 // Receiver, key, and value are passed on the frame and consumed. 467 Result EmitKeyedStore(StaticType* key_type); 468 469 // Special code for typeof expressions: Unfortunately, we must 470 // be careful when loading the expression in 'typeof' 471 // expressions. We are not allowed to throw reference errors for 472 // non-existing properties of the global object, so we must make it 473 // look like an explicit property access, instead of an access 474 // through the context chain. 475 void LoadTypeofExpression(Expression* x); 476 477 // Translate the value on top of the frame into control flow to the 478 // control destination. 479 void ToBoolean(ControlDestination* destination); 480 481 // Generate code that computes a shortcutting logical operation. 482 void GenerateLogicalBooleanOperation(BinaryOperation* node); 483 484 void GenericBinaryOperation(BinaryOperation* expr, 485 OverwriteMode overwrite_mode); 486 487 // Generate a stub call from the virtual frame. 488 Result GenerateGenericBinaryOpStubCall(GenericBinaryOpStub* stub, 489 Result* left, 490 Result* right); 491 492 // Emits code sequence that jumps to a JumpTarget if the inputs 493 // are both smis. Cannot be in MacroAssembler because it takes 494 // advantage of TypeInfo to skip unneeded checks. 495 void JumpIfBothSmiUsingTypeInfo(Result* left, 496 Result* right, 497 JumpTarget* both_smi); 498 499 // Emits code sequence that jumps to deferred code if the input 500 // is not a smi. Cannot be in MacroAssembler because it takes 501 // advantage of TypeInfo to skip unneeded checks. 502 void JumpIfNotSmiUsingTypeInfo(Register reg, 503 TypeInfo type, 504 DeferredCode* deferred); 505 506 // Emits code sequence that jumps to deferred code if the inputs 507 // are not both smis. Cannot be in MacroAssembler because it takes 508 // advantage of TypeInfo to skip unneeded checks. 509 void JumpIfNotBothSmiUsingTypeInfo(Register left, 510 Register right, 511 TypeInfo left_info, 512 TypeInfo right_info, 513 DeferredCode* deferred); 514 515 // If possible, combine two constant smi values using op to produce 516 // a smi result, and push it on the virtual frame, all at compile time. 517 // Returns true if it succeeds. Otherwise it has no effect. 518 bool FoldConstantSmis(Token::Value op, int left, int right); 519 520 // Emit code to perform a binary operation on a constant 521 // smi and a likely smi. Consumes the Result *operand. 522 Result ConstantSmiBinaryOperation(BinaryOperation* expr, 523 Result* operand, 524 Handle<Object> constant_operand, 525 bool reversed, 526 OverwriteMode overwrite_mode); 527 528 // Emit code to perform a binary operation on two likely smis. 529 // The code to handle smi arguments is produced inline. 530 // Consumes the Results *left and *right. 531 Result LikelySmiBinaryOperation(BinaryOperation* expr, 532 Result* left, 533 Result* right, 534 OverwriteMode overwrite_mode); 535 536 void Comparison(AstNode* node, 537 Condition cc, 538 bool strict, 539 ControlDestination* destination); 540 541 // If at least one of the sides is a constant smi, generate optimized code. 542 void ConstantSmiComparison(Condition cc, 543 bool strict, 544 ControlDestination* destination, 545 Result* left_side, 546 Result* right_side, 547 bool left_side_constant_smi, 548 bool right_side_constant_smi, 549 bool is_loop_condition); 550 551 void GenerateInlineNumberComparison(Result* left_side, 552 Result* right_side, 553 Condition cc, 554 ControlDestination* dest); 555 556 // To prevent long attacker-controlled byte sequences, integer constants 557 // from the JavaScript source are loaded in two parts if they are larger 558 // than 16 bits. 559 static const int kMaxSmiInlinedBits = 16; 560 bool IsUnsafeSmi(Handle<Object> value); 561 // Load an integer constant x into a register target using 562 // at most 16 bits of user-controlled data per assembly operation. 563 void LoadUnsafeSmi(Register target, Handle<Object> value); 564 565 void CallWithArguments(ZoneList<Expression*>* arguments, 566 CallFunctionFlags flags, 567 int position); 568 569 // An optimized implementation of expressions of the form 570 // x.apply(y, arguments). We call x the applicand and y the receiver. 571 // The optimization avoids allocating an arguments object if possible. 572 void CallApplyLazy(Expression* applicand, 573 Expression* receiver, 574 VariableProxy* arguments, 575 int position); 576 577 void CheckStack(); 578 579 bool CheckForInlineRuntimeCall(CallRuntime* node); 580 581 void ProcessDeclarations(ZoneList<Declaration*>* declarations); 582 583 // Declare global variables and functions in the given array of 584 // name/value pairs. 585 void DeclareGlobals(Handle<FixedArray> pairs); 586 587 // Instantiate the function based on the shared function info. 588 void InstantiateFunction(Handle<SharedFunctionInfo> function_info, 589 bool pretenure); 590 591 // Support for type checks. 592 void GenerateIsSmi(ZoneList<Expression*>* args); 593 void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); 594 void GenerateIsArray(ZoneList<Expression*>* args); 595 void GenerateIsRegExp(ZoneList<Expression*>* args); 596 void GenerateIsObject(ZoneList<Expression*>* args); 597 void GenerateIsSpecObject(ZoneList<Expression*>* args); 598 void GenerateIsFunction(ZoneList<Expression*>* args); 599 void GenerateIsUndetectableObject(ZoneList<Expression*>* args); 600 void GenerateIsStringWrapperSafeForDefaultValueOf( 601 ZoneList<Expression*>* args); 602 603 // Support for construct call checks. 604 void GenerateIsConstructCall(ZoneList<Expression*>* args); 605 606 // Support for arguments.length and arguments[?]. 607 void GenerateArgumentsLength(ZoneList<Expression*>* args); 608 void GenerateArguments(ZoneList<Expression*>* args); 609 610 // Support for accessing the class and value fields of an object. 611 void GenerateClassOf(ZoneList<Expression*>* args); 612 void GenerateValueOf(ZoneList<Expression*>* args); 613 void GenerateSetValueOf(ZoneList<Expression*>* args); 614 615 // Fast support for charCodeAt(n). 616 void GenerateStringCharCodeAt(ZoneList<Expression*>* args); 617 618 // Fast support for string.charAt(n) and string[n]. 619 void GenerateStringCharFromCode(ZoneList<Expression*>* args); 620 621 // Fast support for string.charAt(n) and string[n]. 622 void GenerateStringCharAt(ZoneList<Expression*>* args); 623 624 // Fast support for object equality testing. 625 void GenerateObjectEquals(ZoneList<Expression*>* args); 626 627 void GenerateLog(ZoneList<Expression*>* args); 628 629 void GenerateGetFramePointer(ZoneList<Expression*>* args); 630 631 // Fast support for Math.random(). 632 void GenerateRandomHeapNumber(ZoneList<Expression*>* args); 633 634 // Fast support for StringAdd. 635 void GenerateStringAdd(ZoneList<Expression*>* args); 636 637 // Fast support for SubString. 638 void GenerateSubString(ZoneList<Expression*>* args); 639 640 // Fast support for StringCompare. 641 void GenerateStringCompare(ZoneList<Expression*>* args); 642 643 // Support for direct calls from JavaScript to native RegExp code. 644 void GenerateRegExpExec(ZoneList<Expression*>* args); 645 646 void GenerateRegExpConstructResult(ZoneList<Expression*>* args); 647 648 // Support for fast native caches. 649 void GenerateGetFromCache(ZoneList<Expression*>* args); 650 651 // Fast support for number to string. 652 void GenerateNumberToString(ZoneList<Expression*>* args); 653 654 // Fast swapping of elements. Takes three expressions, the object and two 655 // indices. This should only be used if the indices are known to be 656 // non-negative and within bounds of the elements array at the call site. 657 void GenerateSwapElements(ZoneList<Expression*>* args); 658 659 // Fast call for custom callbacks. 660 void GenerateCallFunction(ZoneList<Expression*>* args); 661 662 // Fast call to math functions. 663 void GenerateMathPow(ZoneList<Expression*>* args); 664 void GenerateMathSin(ZoneList<Expression*>* args); 665 void GenerateMathCos(ZoneList<Expression*>* args); 666 void GenerateMathSqrt(ZoneList<Expression*>* args); 667 668 void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args); 669 670 void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args); 671 void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args); 672 void GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args); 673 674// Simple condition analysis. 675 enum ConditionAnalysis { 676 ALWAYS_TRUE, 677 ALWAYS_FALSE, 678 DONT_KNOW 679 }; 680 ConditionAnalysis AnalyzeCondition(Expression* cond); 681 682 // Methods used to indicate which source code is generated for. Source 683 // positions are collected by the assembler and emitted with the relocation 684 // information. 685 void CodeForFunctionPosition(FunctionLiteral* fun); 686 void CodeForReturnPosition(FunctionLiteral* fun); 687 void CodeForStatementPosition(Statement* node); 688 void CodeForDoWhileConditionPosition(DoWhileStatement* stmt); 689 void CodeForSourcePosition(int pos); 690 691 void SetTypeForStackSlot(Slot* slot, TypeInfo info); 692 693#ifdef DEBUG 694 // True if the registers are valid for entry to a block. There should 695 // be no frame-external references to (non-reserved) registers. 696 bool HasValidEntryRegisters(); 697#endif 698 699 ZoneList<DeferredCode*> deferred_; 700 701 // Assembler 702 MacroAssembler* masm_; // to generate code 703 704 CompilationInfo* info_; 705 706 // Code generation state 707 VirtualFrame* frame_; 708 RegisterAllocator* allocator_; 709 CodeGenState* state_; 710 int loop_nesting_; 711 712 // Jump targets. 713 // The target of the return from the function. 714 BreakTarget function_return_; 715 716 // True if the function return is shadowed (ie, jumping to the target 717 // function_return_ does not jump to the true function return, but rather 718 // to some unlinking code). 719 bool function_return_is_shadowed_; 720 721 // True when we are in code that expects the virtual frame to be fully 722 // spilled. Some virtual frame function are disabled in DEBUG builds when 723 // called from spilled code, because they do not leave the virtual frame 724 // in a spilled state. 725 bool in_spilled_code_; 726 727 friend class VirtualFrame; 728 friend class JumpTarget; 729 friend class Reference; 730 friend class Result; 731 friend class FastCodeGenerator; 732 friend class FullCodeGenerator; 733 friend class FullCodeGenSyntaxChecker; 734 735 friend class CodeGeneratorPatcher; // Used in test-log-stack-tracer.cc 736 737 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); 738}; 739 740 741} } // namespace v8::internal 742 743#endif // V8_X64_CODEGEN_X64_H_ 744