Home | History | Annotate | Download | only in ia32
      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_IA32_CODEGEN_IA32_H_
     29 #define V8_IA32_CODEGEN_IA32_H_
     30 
     31 namespace v8 {
     32 namespace internal {
     33 
     34 // Forward declarations
     35 class CompilationInfo;
     36 class DeferredCode;
     37 class RegisterAllocator;
     38 class RegisterFile;
     39 
     40 enum InitState { CONST_INIT, NOT_CONST_INIT };
     41 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
     42 
     43 
     44 // -------------------------------------------------------------------------
     45 // Reference support
     46 
     47 // A reference is a C++ stack-allocated object that puts a
     48 // reference on the virtual frame.  The reference may be consumed
     49 // by GetValue, TakeValue, SetValue, and Codegen::UnloadReference.
     50 // When the lifetime (scope) of a valid reference ends, it must have
     51 // been consumed, and be in state UNLOADED.
     52 class Reference BASE_EMBEDDED {
     53  public:
     54   // The values of the types is important, see size().
     55   enum Type { UNLOADED = -2, ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 };
     56   Reference(CodeGenerator* cgen,
     57             Expression* expression,
     58             bool persist_after_get = false);
     59   ~Reference();
     60 
     61   Expression* expression() const { return expression_; }
     62   Type type() const { return type_; }
     63   void set_type(Type value) {
     64     ASSERT_EQ(ILLEGAL, type_);
     65     type_ = value;
     66   }
     67 
     68   void set_unloaded() {
     69     ASSERT_NE(ILLEGAL, type_);
     70     ASSERT_NE(UNLOADED, type_);
     71     type_ = UNLOADED;
     72   }
     73   // The size the reference takes up on the stack.
     74   int size() const {
     75     return (type_ < SLOT) ? 0 : type_;
     76   }
     77 
     78   bool is_illegal() const { return type_ == ILLEGAL; }
     79   bool is_slot() const { return type_ == SLOT; }
     80   bool is_property() const { return type_ == NAMED || type_ == KEYED; }
     81   bool is_unloaded() const { return type_ == UNLOADED; }
     82 
     83   // Return the name.  Only valid for named property references.
     84   Handle<String> GetName();
     85 
     86   // Generate code to push the value of the reference on top of the
     87   // expression stack.  The reference is expected to be already on top of
     88   // the expression stack, and it is consumed by the call unless the
     89   // reference is for a compound assignment.
     90   // If the reference is not consumed, it is left in place under its value.
     91   void GetValue();
     92 
     93   // Like GetValue except that the slot is expected to be written to before
     94   // being read from again.  The value of the reference may be invalidated,
     95   // causing subsequent attempts to read it to fail.
     96   void TakeValue();
     97 
     98   // Generate code to store the value on top of the expression stack in the
     99   // reference.  The reference is expected to be immediately below the value
    100   // on the expression stack.  The  value is stored in the location specified
    101   // by the reference, and is left on top of the stack, after the reference
    102   // is popped from beneath it (unloaded).
    103   void SetValue(InitState init_state);
    104 
    105  private:
    106   CodeGenerator* cgen_;
    107   Expression* expression_;
    108   Type type_;
    109   // Keep the reference on the stack after get, so it can be used by set later.
    110   bool persist_after_get_;
    111 };
    112 
    113 
    114 // -------------------------------------------------------------------------
    115 // Control destinations.
    116 
    117 // A control destination encapsulates a pair of jump targets and a
    118 // flag indicating which one is the preferred fall-through.  The
    119 // preferred fall-through must be unbound, the other may be already
    120 // bound (ie, a backward target).
    121 //
    122 // The true and false targets may be jumped to unconditionally or
    123 // control may split conditionally.  Unconditional jumping and
    124 // splitting should be emitted in tail position (as the last thing
    125 // when compiling an expression) because they can cause either label
    126 // to be bound or the non-fall through to be jumped to leaving an
    127 // invalid virtual frame.
    128 //
    129 // The labels in the control destination can be extracted and
    130 // manipulated normally without affecting the state of the
    131 // destination.
    132 
    133 class ControlDestination BASE_EMBEDDED {
    134  public:
    135   ControlDestination(JumpTarget* true_target,
    136                      JumpTarget* false_target,
    137                      bool true_is_fall_through)
    138       : true_target_(true_target),
    139         false_target_(false_target),
    140         true_is_fall_through_(true_is_fall_through),
    141         is_used_(false) {
    142     ASSERT(true_is_fall_through ? !true_target->is_bound()
    143                                 : !false_target->is_bound());
    144   }
    145 
    146   // Accessors for the jump targets.  Directly jumping or branching to
    147   // or binding the targets will not update the destination's state.
    148   JumpTarget* true_target() const { return true_target_; }
    149   JumpTarget* false_target() const { return false_target_; }
    150 
    151   // True if the the destination has been jumped to unconditionally or
    152   // control has been split to both targets.  This predicate does not
    153   // test whether the targets have been extracted and manipulated as
    154   // raw jump targets.
    155   bool is_used() const { return is_used_; }
    156 
    157   // True if the destination is used and the true target (respectively
    158   // false target) was the fall through.  If the target is backward,
    159   // "fall through" included jumping unconditionally to it.
    160   bool true_was_fall_through() const {
    161     return is_used_ && true_is_fall_through_;
    162   }
    163 
    164   bool false_was_fall_through() const {
    165     return is_used_ && !true_is_fall_through_;
    166   }
    167 
    168   // Emit a branch to one of the true or false targets, and bind the
    169   // other target.  Because this binds the fall-through target, it
    170   // should be emitted in tail position (as the last thing when
    171   // compiling an expression).
    172   void Split(Condition cc) {
    173     ASSERT(!is_used_);
    174     if (true_is_fall_through_) {
    175       false_target_->Branch(NegateCondition(cc));
    176       true_target_->Bind();
    177     } else {
    178       true_target_->Branch(cc);
    179       false_target_->Bind();
    180     }
    181     is_used_ = true;
    182   }
    183 
    184   // Emit an unconditional jump in tail position, to the true target
    185   // (if the argument is true) or the false target.  The "jump" will
    186   // actually bind the jump target if it is forward, jump to it if it
    187   // is backward.
    188   void Goto(bool where) {
    189     ASSERT(!is_used_);
    190     JumpTarget* target = where ? true_target_ : false_target_;
    191     if (target->is_bound()) {
    192       target->Jump();
    193     } else {
    194       target->Bind();
    195     }
    196     is_used_ = true;
    197     true_is_fall_through_ = where;
    198   }
    199 
    200   // Mark this jump target as used as if Goto had been called, but
    201   // without generating a jump or binding a label (the control effect
    202   // should have already happened).  This is used when the left
    203   // subexpression of the short-circuit boolean operators are
    204   // compiled.
    205   void Use(bool where) {
    206     ASSERT(!is_used_);
    207     ASSERT((where ? true_target_ : false_target_)->is_bound());
    208     is_used_ = true;
    209     true_is_fall_through_ = where;
    210   }
    211 
    212   // Swap the true and false targets but keep the same actual label as
    213   // the fall through.  This is used when compiling negated
    214   // expressions, where we want to swap the targets but preserve the
    215   // state.
    216   void Invert() {
    217     JumpTarget* temp_target = true_target_;
    218     true_target_ = false_target_;
    219     false_target_ = temp_target;
    220 
    221     true_is_fall_through_ = !true_is_fall_through_;
    222   }
    223 
    224  private:
    225   // True and false jump targets.
    226   JumpTarget* true_target_;
    227   JumpTarget* false_target_;
    228 
    229   // Before using the destination: true if the true target is the
    230   // preferred fall through, false if the false target is.  After
    231   // using the destination: true if the true target was actually used
    232   // as the fall through, false if the false target was.
    233   bool true_is_fall_through_;
    234 
    235   // True if the Split or Goto functions have been called.
    236   bool is_used_;
    237 };
    238 
    239 
    240 // -------------------------------------------------------------------------
    241 // Code generation state
    242 
    243 // The state is passed down the AST by the code generator (and back up, in
    244 // the form of the state of the jump target pair).  It is threaded through
    245 // the call stack.  Constructing a state implicitly pushes it on the owning
    246 // code generator's stack of states, and destroying one implicitly pops it.
    247 //
    248 // The code generator state is only used for expressions, so statements have
    249 // the initial state.
    250 
    251 class CodeGenState BASE_EMBEDDED {
    252  public:
    253   // Create an initial code generator state.  Destroying the initial state
    254   // leaves the code generator with a NULL state.
    255   explicit CodeGenState(CodeGenerator* owner);
    256 
    257   // Create a code generator state based on a code generator's current
    258   // state.  The new state has its own control destination.
    259   CodeGenState(CodeGenerator* owner, ControlDestination* destination);
    260 
    261   // Destroy a code generator state and restore the owning code generator's
    262   // previous state.
    263   ~CodeGenState();
    264 
    265   // Accessors for the state.
    266   ControlDestination* destination() const { return destination_; }
    267 
    268  private:
    269   // The owning code generator.
    270   CodeGenerator* owner_;
    271 
    272   // A control destination in case the expression has a control-flow
    273   // effect.
    274   ControlDestination* destination_;
    275 
    276   // The previous state of the owning code generator, restored when
    277   // this state is destroyed.
    278   CodeGenState* previous_;
    279 };
    280 
    281 
    282 // -------------------------------------------------------------------------
    283 // Arguments allocation mode.
    284 
    285 enum ArgumentsAllocationMode {
    286   NO_ARGUMENTS_ALLOCATION,
    287   EAGER_ARGUMENTS_ALLOCATION,
    288   LAZY_ARGUMENTS_ALLOCATION
    289 };
    290 
    291 
    292 // -------------------------------------------------------------------------
    293 // CodeGenerator
    294 
    295 class CodeGenerator: public AstVisitor {
    296  public:
    297   // Takes a function literal, generates code for it. This function should only
    298   // be called by compiler.cc.
    299   static Handle<Code> MakeCode(CompilationInfo* info);
    300 
    301   // Printing of AST, etc. as requested by flags.
    302   static void MakeCodePrologue(CompilationInfo* info);
    303 
    304   // Allocate and install the code.
    305   static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm,
    306                                        Code::Flags flags,
    307                                        CompilationInfo* info);
    308 
    309 #ifdef ENABLE_LOGGING_AND_PROFILING
    310   static bool ShouldGenerateLog(Expression* type);
    311 #endif
    312 
    313   static void RecordPositions(MacroAssembler* masm, int pos);
    314 
    315   // Accessors
    316   MacroAssembler* masm() { return masm_; }
    317   VirtualFrame* frame() const { return frame_; }
    318   inline Handle<Script> script();
    319 
    320   bool has_valid_frame() const { return frame_ != NULL; }
    321 
    322   // Set the virtual frame to be new_frame, with non-frame register
    323   // reference counts given by non_frame_registers.  The non-frame
    324   // register reference counts of the old frame are returned in
    325   // non_frame_registers.
    326   void SetFrame(VirtualFrame* new_frame, RegisterFile* non_frame_registers);
    327 
    328   void DeleteFrame();
    329 
    330   RegisterAllocator* allocator() const { return allocator_; }
    331 
    332   CodeGenState* state() { return state_; }
    333   void set_state(CodeGenState* state) { state_ = state; }
    334 
    335   void AddDeferred(DeferredCode* code) { deferred_.Add(code); }
    336 
    337   bool in_spilled_code() const { return in_spilled_code_; }
    338   void set_in_spilled_code(bool flag) { in_spilled_code_ = flag; }
    339 
    340  private:
    341   // Construction/Destruction
    342   explicit CodeGenerator(MacroAssembler* masm);
    343 
    344   // Accessors
    345   inline bool is_eval();
    346   Scope* scope();
    347 
    348   // Generating deferred code.
    349   void ProcessDeferred();
    350 
    351   // State
    352   ControlDestination* destination() const { return state_->destination(); }
    353 
    354   // Track loop nesting level.
    355   int loop_nesting() const { return loop_nesting_; }
    356   void IncrementLoopNesting() { loop_nesting_++; }
    357   void DecrementLoopNesting() { loop_nesting_--; }
    358 
    359   // Node visitors.
    360   void VisitStatements(ZoneList<Statement*>* statements);
    361 
    362 #define DEF_VISIT(type) \
    363   void Visit##type(type* node);
    364   AST_NODE_LIST(DEF_VISIT)
    365 #undef DEF_VISIT
    366 
    367   // Visit a statement and then spill the virtual frame if control flow can
    368   // reach the end of the statement (ie, it does not exit via break,
    369   // continue, return, or throw).  This function is used temporarily while
    370   // the code generator is being transformed.
    371   void VisitAndSpill(Statement* statement);
    372 
    373   // Visit a list of statements and then spill the virtual frame if control
    374   // flow can reach the end of the list.
    375   void VisitStatementsAndSpill(ZoneList<Statement*>* statements);
    376 
    377   // Main code generation function
    378   void Generate(CompilationInfo* info);
    379 
    380   // Generate the return sequence code.  Should be called no more than
    381   // once per compiled function, immediately after binding the return
    382   // target (which can not be done more than once).
    383   void GenerateReturnSequence(Result* return_value);
    384 
    385   // Returns the arguments allocation mode.
    386   ArgumentsAllocationMode ArgumentsMode();
    387 
    388   // Store the arguments object and allocate it if necessary.
    389   Result StoreArgumentsObject(bool initial);
    390 
    391   // The following are used by class Reference.
    392   void LoadReference(Reference* ref);
    393   void UnloadReference(Reference* ref);
    394 
    395   static Operand ContextOperand(Register context, int index) {
    396     return Operand(context, Context::SlotOffset(index));
    397   }
    398 
    399   Operand SlotOperand(Slot* slot, Register tmp);
    400 
    401   Operand ContextSlotOperandCheckExtensions(Slot* slot,
    402                                             Result tmp,
    403                                             JumpTarget* slow);
    404 
    405   // Expressions
    406   static Operand GlobalObject() {
    407     return ContextOperand(esi, Context::GLOBAL_INDEX);
    408   }
    409 
    410   void LoadCondition(Expression* x,
    411                      ControlDestination* destination,
    412                      bool force_control);
    413   void Load(Expression* expr);
    414   void LoadGlobal();
    415   void LoadGlobalReceiver();
    416 
    417   // Generate code to push the value of an expression on top of the frame
    418   // and then spill the frame fully to memory.  This function is used
    419   // temporarily while the code generator is being transformed.
    420   void LoadAndSpill(Expression* expression);
    421 
    422   // Read a value from a slot and leave it on top of the expression stack.
    423   Result LoadFromSlot(Slot* slot, TypeofState typeof_state);
    424   Result LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state);
    425   Result LoadFromGlobalSlotCheckExtensions(Slot* slot,
    426                                            TypeofState typeof_state,
    427                                            JumpTarget* slow);
    428 
    429   // Store the value on top of the expression stack into a slot, leaving the
    430   // value in place.
    431   void StoreToSlot(Slot* slot, InitState init_state);
    432 
    433   // Support for compiling assignment expressions.
    434   void EmitSlotAssignment(Assignment* node);
    435   void EmitNamedPropertyAssignment(Assignment* node);
    436   void EmitKeyedPropertyAssignment(Assignment* node);
    437 
    438   // Receiver is passed on the frame and consumed.
    439   Result EmitNamedLoad(Handle<String> name, bool is_contextual);
    440 
    441   // If the store is contextual, value is passed on the frame and consumed.
    442   // Otherwise, receiver and value are passed on the frame and consumed.
    443   Result EmitNamedStore(Handle<String> name, bool is_contextual);
    444 
    445   // Receiver and key are passed on the frame and consumed.
    446   Result EmitKeyedLoad();
    447 
    448   // Receiver, key, and value are passed on the frame and consumed.
    449   Result EmitKeyedStore(StaticType* key_type);
    450 
    451   // Special code for typeof expressions: Unfortunately, we must
    452   // be careful when loading the expression in 'typeof'
    453   // expressions. We are not allowed to throw reference errors for
    454   // non-existing properties of the global object, so we must make it
    455   // look like an explicit property access, instead of an access
    456   // through the context chain.
    457   void LoadTypeofExpression(Expression* x);
    458 
    459   // Translate the value on top of the frame into control flow to the
    460   // control destination.
    461   void ToBoolean(ControlDestination* destination);
    462 
    463   void GenericBinaryOperation(
    464       Token::Value op,
    465       StaticType* type,
    466       OverwriteMode overwrite_mode);
    467 
    468   // If possible, combine two constant smi values using op to produce
    469   // a smi result, and push it on the virtual frame, all at compile time.
    470   // Returns true if it succeeds.  Otherwise it has no effect.
    471   bool FoldConstantSmis(Token::Value op, int left, int right);
    472 
    473   // Emit code to perform a binary operation on a constant
    474   // smi and a likely smi.  Consumes the Result *operand.
    475   Result ConstantSmiBinaryOperation(Token::Value op,
    476                                     Result* operand,
    477                                     Handle<Object> constant_operand,
    478                                     StaticType* type,
    479                                     bool reversed,
    480                                     OverwriteMode overwrite_mode);
    481 
    482   // Emit code to perform a binary operation on two likely smis.
    483   // The code to handle smi arguments is produced inline.
    484   // Consumes the Results *left and *right.
    485   Result LikelySmiBinaryOperation(Token::Value op,
    486                                   Result* left,
    487                                   Result* right,
    488                                   OverwriteMode overwrite_mode);
    489 
    490   void Comparison(AstNode* node,
    491                   Condition cc,
    492                   bool strict,
    493                   ControlDestination* destination);
    494 
    495   // To prevent long attacker-controlled byte sequences, integer constants
    496   // from the JavaScript source are loaded in two parts if they are larger
    497   // than 16 bits.
    498   static const int kMaxSmiInlinedBits = 16;
    499   bool IsUnsafeSmi(Handle<Object> value);
    500   // Load an integer constant x into a register target or into the stack using
    501   // at most 16 bits of user-controlled data per assembly operation.
    502   void MoveUnsafeSmi(Register target, Handle<Object> value);
    503   void StoreUnsafeSmiToLocal(int offset, Handle<Object> value);
    504   void PushUnsafeSmi(Handle<Object> value);
    505 
    506   void CallWithArguments(ZoneList<Expression*>* arguments,
    507                          CallFunctionFlags flags,
    508                          int position);
    509 
    510   // An optimized implementation of expressions of the form
    511   // x.apply(y, arguments).  We call x the applicand and y the receiver.
    512   // The optimization avoids allocating an arguments object if possible.
    513   void CallApplyLazy(Expression* applicand,
    514                      Expression* receiver,
    515                      VariableProxy* arguments,
    516                      int position);
    517 
    518   void CheckStack();
    519 
    520   struct InlineRuntimeLUT {
    521     void (CodeGenerator::*method)(ZoneList<Expression*>*);
    522     const char* name;
    523   };
    524 
    525   static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name);
    526   bool CheckForInlineRuntimeCall(CallRuntime* node);
    527   static bool PatchInlineRuntimeEntry(Handle<String> name,
    528                                       const InlineRuntimeLUT& new_entry,
    529                                       InlineRuntimeLUT* old_entry);
    530 
    531   void ProcessDeclarations(ZoneList<Declaration*>* declarations);
    532 
    533   static Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop);
    534 
    535   // Declare global variables and functions in the given array of
    536   // name/value pairs.
    537   void DeclareGlobals(Handle<FixedArray> pairs);
    538 
    539   // Instantiate the function boilerplate.
    540   Result InstantiateBoilerplate(Handle<JSFunction> boilerplate);
    541 
    542   // Support for type checks.
    543   void GenerateIsSmi(ZoneList<Expression*>* args);
    544   void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args);
    545   void GenerateIsArray(ZoneList<Expression*>* args);
    546   void GenerateIsRegExp(ZoneList<Expression*>* args);
    547   void GenerateIsObject(ZoneList<Expression*>* args);
    548   void GenerateIsFunction(ZoneList<Expression*>* args);
    549   void GenerateIsUndetectableObject(ZoneList<Expression*>* args);
    550 
    551   // Support for construct call checks.
    552   void GenerateIsConstructCall(ZoneList<Expression*>* args);
    553 
    554   // Support for arguments.length and arguments[?].
    555   void GenerateArgumentsLength(ZoneList<Expression*>* args);
    556   void GenerateArgumentsAccess(ZoneList<Expression*>* args);
    557 
    558   // Support for accessing the class and value fields of an object.
    559   void GenerateClassOf(ZoneList<Expression*>* args);
    560   void GenerateValueOf(ZoneList<Expression*>* args);
    561   void GenerateSetValueOf(ZoneList<Expression*>* args);
    562 
    563   // Fast support for charCodeAt(n).
    564   void GenerateFastCharCodeAt(ZoneList<Expression*>* args);
    565 
    566   // Fast support for object equality testing.
    567   void GenerateObjectEquals(ZoneList<Expression*>* args);
    568 
    569   void GenerateLog(ZoneList<Expression*>* args);
    570 
    571   void GenerateGetFramePointer(ZoneList<Expression*>* args);
    572 
    573   // Fast support for Math.random().
    574   void GenerateRandomPositiveSmi(ZoneList<Expression*>* args);
    575 
    576   // Fast support for StringAdd.
    577   void GenerateStringAdd(ZoneList<Expression*>* args);
    578 
    579   // Fast support for SubString.
    580   void GenerateSubString(ZoneList<Expression*>* args);
    581 
    582   // Fast support for StringCompare.
    583   void GenerateStringCompare(ZoneList<Expression*>* args);
    584 
    585   // Support for direct calls from JavaScript to native RegExp code.
    586   void GenerateRegExpExec(ZoneList<Expression*>* args);
    587 
    588   // Fast support for number to string.
    589   void GenerateNumberToString(ZoneList<Expression*>* args);
    590 
    591   // Fast call to transcendental functions.
    592   void GenerateMathSin(ZoneList<Expression*>* args);
    593   void GenerateMathCos(ZoneList<Expression*>* args);
    594 
    595   // Simple condition analysis.
    596   enum ConditionAnalysis {
    597     ALWAYS_TRUE,
    598     ALWAYS_FALSE,
    599     DONT_KNOW
    600   };
    601   ConditionAnalysis AnalyzeCondition(Expression* cond);
    602 
    603   // Methods used to indicate which source code is generated for. Source
    604   // positions are collected by the assembler and emitted with the relocation
    605   // information.
    606   void CodeForFunctionPosition(FunctionLiteral* fun);
    607   void CodeForReturnPosition(FunctionLiteral* fun);
    608   void CodeForStatementPosition(Statement* stmt);
    609   void CodeForDoWhileConditionPosition(DoWhileStatement* stmt);
    610   void CodeForSourcePosition(int pos);
    611 
    612 #ifdef DEBUG
    613   // True if the registers are valid for entry to a block.  There should
    614   // be no frame-external references to (non-reserved) registers.
    615   bool HasValidEntryRegisters();
    616 #endif
    617 
    618   ZoneList<DeferredCode*> deferred_;
    619 
    620   // Assembler
    621   MacroAssembler* masm_;  // to generate code
    622 
    623   CompilationInfo* info_;
    624 
    625   // Code generation state
    626   VirtualFrame* frame_;
    627   RegisterAllocator* allocator_;
    628   CodeGenState* state_;
    629   int loop_nesting_;
    630 
    631   // Jump targets.
    632   // The target of the return from the function.
    633   BreakTarget function_return_;
    634 
    635   // True if the function return is shadowed (ie, jumping to the target
    636   // function_return_ does not jump to the true function return, but rather
    637   // to some unlinking code).
    638   bool function_return_is_shadowed_;
    639 
    640   // True when we are in code that expects the virtual frame to be fully
    641   // spilled.  Some virtual frame function are disabled in DEBUG builds when
    642   // called from spilled code, because they do not leave the virtual frame
    643   // in a spilled state.
    644   bool in_spilled_code_;
    645 
    646   static InlineRuntimeLUT kInlineRuntimeLUT[];
    647 
    648   friend class VirtualFrame;
    649   friend class JumpTarget;
    650   friend class Reference;
    651   friend class Result;
    652   friend class FastCodeGenerator;
    653   friend class FullCodeGenerator;
    654   friend class FullCodeGenSyntaxChecker;
    655 
    656   friend class CodeGeneratorPatcher;  // Used in test-log-stack-tracer.cc
    657 
    658   DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
    659 };
    660 
    661 
    662 // Compute a transcendental math function natively, or call the
    663 // TranscendentalCache runtime function.
    664 class TranscendentalCacheStub: public CodeStub {
    665  public:
    666   explicit TranscendentalCacheStub(TranscendentalCache::Type type)
    667       : type_(type) {}
    668   void Generate(MacroAssembler* masm);
    669  private:
    670   TranscendentalCache::Type type_;
    671   Major MajorKey() { return TranscendentalCache; }
    672   int MinorKey() { return type_; }
    673   Runtime::FunctionId RuntimeFunction();
    674   void GenerateOperation(MacroAssembler* masm);
    675 };
    676 
    677 
    678 // Flag that indicates how to generate code for the stub GenericBinaryOpStub.
    679 enum GenericBinaryFlags {
    680   NO_GENERIC_BINARY_FLAGS = 0,
    681   NO_SMI_CODE_IN_STUB = 1 << 0  // Omit smi code in stub.
    682 };
    683 
    684 
    685 class GenericBinaryOpStub: public CodeStub {
    686  public:
    687   GenericBinaryOpStub(Token::Value op,
    688                       OverwriteMode mode,
    689                       GenericBinaryFlags flags,
    690                       NumberInfo::Type operands_type = NumberInfo::kUnknown)
    691       : op_(op),
    692         mode_(mode),
    693         flags_(flags),
    694         args_in_registers_(false),
    695         args_reversed_(false),
    696         name_(NULL),
    697         operands_type_(operands_type) {
    698     use_sse3_ = CpuFeatures::IsSupported(SSE3);
    699     ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
    700   }
    701 
    702   // Generate code to call the stub with the supplied arguments. This will add
    703   // code at the call site to prepare arguments either in registers or on the
    704   // stack together with the actual call.
    705   void GenerateCall(MacroAssembler* masm, Register left, Register right);
    706   void GenerateCall(MacroAssembler* masm, Register left, Smi* right);
    707   void GenerateCall(MacroAssembler* masm, Smi* left, Register right);
    708 
    709   Result GenerateCall(MacroAssembler* masm,
    710                       VirtualFrame* frame,
    711                       Result* left,
    712                       Result* right);
    713 
    714  private:
    715   Token::Value op_;
    716   OverwriteMode mode_;
    717   GenericBinaryFlags flags_;
    718   bool args_in_registers_;  // Arguments passed in registers not on the stack.
    719   bool args_reversed_;  // Left and right argument are swapped.
    720   bool use_sse3_;
    721   char* name_;
    722   NumberInfo::Type operands_type_;  // Number type information of operands.
    723 
    724   const char* GetName();
    725 
    726 #ifdef DEBUG
    727   void Print() {
    728     PrintF("GenericBinaryOpStub %d (op %s), "
    729            "(mode %d, flags %d, registers %d, reversed %d, number_info %s)\n",
    730            MinorKey(),
    731            Token::String(op_),
    732            static_cast<int>(mode_),
    733            static_cast<int>(flags_),
    734            static_cast<int>(args_in_registers_),
    735            static_cast<int>(args_reversed_),
    736            NumberInfo::ToString(operands_type_));
    737   }
    738 #endif
    739 
    740   // Minor key encoding in 16 bits NNNFRASOOOOOOOMM.
    741   class ModeBits: public BitField<OverwriteMode, 0, 2> {};
    742   class OpBits: public BitField<Token::Value, 2, 7> {};
    743   class SSE3Bits: public BitField<bool, 9, 1> {};
    744   class ArgsInRegistersBits: public BitField<bool, 10, 1> {};
    745   class ArgsReversedBits: public BitField<bool, 11, 1> {};
    746   class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
    747   class NumberInfoBits: public BitField<NumberInfo::Type, 13, 3> {};
    748 
    749   Major MajorKey() { return GenericBinaryOp; }
    750   int MinorKey() {
    751     // Encode the parameters in a unique 16 bit value.
    752     return OpBits::encode(op_)
    753            | ModeBits::encode(mode_)
    754            | FlagBits::encode(flags_)
    755            | SSE3Bits::encode(use_sse3_)
    756            | ArgsInRegistersBits::encode(args_in_registers_)
    757            | ArgsReversedBits::encode(args_reversed_)
    758            | NumberInfoBits::encode(operands_type_);
    759   }
    760 
    761   void Generate(MacroAssembler* masm);
    762   void GenerateSmiCode(MacroAssembler* masm, Label* slow);
    763   void GenerateLoadArguments(MacroAssembler* masm);
    764   void GenerateReturn(MacroAssembler* masm);
    765   void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure);
    766 
    767   bool ArgsInRegistersSupported() {
    768     return op_ == Token::ADD || op_ == Token::SUB
    769         || op_ == Token::MUL || op_ == Token::DIV;
    770   }
    771   bool IsOperationCommutative() {
    772     return (op_ == Token::ADD) || (op_ == Token::MUL);
    773   }
    774 
    775   void SetArgsInRegisters() { args_in_registers_ = true; }
    776   void SetArgsReversed() { args_reversed_ = true; }
    777   bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; }
    778   bool HasArgsInRegisters() { return args_in_registers_; }
    779   bool HasArgsReversed() { return args_reversed_; }
    780 };
    781 
    782 
    783 class StringStubBase: public CodeStub {
    784  public:
    785   // Generate code for copying characters using a simple loop. This should only
    786   // be used in places where the number of characters is small and the
    787   // additional setup and checking in GenerateCopyCharactersREP adds too much
    788   // overhead. Copying of overlapping regions is not supported.
    789   void GenerateCopyCharacters(MacroAssembler* masm,
    790                               Register dest,
    791                               Register src,
    792                               Register count,
    793                               Register scratch,
    794                               bool ascii);
    795 
    796   // Generate code for copying characters using the rep movs instruction.
    797   // Copies ecx characters from esi to edi. Copying of overlapping regions is
    798   // not supported.
    799   void GenerateCopyCharactersREP(MacroAssembler* masm,
    800                                  Register dest,     // Must be edi.
    801                                  Register src,      // Must be esi.
    802                                  Register count,    // Must be ecx.
    803                                  Register scratch,  // Neither of the above.
    804                                  bool ascii);
    805 
    806   // Probe the symbol table for a two character string. If the string is
    807   // not found by probing a jump to the label not_found is performed. This jump
    808   // does not guarantee that the string is not in the symbol table. If the
    809   // string is found the code falls through with the string in register eax.
    810   void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
    811                                             Register c1,
    812                                             Register c2,
    813                                             Register scratch1,
    814                                             Register scratch2,
    815                                             Register scratch3,
    816                                             Label* not_found);
    817 
    818   // Generate string hash.
    819   void GenerateHashInit(MacroAssembler* masm,
    820                         Register hash,
    821                         Register character,
    822                         Register scratch);
    823   void GenerateHashAddCharacter(MacroAssembler* masm,
    824                                 Register hash,
    825                                 Register character,
    826                                 Register scratch);
    827   void GenerateHashGetHash(MacroAssembler* masm,
    828                            Register hash,
    829                            Register scratch);
    830 };
    831 
    832 
    833 // Flag that indicates how to generate code for the stub StringAddStub.
    834 enum StringAddFlags {
    835   NO_STRING_ADD_FLAGS = 0,
    836   NO_STRING_CHECK_IN_STUB = 1 << 0  // Omit string check in stub.
    837 };
    838 
    839 
    840 class StringAddStub: public StringStubBase {
    841  public:
    842   explicit StringAddStub(StringAddFlags flags) {
    843     string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
    844   }
    845 
    846  private:
    847   Major MajorKey() { return StringAdd; }
    848   int MinorKey() { return string_check_ ? 0 : 1; }
    849 
    850   void Generate(MacroAssembler* masm);
    851 
    852   // Should the stub check whether arguments are strings?
    853   bool string_check_;
    854 };
    855 
    856 
    857 class SubStringStub: public StringStubBase {
    858  public:
    859   SubStringStub() {}
    860 
    861  private:
    862   Major MajorKey() { return SubString; }
    863   int MinorKey() { return 0; }
    864 
    865   void Generate(MacroAssembler* masm);
    866 };
    867 
    868 
    869 class StringCompareStub: public StringStubBase {
    870  public:
    871   explicit StringCompareStub() {
    872   }
    873 
    874   // Compare two flat ascii strings and returns result in eax after popping two
    875   // arguments from the stack.
    876   static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
    877                                               Register left,
    878                                               Register right,
    879                                               Register scratch1,
    880                                               Register scratch2,
    881                                               Register scratch3);
    882 
    883  private:
    884   Major MajorKey() { return StringCompare; }
    885   int MinorKey() { return 0; }
    886 
    887   void Generate(MacroAssembler* masm);
    888 };
    889 
    890 
    891 class NumberToStringStub: public CodeStub {
    892  public:
    893   NumberToStringStub() { }
    894 
    895   // Generate code to do a lookup in the number string cache. If the number in
    896   // the register object is found in the cache the generated code falls through
    897   // with the result in the result register. The object and the result register
    898   // can be the same. If the number is not found in the cache the code jumps to
    899   // the label not_found with only the content of register object unchanged.
    900   static void GenerateLookupNumberStringCache(MacroAssembler* masm,
    901                                               Register object,
    902                                               Register result,
    903                                               Register scratch1,
    904                                               Register scratch2,
    905                                               bool object_is_smi,
    906                                               Label* not_found);
    907 
    908  private:
    909   Major MajorKey() { return NumberToString; }
    910   int MinorKey() { return 0; }
    911 
    912   void Generate(MacroAssembler* masm);
    913 
    914   const char* GetName() { return "NumberToStringStub"; }
    915 
    916 #ifdef DEBUG
    917   void Print() {
    918     PrintF("NumberToStringStub\n");
    919   }
    920 #endif
    921 };
    922 
    923 
    924 } }  // namespace v8::internal
    925 
    926 #endif  // V8_IA32_CODEGEN_IA32_H_
    927